Reference
Lutra is a statically typed programming language with a minimal algebraic type system and some aspects of functional paradigm.
Type system¶
Primitives include following types:
boolholds one bit of information. Possible values arefalseandtrue.int8,int16,int32,int64are signed integers.int{n}holdsnbits of information. Possible values are first2**(n-1)non-negative integers and first2**(n-1)negative integersuint8,uint16,uint32,uint64are unsigned integers.uint{n}holdsnbits of information. Possible values are first2**nnon-negative integers.float32,float64are IEEE 754 single and double precision floating point numbers, respectively.textis UTF8 encoded string of characters of length at most2**32 - 1.
Tuples are a product of possibly many different types. Each field of the tuple can be named.
Arrays are repetitions of one single type.
Enums are a sum type of possibly many different types. Each variant must be named.
Expressions¶
Primitive types can be expressed with literals:
Tuples can be constructed using curly braces and can contain arbitrary expressions of different types:
Each of tuple fields may be prefixed by a name:
Arrays can be constructed using square brackets and can contain arbitrary expressions. All items must be of the same type. Array items cannot be named.
Tuple field lookup can be expressed using . followed by
the name or 0-based position of the field.
Function calls are expressed by the name of the function followed by parenthesis, which contain function arguments.
Pipelines are alternative notation for function call which
are more convenient for chaining. The notation consists of
parenthesis that contain expressions separated by pipe symbol |.
Using a pipe symbol between two expressions is syntactically equivalent
to using the first expression as the first argument to the call of the second
expression.
All expressions apart from the first are therefore limited to function calls,
names and inline functions.
Each of the following notations are equivalent:
- my_func(5)
- 5 | my_func()
- 5 | my_func
The following notations are equivalent:
- another_func(my_func(5), false)
- 5 | my_func | another_func(false)
Following binary and unary operators use standard infix and prefix notation, respectively, and are equivalent to calls to corresponding standard library functions.
Binary:
- * std::mul
- / std::div
- % std::mod
- + std::add
- - std::sub
- == std::eq
- != std::ne
- > std::gt
- < std::lt
- >= std::gte
- <= std::lte
- && std::and
- || std::or
Unary:
- - std::neg
- ! std::not
Ranges are syntactic sugar for constructing tuples of form
{start = _, end = _} and use .. infix notation.
The following notations are equivalent:
- 3..10
- {start = 3, end = 10}
Functions can be defined as follows:
where:
- x and y are two function arguments,
- T and U are their required types, respectively,
- V is the function return type,
- ... is the expression that computes the return value.
Return type of the function is optional if it can be inferred from the function body.
Definitions¶
Lutra source files are a sequences of definitions of functions, types, constants and modules.
Function definitions use keyword func, followed by the parameters, return type and the body.
Return type can be omitted it can be inferred from the body expression.
Types are defined using keyword type followed by the name and the type.
Module definition use keyword module.
Modules are a namespace for other definitions.