def vs defp
def declares a public function visible to the host engine and other modules. defp declares a private function only callable within the same file:
# Public, the engine can call this
def on_tick(dt :: float) do
tick(@speed, dt)
end
# Private, only callable within this file
defp tick(speed :: float, dt :: float) do
@player_x = @player_x + speed * dt
endParameters
Every parameter requires a type annotation with :::
defp add(a :: int, b :: int) :: int do
return a + b
endThere are no default parameter values, use multiple functions or an explicit check instead.
Return Type
Private functions (defp) require an explicit return type annotation when they return a value. Public functions (def) may omit it:
defp area(w :: float, h :: float) :: float do
w * h
endThe last expression in a function body is the implicit return value. return is optional but can be used to exit early:
defp clamp_score(s :: int) :: int do
if s < 0 do return 0 end
if s > 999 do return 999 end
return s
endMultiple Return Values
A function can return more than one value by listing them after return, separated by commas:
defp minmax(a :: int, b :: int) :: int do
if a < b do
return a
end
return b
end
lo = minmax(7, 3)
print(lo) # 3For two values, use a struct:
defstruct Range do
lo :: int
hi :: int
end
defp range_of(a :: int, b :: int) :: Range do
if a < b do return Range{ lo: a, hi: b } end
return Range{ lo: b, hi: a }
end
r = range_of(7, 3)
print(r.lo) # 3
print(r.hi) # 7Recursion
Functions can call themselves. Chasm has no stack overflow protection, so keep recursion depth bounded:
defp fib(n :: int) :: int do
if n <= 1 do
return n
end
return fib(n - 1) + fib(n - 2)
end
print(fib(10)) # 55Calling Functions
Call a function by name with arguments in parentheses:
result = add(3, 4)
lo, hi = minmax(9, 2)The Pipe Operator with Functions
The |> operator passes a value as the first argument to the next function. It chains well with defp helpers:
defp double(x :: float) :: float do x * 2.0 end
defp cap(x :: float) :: float do clamp(x, 0.0, 100.0) end
result = 30.0 |> double() |> cap()
print(result) # 60Entry Points
The engine calls specific def functions by convention:
| Function | When called |
|---|---|
def on_init() | Once, before the first tick |
def on_tick(dt :: float) | Every frame, with elapsed time in seconds |
def on_draw() | Every frame, after on_tick |
def main() | Standalone scripts (no engine) |