Functions & Closures

Functions in Djazair are first-class citizens. They can be stored in variables, passed as arguments, returned from other functions, and capture lexical closures.

Defining Functions

djazair
# Standard function declaration
fn add(a, b)
    return a + b
end

print(add(10, 20)) # => 30

# Concise Arrow Function expression
let multiply = fn(a, b) => a * b
print(multiply(4, 5)) # => 20

Default Arguments

Parameters can have default expressions, which can even reference previous parameters:

djazair
fn greet(name = "World", greeting = "Hello")
    print("${greeting}, ${name}!")
end

greet()                 # => Hello, World!
greet("Riad")           # => Hello, Riad!
greet("Ali", "Welcome") # => Welcome, Ali!

# Referencing earlier parameters in default values:
fn calculateOffset(base, step = base * 2)
    return base + step
end
print(calculateOffset(5)) # => 15 (5 + 10)

Rest Parameters (...args)

Variadic functions accept any number of trailing arguments packed into an Array:

djazair
fn sumAll(initial, ...rest)
    let total = initial
    for val in rest
        total += val
    end
    return total
end

print(sumAll(10, 1, 2, 3, 4)) # => 20

Lexical Closures

Functions maintain a reference to their enclosing scope even after the outer function has returned:

djazair
fn createCounter(start = 0)
    let count = start
    return fn()
        count++
        return count
    end
end

let c1 = createCounter(10)
print(c1()) # => 11
print(c1()) # => 12

let c2 = createCounter(100)
print(c2()) # => 101 (independent closure environment)