Functions and Parameters - CPULL/Dflat GitHub Wiki
Functions in Dflat are defined using the fun keyword followed by the return type, function name, the parameters enclosed in parentheses, and the function body.
If a function does not return a value, the return type is omitted (void functions.)
Functions can return a single value, multiple values separated by commas, or a tuple.
fun i32 Add(i32 a, i32 b) {
return a + b
}
Functions composed by a single expression do not need a return statement.
fun i32 Multiply(i32 a, i32 b) { a * b }
Function parameters are strictly defined to control how arguments are passed, including ownership and mutability. The function definition specifies the parameter mode, while the call site only marks special actions such as writable references or moving ownership. Parameters can be copied, passed by read-only or writable reference, borrowed as read-only or read/write, or moved via ownership transfer. Mismatched calls result in compile errors. Functions also support default values anywhere in the parameter list and named arguments. Function overloading is resolved by matching exact types or using the smallest same-family widening conversions.
Values returned by functions transfer ownership of objects to the caller. Under the hood, failing functions return normally alongside an error register holding error records when a failure occurs.
Lambdas are anonymous functions structured with parameters placed before a semicolon and mandatory captures placed after it. Listing captures is required to use outer variables, and using an unlisted outer variable causes a compile error, though unlisted local constants are automatically copied in with a warning. Captures can specify how variables are accessed, such as being borrowed, copied, moved in, or held as weak references. Function types are denoted using signatures that specify input types and return types, or void.
Single value: fun u64 fib(u64 n) { ... }
Void: fun log(string msg) { }
Multiple values: fun i32, string getUser() { return 1, "a" }
Tuple: fun (i32 v, string n) getPair() { return (1, "a") }
-
Copied Parameter Native data types (such as integers, reals, chars, bools, enums, and pointers) are copied when defined normally.
All non class variables are passed by value:fun f(i32 x)x is passed by value
Definition: fun f(i32 param) Usage: f(value)
For object class instances, allows the caller to choose to copy the object by marking it with an exclamation mark as obj!.
Item obj
f(obj!)
The obj! notation, will create a copy of obj that will be passed to the function body.
Definition: fun f(MyClass param) Usage: f(myClass!)
-
Read-Only References Definition:
fun f(&i32 param)fun f(AClass obj)(objects are passed by read-only reference by default) Usage:f(value)Passes native data or objects by reference or as borrowed instances in a read-only manner. The function body cannot modify the object. -
Writable Reference Definition:
fun f((&)i32 param)fun f((&)AClass obj)Usage:f((&)value)Passes native data or objects by reference or as borrowed instances with read and write permissions, which requires the caller to explicitly prefix the argument with(&). The function body can modify the object. -
Volatile Read-Only Definition:
fun f(volatile &i32 param)Usage:f(value)Defines a parameter as volatile and read-only, ensuring every access goes directly to memory without compiler caching. -
Ownership Move Definition>
fun f(->Item obj)Usage:f(->obj)Transfers ownership of an object into the function, requiring the caller to explicitly mark the argument with->. The function body becomes the owner of the object and can even destroy it, the caller should not make any assumption regarding the object passed with onwership transfer.
The definition says how a parameter is passed, ownership included. The call marks only what the reader must notice (writing, moving) or what the caller chooses (copying).
| Definition | Example | Description |
|---|---|---|
f(i32 x) |
f(x) |
copied |
f(&i32 x) |
f(x) |
by reference, read-only |
f((&)i32 x) |
f((&)x) |
by reference, writable; (&) required in the call |
f(volatile &i32 x) |
f(x) |
volatile, read-only |
f(Item o) |
f(o) |
borrowed, read-only |
f((&)Item o) |
f((&)o) |
borrowed, read/write; (&) required in the call |
f(Item o) |
f(o!) |
copied by the caller, not part of the definition |
f(->Item o) |
f(->o) |
ownership moves; -> required in the call |
- Native data: integers, reals, chars, bools, enums, pointers. Objects: class instances.
- A mismatched call is a compile error.
- Defaults anywhere; named arguments when needed (
hello(age: 27)).
-
Default Values: Optional parameters can specify default values using
=. Parameters with defaults can appear anywhere as long there is no ambiguity. - Named Arguments: Arguments can be passed explicitly by name, allowing out-of-order arguments or skipping optional parameters.
fun bool Connect(string host = "localhost", u16 port = 80, bool secure = false) {
// ...
}
// Usage with named arguments
Connect(port: 443, secure: true)
Functions can accept a variable number of arguments using the variadic prefix (...).
fun LogAll(string level, ...string messages) {
for string msg in messages {
Print($"{level}: {msg}");
}
}
it is equivalent to passing a collection of items.
Functions can be parameterized over types using angle brackets (<T>), supporting type constraints and inference.
fun Item Max<Item>(Item first, Item second) where Item : Comparable {
return first > second ? { first, second }
}
Multiple functions may share the same identifier provided their parameter signatures (types, arity, or order) are distinct. Return types alone do not differentiate overloads.