Forge functions use Python-like definitions with static parameter types.
def name(params) -> return_type:
body
def add(a: int32, b: int32) -> int32:
return a + b
voiddef private_fn() -> int32: # No pub
return 0
pub def public_fn() -> int32: # pub
return 0
pub marks an item as public. Note that the module loader currently merges
all items from imported modules — private and public alike — so visibility
is informational only and is not enforced at import time.
# By value (copy)
def by_value(x: int32) -> int32:
return x
# By pointer (mutable access via unsafe)
def by_ptr(x: ptr[int32]) -> int32:
unsafe:
return *x
Pass a local’s address with &x — it coerces to ptr[T] at the call site:
var n = 42
let v = by_ptr(&n) # v == 42
def returns_int() -> int32:
return 42
def returns_void() -> void:
return
Struct and tuple return types work end-to-end: the caller allocates a scratch slot and the callee writes the result through a hidden first argument (return by pointer). See Known Issues for ABI details.
def make_point(x: int64, y: int64) -> Point:
var p: Point
p.x = x
p.y = y
return p
def pair() -> (int64, int64):
return (1, 2)
Functions can declare type parameters and are monomorphized per call site:
def id[T](x: T) -> T:
return x
def swap[T](a: T, b: T) -> T:
var t: T = b
return t
def make_pair[T](a: T, b: T) -> Pair[T]:
return Pair[T] { first: a, second: b }
def sum_pair[T](p: Pair[T]) -> T:
return p.first + p.second
id[int64](x) is not
parsed)id$i64); distinct instantiations
share nothingvar t: T), and generic struct literals (Pair[T] { ... })make_pair,
sum_pair above)Pair[Pair[int64]]# Hosted (default)
pub def main() -> int32:
return 0
In hosted targets the runtime _start calls main and uses its return value
as the process exit code.
Freestanding targets use a custom entry point with no runtime:
@freestanding
pub def _start() -> void:
...
Declare foreign functions. The extern def declaration has no body and maps
to a symbol the runtime (or the linker) provides:
extern def _dev_halt() -> void
extern def puts(s: ptr[char]) -> int32
@extern(abi) sets the ABI annotation; @extern("c") is the default.
def factorial(n: int32) -> int32:
if n <= 1:
return 1
return n * factorial(n - 1)
Tail recursion is not optimized — deep recursion may overflow the stack.
The following are not available in this milestone (see Known Issues):
impl blocks — impl panics the compiler; there is no obj.method() call syntaxfn(int32) -> int32 annotations fail to parse|x| x + 1extern def printf(fmt, ...)