Birdway
About Documentation

Birdway 0.1 language reference§

Warning

This document is still a draft.

Table of contents

1. Program structure§

Each source file is a unit.

A program is made of one entry point unit and zero or more module units.

1.1. File format§

Birdway source files should be encoded in ASCII or UTF-8 and have a .bw extension.

1.2. Entry point§

The unit designated to be the entry point of the program must contain a function named main, without arguments, and returning null. This function will be executed when the program starts, after parsing command-line arguments. The command-line parameters declared in it will be used for the program.

1.3. Module units§

The other units used by the main one will have all their functions and constants exposed.

2. Lexical elements§

Characters in source files can be grouped into tokens, depending on the lexical context. The context at the beginning of a file is always the main context.

2.1. Main context§

2.1.1. Whitespaces§

Horizontal tabs, line feeds, carriage return and spaces are always valid but ignored.

2.1.2. Comments§

Line comments starts with two hyphens -- and end at the next two hyphens or line feed.

Block comments starts with three hyphens --- and end at the next three hyphens.

Comments are also ignored.

2.1.3. Punctuation§

The punctuators of the language includes: braces { }, parentheses ( ), square brackets [ ], dots ., commas ,, semicolons ;, colons : and double colons ::, at symbols @, dollar signs $, single underscores _, arrows -> and equal signs =.

2.1.4. Operators§

The unary operators are #, ? and the keyword not.

The only unary and binary operator is -.

The binary operators are &, |, ^, +, ==, %, *, /, //, :=, !=, >, >>, >=, <, <<, <=, and the keywords and and or.

2.1.5. Keywords§

Below is a list of the keywords of the language (excluding keyword operators and primitive types):

Text Only
break     params
const     print
do        println
else      read
enum      readln
false     return
for       struct
from      then
func      throw
if        to
in        true
let       try
next      use
null      while
on

2.1.6. Primitive type names§

The primitive types are Void, Bool, Int, Float, Str, File and Signal.

2.1.7. Number literals§

2.1.7.1. Decimal integer literals§

Decimal integers can either be one or more decimal digits (0123456789) that doesn’t start by a zero, or a single zero.

2.1.7.2. Hexadecimal integer literals§

Hexadecimal integers are 0x followed by one or more hexadecimal digits (0123456789aAbBcCdDeEfF).

2.1.7.3. Binary integer literals§

Binary integers are 0b followed by one or more binary digits (01).

2.1.7.4. Floating-point literals§

Floating-point literals are made of an integer part, followed by one or the two of a fractional part and an exponent part.

The integer part is the same as a decimal integer.

The fractional part is a dot . followed by one or more decimal digits.

The exponent part is the letter E (either lowercase e or uppercase E), followed by an optional sign (+, - or nothing) and a decimal integer.

2.1.8. Identifiers§

Identifiers are made of one or more of the following characters: lowercase and uppercase ASCII letters, digits and undercores.

Identifiers may not start by a digit nor match a keyword or keyword operator.

2.1.8.1. Type names§

Type names are identifiers with the additional constraint of not being any of the primitive type names.

2.1.9. String literals§

Strings are delimited by double quotes ". After encountering one, the context switch to the string context.

2.2. String context§

2.2.1. Escape sequences§

Certain characters can be preceded by a backslash \ to remove/give them a special meaning:

Escape Expansion
\\ \
\" "
\{ {
\n A newline (ASCII character 10/LF)
\t A tabulation (ASCII character 9/TAB)
\r A carriage return (ASCII character 13/CR)

Any other character cannot be escaped.

2.2.2. Formatting§

An opening brace { mark the beginning of a formatting field. A field is made of a value and formatting options. The three types of values are decribed in the next sections.

The value may be an integer, an identifier, or an expression bewteen parentheses. These expressions are read using the main context.

The options can be a single interrogation mark ?, two interrogation marks ??, or nothing.

2.2.3. End of string§

Double quotes " mark the end of a string literal, switching back to the main context.

2.2.4. Text§

Any other character is treated as string content.

3. Types§

3.1. Primitive types§

3.1.1. Void§

The Void type is the unit type and represents the absence of data. The only value it can take is the null constant.

There cannot be Void bindings, and it can’t be used within most composite types.

3.1.2. Booleans§

The Bool type can take only two values, the constants true and false.

3.1.3. Integers§

The Int type is a 32-bit signed integer.

3.1.4. Floating-point numbers§

The Float type is a double precision (64 bits) floating-point number.

3.1.5. Strings§

The Str type is a string of unicode characters.

A string is iterable with items of type Str, and indexable by Int with items also of type Str.

Single characters are represented by strings of length 1.

3.1.6. Files§

The File type represents a text stream. It may be one or both of readable and writeable.

3.1.7. Signals§

The Signal type represents an error. See the dedicated section for more information.

3.2. Composite types§

Composite types are built using primitive type or other composite types.

3.2.1. Nullable types§

Syntax
nullable type = type, "?";

A nullable type T? can hold values of type T and null.

T cannot be Void or another nullable type.

3.2.2. Lists§

Syntax
list type = "[", type, "]";

A list type [T] is a dynamic collection of T.

T cannot be Void, and all the values should all have the same type, or be able to be converted into a single type through implicit conversion.

A list [T] is iterable with items of type T, and indexable by int with items also of type T.

3.2.3. Dictionaries§

Syntax
dict type = "[", type, ":", type "]";

A dictionary type [T: U] is a mapping of T values to U values.

T and U cannot be Void, and T must be hashable (that is, accepted by the hash function).

The types of the keys must be the same (or beign compatible for implicit conversion like in lists) and the types of the values as well.

A dictionary [T: U] is iterable with items of type T, and indexable by T with items of type U.

3.2.4. Tuples§

Syntax
tuple type = "(", [ type, { ",", type } [ "," ] ] ")";

A tuple type (T1, T2, ...) is a group of different types.

Tuple fields cannot be Void, and a tuple with zero fields is illegal. A tuple with only one field is the same as the type of its field.

3.2.5. Function types§

Syntax
function type = type, "->", type;

A function type T -> R is the type of a function that takes an argument of type T and return a value of type R. A function type (T1, T2, ...) -> R is the type of a function that takes zero, one or more arguments of type T1, T2, … and return a value of type R.

3.3. User-defined types§

3.3.1. Enumerations§

Enumerations are primitive types that can take a specific list of values.

3.3.2. Structures§

Structures are groups of types like tuples, except that their fields are named.

3.4. Never type§

An expression that will only throw a signal have the never type, represented ! (for displaying purposes only, it is not valid syntax).

It is different from the unit type because it represents the absence of a value, whereas Void has one and only one value.

3.5. Implicit conversion§

If a value can be of type T or Void, then its type will be T?.

If a value can be of type Int or Float, then its type will be Float.

If an Int value is found where a Float value was expected, it is also converted to Float implicitly.

The never type ! can be implictly converted into any other type.

A mutable type can be used where the immutable version of the same type is expected.

Whenever several expressions are required to have the same type, it is valid if different types that be converted implicitly into a single type are given.

3.6. Type inference§

The type of a binding, if omitted, is deduced from the value it is assigned, and the types of function parameters are generic by default. A generic function parameter can take any type that follows the constraints and is valid within the function.

3.6.1. Partial types§

Sometimes, the exact type of an expression is unknown, and in that case the types that cannot be determined should represented as ~ (for displaying purposes only like the ! type).

For example, an empty list could be a list or dictionary of anything, and as such its type will be [~].

If a partial type is never resolved, the program is still valid because it means that the actual type is not important.

3.7. Type constraints§

Integers can be used where a type is expected, indicating a generic type. Two generic types with the same number must then be resolved with the same type.

4. Expressions§

Expressions are divided in three categories that defines their precedence:

Syntax
primary expression = null
                   | boolean constant
                   | integer constant
                   | floating point constant
                   | string literal
                   | list literal
                   | dictionary literal
                   | tuple literal
                   | bound value
                   | black hole
                   | unary operation
                   | anonymous function;

secondary expression = field access
                     | item access
                     | function call
                     | primary expression;

expression = binary operation
           | secondary expression
           | if expression
           | for expression
           | while expression
           | try expression
           | function call
           | input output expression
           | block
           | block statements
           | flow control expressions;

Expressions in birdway are lazy, that is, they won’t be evaluated until the result is really needed.

4.1. Constant values§

Note

The types File and Signal have no literal representation. They are created by or declared as built-ins.

4.1.1. Null§

The keyword null is the value of the unit type Void.

4.1.2. Boolean constants§

The keywords true and false are the two values of the Bool type.

4.1.3. Integer constants§

Decimal, hexadecimal and binay integer literals evaluates to a value of the Int type.

4.1.4. Floating-point constants§

Floating-point literals evaluates to a value of the [Float](#314-floating-point-numbers) type.

4.1.5. Strings§

String literals evaluates to a value of the Str type.

Formatting fields where the value is an integer will be left as-is to be formatted later by fmt. Otherwise, if the value is an identifier, the value bound to that identifier in the current scope will be used. Finally, if the value is an expression, the result of this expression evaluated in the scope of the string literal will be used.

No options means that to_string will be used, and one or two interrogation marks means that debug will be used instead, with inline set to true if a single ? is used.

If the type of a binding or expression given to format is incompatible with the formatting function, it should result in a type error.

4.2. Composite types literals§

Note

Nullable values are created through implicit conversion and functions will be dealt with in another section.

4.2.1. List literals§

Syntax
list literal = "[", [ expression, { ",", expression } [ "," ] ], "]";

List literals are values separated by commas and surrounded by square brackets. A list containing T values will be of type [T] and an empty list will have the partial type [~].

4.2.2. Dictionary literals§

Syntax
key value = expression, ":", expression;

dict literal = "{", [ key value, { ",", key value } [ "," ] ], "}";

Dictionary literals are key-value pairs of the form key: value separated by commas and surrounded by square brackets. A dictionary containing T keys and U values will be of type [T: U], and an empty dictionary will have the partial type [~: ~].

4.2.3. Tuple literals§

Syntax
tuple literal = "(", [ expression ], { ",", expression } [ "," ] ")";

List literals are values separated by commas and surrounded by parentheses. The type of the tuple will be a tuple type of the types of the values.

A tuple cannot be empty, and a tuple with a single value will evaulate to that value.

4.3. Bound values§

The value of an identifier if the value bound to it via a let or const.

4.4. Operations§

4.4.1. Unary operations§

Syntax
unary operation = ( UNARY ONLY | UNARY OR BINARY ), primary expression;

Apply an unary operator to an expression.

4.4.2. Binary operations§

Syntax
unary operation = secondary expression,
                  ( UNARY OR BINARY | BINARY ONLY ),
                  expression;

Apply a binary operator to two expressions.

See also

The list of operators and their behavior

4.4.3. Field access§

Syntax
field access = secondary expression, (* value *)
               ".",
               ( identifier | DECIMAL INTEGER ); (* field *)

If the value is a struct, the field must be an identifier and it will evaluate to the value of the corresponding struct field.

If the value is a tuple, the field must be an integer and it will evaluate to the value of the tuple field at that index.

If the tuple or struct is mutable, then the field accessed is mutable too.

A field access is impossible with any other type.

4.4.4. Item access§

Syntax
item access = secondary expression, (* value *)
              "[",
              expression, (* index *)
              "]";

Get the item at the specified index. The type of the value must be indexable by the type of the index.

If the collection is mutable, then the item accessed is mutable too.

4.5. If-then-else§

Syntax
if expression = "if", expression, (* condition *)
                "then", expression, (* result *)
                [ "else", expression ]; (* alternative *)

If the condition is true, evaluates to the result, and othwerwise to the alternative. If the else ... part is missing, it evaluates to null in case the condition is false.

The condition must be of type Bool, and the result and the alternative must have the same type.

4.6. Loops§

4.6.1. For loops§

Syntax
for expression = "for", ( declaration | "_" ), (* item *)
                 "in", expression, (* collection *)
                 "do", expression; (* expression *)

Evaluates to a list of expressions evaluated with the item taking each value of the collection. The item is mutable if and only if the collection is mutable.

If the item is a single undercore _, the values inside the collection are ignored and the loop just repeats the same expression for the length of the collection.

The collection must be iterable by the type of the variable. An iterable of any type can be used with _ as the item.

In case the expressions are of type Void, the loop just evaluates to null.

If a break signal is caught, the loop stops and return the list of expressions evaluated so far. If a continue signal is caught, the loop continues its execution and ignore one of the expressions.

4.6.2. While loops§

Syntax
while expression = "while", expression, (* condition *)
                   "do", expression; (* expression *)

Evaluates to a list of expressions evaluated repeatedly while the condition is true.

The condition must be of type Bool.

In case the expressions are of type Void, the loop just evaluates to null.

The break and continue signals are handled the same way as the for loop does.

4.7. Error handling§

Syntax
try expression = "try", expression, (* expression *)
                 {
                    "catch", expression, (* signal *)
                    "do", expression (* handler *) 
                 },
                 [ "finally", expression ]; (* cleanup *)

Evaluates to the expression, but if an error is thrown and matches one of the handled signals, then evaluates to the corresponding handler. After that, the cleanup expression is evaluated (if present) and its value discarded.

The expression and the handlers must all have the same type. The signals must be of type Signal and the cleanup of type Void.

4.8. Functions§

4.8.1. Calling functions§

Syntax
function call = secondary expression, "(",
                [ expression, { ",", expression }, [ "," ] ],
                ")";

Evaluate the body of a function with the given arguments.

If a return signal is caught, the function return immediately.

4.8.1.1. Overload resolution§

If a function is overloaded, the implementation that will be called is the one wich match the number and the types of the arguments.

If a function has multiple overloads that accept the number and types of the arguments, the least generic one (i.e. the one with the least generic parameters) is chosen.

4.8.2. Anonymous functions§

Syntax
anonymous function = ( "(", 
                       [ IDENTIFIER, { ",", IDENTIFIER }, [ "," ] ],
                       ")"
                     | IDENTIFIER
                     ),
                     "->", expression; (* body *)

Creates an anonymous function with the specified parameters and body.

4.8.2.1. Closures§

When an anonymous function is evaluated, it is given a closure containing all the local bindings used by the function. All bindings are captured by value the moment it is evaluated.

4.9. I/O§

4.9.1. Output§

Syntax
print expression = ( "print" | "println" ), expression, (* content *)
                   [ "to", expression ]; (* stream *)

Writes the content formatted using to_string to the stream. If no stream is specified, it defaults to the standard output.

If println is used, a newline is written after the content.

The content must be a string or a valid argument to pass to to_string. The stream must be of type File and writeable. It always evaluates to null.

4.9.2. Input§

Syntax
read expression = ( "read", [ expression (* limit *) ] | "readln" ),
                  [ "from", expression ]; (* stream *)

Reads the content of a stream and return it. If no stream is specified, it defaults to the standard input.

If read is used, reads until the end of the stream, and if a limit is given, reads at most that number of characters from the stream. If readln is used instead, reads until a newline is encountered. The newline is read from the stream and discarded.

The limit must be of type Int and the stream of type File and readable. The result is always a Str.

4.10. Blocks§

Syntax
block = "{",
        { expression | block statement, ";" },
        [ expression (* tail *) ],
        "}"; 

Evaluates each expression after another. The value of the block is the value of the tail expression, if there is one, or null otherwise.

4.11. The black hole§

A single undercore _ is the “black hole”. It acts like a binding, except its type is $Void. It should behave like null under most circumstances.

See also

The assignment operator

4.12. Flow control§

The type of all these expressions is the never type.

4.12.1. Continue§
Syntax
continue expression = "continue";

Throws a continue signal. It can only be used inside of a loop.

4.12.2. Break§
Syntax
break expression = "break";

Throws a break signal. It can only be used inside of a loop.

4.12.3. Return§
Syntax
return expression = "return", [ expression (* return value *) ];

Sets the value of the expression as the return value of the function it is inside of and throws a return signal. It can only be used inside of a function.

If no return value is specified, then null is returned.

4.12.3. Throw§
Syntax
throw expression = "throw", expression, (* signal *);

Throws an error signal.

The signal must be of type Signal.

5. Operators§

5.1. Arithmetic operators§

5.1.2. Substraction§

The - binary operator substract a number to another.

The types are the same as for the addition.

5.1.1. Addition§

The + binary operator adds two numbers.

Left operand Right operand Result
Int Int Int
Int Float Float
Float Int Float
Float Float Float
Any other type Any other type Invalid

5.1.2. Substraction§

The - binary operator substract a number to another.

The types are the same as for the addition.

5.1.3. Multiplication§

The * binary operator multiplies two numbers.

The types are the same as for the addition.

5.1.4. Division§

The / binary operator divide a number by another.

Left operand Right operand Result
Int Int Float
Int Float Float
Float Int Float
Float Float Float
Any other type Any other type Invalid

5.1.5. Integer division§

The // binary operator gives the quotient of the division of two numbers. The division is floored if the divider is positive, and ceilinged if it is negative.

Left operand Right operand Result
Int Int Int
Any other type Any other type Invalid

5.1.6. Modulo§

The % binary operator gives the remainder of the division of two numbers. The division is floored if the divider is positive, and ceilinged if it is negative.

The types are the same as for the integer division.

5.2. Comparison operators§

5.2.1. Equal§

The == binary operator tests two values for equality.

The two operands must have the same type, and that type can’t be File or any composite type containing File.

5.2.2. Not equal§

The != binary operator tests two values for inequality. It is the negation of the equal operator.

5.2.3. Less than§

The < binary operator tests if a value is strictly less than another.

Left operand Right operand Result
Int Int Bool
Int Float Bool
Float Int Bool
Float Float Bool
Any other type Any other type Invalid

5.2.4. Greater than§

The > binary operator tests if a value is strictly greater than another.

The types are the same as for the less than operator.

5.2.5. Less or equal§

The <= binary operator tests if a value is less then or equal to another.

The types are the same as for the less than operator.

5.2.6. Greater or equal§

The >= binary operator tests if a value is greater then or equal to another.

The types are the same as for the less than operator.

5.3. Logical operators§

5.3.1. Logical NOT§

The not unary operator negates a boolean value.

Operand Result
Bool Bool
Any other type Invalid

5.3.2. Logical OR§

The or binary operator is the logical or of two booleans.

Left operand Right operand Result
Bool Bool Bool
Any other type Any other type Invalid

5.3.3. Logical AND§

The or binary operator is the logical and of two booleans.

The types are the same as for the logical or operator.

5.4. Other operators§

5.4.1. Size§

The # unary operator gives the size of a collection.

Operand Result
Str Int
[T] Int
[T: U] Int
Any other type Invalid

5.4.2. Concatenation§

The & binary operator concatenates two collections of the same type.

Left operand Right operand Result
Str Str Str
[T] [T] [T]
Any other type Any other type Invalid

5.4.3. Prepending§

The >> binary operator prepends a value to a list.

Left operand Right operand Result
T [T] [T]
Any other type Any other type Invalid

5.4.4. Appending§

The << binary operator appends a value to a list.

Left operand Right operand Result
[T] T [T]
Any other type Any other type Invalid

5.4.5. Union§

The | binary operator gives the union of two dictionaries, the values of the right-hand side overriding the values of the left-hand side.

Left operand Right operand Result
[T: U] [T: U] [T: U]
Any other type Any other type Invalid

5.4.6. Isn’t null§

The ? unary operator tests if a nullable value is not null.

Operand Result
T? Bool
Any other type Invalid

5.4.7. Assignment§

The := binary operator assign the value on the right-hand side to the variable on the left-hand side, and evaluates to that value.

Left operand Right operand Result
$T T T

If the expression assigned has not been computed yet because of laziness, it gets computed before being assigned.

Any value can be assigned to the black hole binding, in wich case that value is discarded and the assignment evaluates to null.

6. Statements§

6.1. Unit-level statements§

These statements can only be used directly in the body of the program. A unit is made of zero or more of these statements, terminated by semicolons ;.

6.1.1. Use statement§

Syntax
use statement = "use", IDENTIFIER;

Import another unit as a module from the file in the same directory as the source, with the given name and a .bw extension.

6.1.2. Type declarations§

6.1.2.1. Enumeration declarations§
Syntax
enum declaration = "enum", TYPE NAME, "(",
                   [ IDENTIFIER, { ",", IDENTIFIER }, [ "," ], (* values *) ],
                   ")"; 

Declare an enum type that can take one of the values. All values are declared as constants, and there must be at least one.

6.1.2.2. Structure declarations§
Syntax
struct field = IDENTIFIER, ":", type;

struct declaration = "struct", TYPE NAME, "(",
                     [ struct field, { ",", struct field }, [ "," ] ],
                     ")"; 

Declare a struct with the given fields. All the types must be non-generic, complete types (i.e. not partial). There must be at least one field.

6.1.3. Command-line arguments§

Syntax
program parameter = IDENTIFIER, ":", type;

params declaration = "params", "(",
                     [ program parameter, { ",", program parameter }, [ "," ] ],
                     ")";

Declare command-line parameters. The following types can be used:

6.1.4. Constant declarations§

Syntax
declaration = IDENTIFIER, [ ":", type ];

constant declaration = "const", declaration, "=", expression; 

Binds a value to a name, ensuring the expression is evaluated at compile time.

Constants are not captured by closures because of their static nature.

6.1.5. Function declarations§

Syntax
function parameter = [ "$" | "@" ], declaration;

function parameters = "(", [
                        function parameter,
                        { ",", function parameter },
                        [ "," ]
                      ], ")";

function delcaration = "func", IDENTIFIER, function parameters,
                       [ type ] (* return type *) "->", expression; (* body *)

Declares a function with a given name and parameters, and returning the body when called.

By default, all arguments are passed by copy. They may actually be passed by reference for optimisation reasons, but since they aren’t mutable, it should behave the same way.

When a parameter is preceded by a $ modifier, arguments will be passed to it by mutable reference, and as such, they must be mutable bindings.

When a parameter is preceded by a @ modifier, arguments are still passed to it by copy, but the binding inside the function is mutable.

If the return type is specified, the type of the body must be the same. Otherwise, the return type of the function is inferred from the type of the body.

Functions may be overloaded, that is, a function may have different implementations with different parameters.

6.2. Block-level statement§

These statements can only be used inside blocks.

6.2.1. Constants and functions§

Constants and functions can also be declared inside blocks, just like in the program body. The difference is that functions will have a closure like anonymous functions do.

6.2.2. Bindings§

Syntax
binding = "let", [ "$" ], declaration, "=", value;

Binds a value to a name, but unlike constants, the value may be evaluated at runtime.

The $ modifier indicates that the binding is mutable. If the expression assigned has not been computed yet because of laziness, it gets computed before being assigned.

7. Scope and modules§

7.1. Scope of constants and bindings§

Functions, constants and binding are available in the scope they’re declared in.

For constants and functions declared in the body of the program, they are avaliable through the entire unit.

If they are declared inside block instead, they are available from their declaration to the end of the block.

Functions have access to themselves inside their bodies to allow for recursion. Constants and bindings do not.

7.1.1. Shadowing§

A declaration can shadow (i.e. have the same name as) another if they are not in the same block.

A bindigs thus refers to the last one declared.

7.2. Module exports§

When a module is imported, the declarations in its body (including the declarations imported from another unit) are brought into the global scope of the unit importing it.

8. Signals§

When a signal is thrown, it interrupts the execution of the preogram and propagate down the stack until it is caught. If it is not caught, the program terminates.

8.1. Internal signals§

Three signals should be available for interal use: a break signal, a continue signal and a return signal. They can only be thrown using special statements, and should always be caught (otherwise, it would mean that a break was outside of a loop, for example).

8.2. Error signals§

Other signal can be thrown and caught by the user, and occur anywhere in the program. They are defined as built-in constants. They may never be caught and terminate the program.

9. Built-ins§

Built-ins are functions and constants that are defined in any unit, and that may be shadowed by user declarations, including inside the body. They should be implemented by the compiler.

9.1. Input/Output§

func open(path: Str) File
func open(path: Str, mode: FileMode) File

Open the file at the specified path.

Parameters

path
The path of the file, absolute or relative to the CWD.
mode
The mode to open the file with.

Returns

The opened file.

Throws

ERR_NOTFOUND
If the file does not exists.
ERR_PERM
If the user doesn’t have the permission to open the file with the specified mode.
ERR_NOTAFILE
If the path given points to a directory.

enum FileMode (READ_ONLY, WRITE_ONLY, READ_WRITE)

File opening modes.

func close($file: File) Void

Closes an opened file.

Parameters

file
The file to close.

Throws

ERR_VALUE
If the file was already closed.

9.2. Conversions§

func to_int(value: Bool) Int
func to_int(value: Float) Int
func to_int(value: String) Int?

If the value is a Bool, then false is mapped to 0 and true to 1.

If the value is a Float, it gets truncated (i.e. rounded towards zero).

If the value is a Str, it will be parsed as a decimal integer.

Parameters

value
The value to convert.

Returns

The value converted to an integer, or null if the conversion fails.

func to_float(value: Bool) Float
func to_float(value: Int) Float
func to_float(value: String) Float?

If the value is a Bool, then false is mapped to 0.0 and true to 1.0.

If the value is a Str, it will be parsed as a floating-point number.

Parameters

value
The value to convert.

Returns

The value converted to a float, or null if the conversion fails.

func to_string(value: Int) Str
func to_string(value: Float) Str

Converts a number to its decimal representation.

Parameters

value
The value to convert.

Returns

The value converted to a string.

func debug(value: 1) Str
func debug(value, inline: Bool) Str

Convert any value to its literal representation, or, in case it has no literal form, to a representation giving enough information to recreate the value.

Parameters

value
The value to convert.
inline
If set to true, the value is displayed on one line. Otherwise, the representation may use multiple lines to be more readable. Defaults to true.

Returns

The value converted to a string.

func to_hex(value: Int) Str

Convert an integer to its hexadecimal representation.

Parameters

value
The value to convert.

Returns

The value converted to a string.

func to_bin(value: Int) Str

Convert an integer to its binary representation.

Parameters

value
The value to convert.

Returns

The value converted to a string.

9.3. Operations on nullable values§

func unwrap(maybe: 1?) 1

Return the inner value of maybe, or throws an ERR_NULL if it was null.

Parameters

maybe
A nullable value.

Returns

The inner value.

Throws

ERR_NULL
If maybe was null.

func default(maybe: 1?, default: 1) 1

Return the inner value of maybe, or default it was null.

Parameters

maybe
A nullable value.

Returns

The inner value or default.

func then(maybe: 1?, f: 1 -> 2) 2?

Return null if maybe is null, or the image of maybe by f.

Parameters

maybe
A nullable value.
f
The mapping function.

Returns

A new nullable value.

func expect(maybe: 1?, err: Signal) 1

Return the inner value of maybe, or throws err if it was null.

Parameters

maybe
A nullable value.
err
An error to throw if maybe is null.

Returns

The inner value.

Throws

err
If maybe was null.

9.4. Signals§

const SUCCESS: Signal = ....

Stop the program with success.

Exit code 0

const ERR_VALUE: Signal = ....

A value was not valid.

Exit code 70

const ERR_NULL: Signal = ....

A nullable value was null.

Exit code 70

const ERR_MATH: Signal = ....

A mathematical operation was not valid (e.g. division by zero)

Exit code 70

const ERR_RANGE: Signal = ....

A numeric value overflowed.

Exit code 70

const ERR_OS: Signal = ....

Generic OS error.

Exit code 71

const ERR_IO: Signal = ....

I/O error.

Exit code 74

const ERR_NOTFOUND: Signal = ....

A file didn’t exists.

Exit code 71

const ERR_PERM: Signal = ....

The user didn’t have the permission to perform an operation.

Exit code 77

const ERR_NOTAFILE: Signal = ....

A path pointed to a directory when a file was expected.

Exit code 71

const ERR_NOTADIR: Signal = ....

A path pointed to a file when a directory was expected.

Exit code 71

const ERR_EXISTS: Signal = ....

A file already existed.

Exit code 71

const ERR_LOOKUP: Signal = ....

An item access failed.

Exit code 70

const ERR_FORMAT: Signal = ....

A value was not in the correct format.

Exit code 65

const ERR_USERINT: Signal = ....

Thrown when the user interrupts the program with Ctrl+C.

Exit code 130

const ERR_MEMORY: Signal = ....

An error ocurred when trying to allocate dynamic memory.

Exit code 70

const ERR_APP: Signal = ....

Application-specific error.

Exit code 80

const FAIL: Signal = ....

Generic error.

Exit code 1