Definitions
This page describes the top-level definition forms used in Lutra source files.
Constant definitions¶
A constant definition uses const.
You can provide a type annotation or let the compiler infer the type.
const a: int32 = 4
const lang = "sl"
const main = @2025-11-14
Function definitions¶
A function definition uses func.
func add_one(x: int64) -> x + 1
func bool_to_text(x: bool) -> if x then "yes" else "no"
Parameters¶
A parameter usually has this form:
name: Type
Example:
func add_one(x: int64) -> x + 1
Return types¶
A function can declare its return type after the parameter list.
func main(): int32 -> 4
If the return type is omitted, the compiler infers it from the body.
func add_one(x: int64) -> x + 1
Labeled parameters¶
A function parameter can have an external label and a local name.
The syntax is label local_name: Type.
func calculate(value: int32, add addend: int32, multiply multiplier: int32) -> (
value * multiplier + addend
)
At the call site, you can pass these parameters positionally or by label:
calculate(1, 2, 3)
calculate(1, add = 2, multiply = 3)
calculate(1, multiply = 3, add = 2)
Type parameters with where¶
Functions can have type parameters specified with where clause.
func identity(x: T): T
where T
-> x
When you call a function with type parameters, the function specializes for the types of provided parameters.
For example, the earlier identity function can be called with any type and it
will return that same type:
func main() -> {
identity(1: int32),
identity("hello"),
}
A where clause can leave a type parameter unconstrained:
where T
It can also constrain the allowed shape or domain of that type parameter:
where T: {..}for any tuple,where T: {x2: text, ..}for a tuple with a required named field,where T: {bool, text, ..}for a tuple with required positional fields,where T: bool | textfor one of several primitive types.
For the type forms used in these constraints, see Types.
Examples:
func false_x_false(x: T)
where T: {..}
-> {false, ..x, false}
Type definitions¶
A type definition uses type.
Type aliases¶
A type alias assigns a name to another type.
type Item: {
id: int64,
color: enum {red, green: bool, blue: bool},
}
type Status: enum {
open: int16,
closed: bool,
}
Framed types¶
A type definition can also declare a framed type. Unlike ordinary tuple and enum types, a framed type is nominal: the type name is part of the value's identity.
Use a framed type when you want a distinct named type around an inner value.
type Date(days_epoch: int32)
Construct a framed value by calling the type name:
const my_date = Date(12)
Access the inner value through field lookup:
const my_days: int32 = my_date.days_epoch
The standard library uses framed types for value types such as Date.
Module definitions¶
A module definition uses module and contains nested definitions.
module chinook {
func get_albums(): [Album] -> []
}
See Modules for import and namespace rules.
Entry points¶
Any program can be invoked as the entry point, although the CLI defaults to
invoking main:
func main() -> 1: int32