-
Notifications
You must be signed in to change notification settings - Fork 0
Functions
Flow supports procedure declarations (proc), lambda functions, closures, function overloading, and higher-order functions.
Functions are declared with proc and terminated with end proc:
proc double (Int: x)
x * 2
end proc
Int result = (double 7)
(print (str result)) Note: 14
The last non-void expression in a proc body is automatically the return value:
proc add (Int: a, Int: b)
a + b
end proc
Int sum = (add 3 4) Note: 7
Use return to return early:
proc abs (Int: x)
(if (lt x 0) (return (sub 0 x)) x)
end proc
proc greet (String: name, String: greeting)
(concat greeting (concat ", " name))
end proc
String msg = (greet "Flow" "Hello")
(print msg) Note: Hello, Flow
Functions are called with parentheses around the call:
Int result = (double 5)
(print (str result))
When calling a function with literal arguments, parentheses are optional:
proc square (Int: n)
n * n
end proc
Int s1 = square 4 Note: works with literal
Int s2 = (square val) Note: parens needed for variable args
Lambdas are anonymous functions created with fn:
use "@std"
Note: Single parameter
Function doubler = fn Int n => (mul n 2)
Int r = (doubler 5) Note: 10
Note: Multiple parameters
Function adder = fn Int a, Int b => (add a b)
Int s = (adder 3 4) Note: 7
Note: Zero parameters
Function getFortyTwo = fn => 42
Int answer = (getFortyTwo) Note: 42
Use arrow syntax for precise type annotations:
(Int => Int) tripler = fn Int n => (mul n 3)
(Int, Int => Int) multiplier = fn Int a, Int b => (mul a b)
(Void => Int) constVal = fn => 99
The generic Function type also works:
Function myFunc = fn Int n => n * 2
Lambdas capture variables from their enclosing scope at the time of creation (snapshot capture):
use "@std"
Int x = 10
Function addX = fn Int n => (add n x)
Int result = (addX 5) Note: 15
Note: Snapshot: changing x after creation doesn't affect the lambda
x = 999
Int result2 = (addX 5) Note: still 15 (captured x=10)
Functions can take other functions as arguments:
use "@std"
use "@collections"
Int[] nums = (list 1 2 3 4 5)
Note: Map - transform each element
Int[] doubled = (map nums (fn Int n => (mul n 2)))
(print (str doubled)) Note: [2, 4, 6, 8, 10]
Note: Filter - keep elements matching predicate
Int[] big = (filter nums (fn Int n => (gt n 3)))
(print (str big)) Note: [4, 5]
Note: Reduce - fold with accumulator
Int total = (reduce nums 0 (fn Int acc, Int n => (add acc n)))
(print (str total)) Note: 15
Note: Each - side effects
(each nums (fn Int n => (print (str n))))
Multiple functions can share the same name with different parameter types. Flow's overload resolver picks the best match:
use "@std"
Note: str() works on Int, Float, String, Bool, Note, etc.
(print (str 42)) Note: "42"
(print (str 3.14)) Note: "3.14"
(print (str true)) Note: "true"
The resolver scores candidates: exact match (+1000), compatible type (+500), convertible type (+100).
Lambdas work naturally with ->:
use "@std"
Function doubler = fn Int n => (mul n 2)
Function tripler = fn Int n => (mul n 3)
Int result = 3 -> doubler -> tripler
(print (str result)) Note: 18 (3*2=6, 6*3=18)
use "@std"
Function doubler = fn Int n => (mul n 2)
Function tripler = fn Int n => (mul n 3)
Function compose = fn Int n => (doubler (tripler n))
Int result = (compose 2)
(print (str result)) Note: 12 (2*3=6, 6*2=12)
-
Flow Operator - Chaining with
-> -
Collections -
map,filter,reduce, and more - Standard Library - All built-in functions