Skip to content

Functions

github-actions[bot] edited this page May 2, 2026 · 1 revision

Functions

Flow supports procedure declarations (proc), lambda functions, closures, function overloading, and higher-order functions.

Procedure Declarations

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

Implicit Returns

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

Explicit Returns

Use return to return early:

proc abs (Int: x)
    (if (lt x 0) (return (sub 0 x)) x)
end proc

Multiple Parameters

proc greet (String: name, String: greeting)
    (concat greeting (concat ", " name))
end proc

String msg = (greet "Flow" "Hello")
(print msg)  Note: Hello, Flow

Calling Functions

Functions are called with parentheses around the call:

Int result = (double 5)
(print (str result))

Optional Parentheses

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

Lambda Functions

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

Function Type Annotations

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

Closures

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)

Higher-Order Functions

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))))

Function Overloading

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 with the Flow Operator

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)

Nested Lambda Calls

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)

See Also

Clone this wiki locally