Functions

Functions are first-class values in Risor. Assign them to variables, pass them as arguments, return them from other functions. In a language with no loops, functions are how you get things done.

Function Declarations

Named functions use the function keyword:

function add(a, b) {
    return a + b
}

return exits the function with a result. Without an explicit return, the function returns nil.

Arrow Functions

Arrow functions are the concise alternative. A single parameter needs no parentheses:

let double = x => x * 2

Multiple parameters require parentheses:

let add = (a, b) => a + b

Single-expression arrows implicitly return. For multi-statement bodies, add braces and an explicit return:

let process = (x) => {
    let result = x * 2
    return result + 1
}

Default Parameters

Parameters can have default values. Omit the argument at the call site and the default kicks in:

function greet(name = "World") {
    return sprintf("Hello, %s!", name)
}
 
greet()        // "Hello, World!"
greet("Alice") // "Hello, Alice!"

Closures

Functions capture variables from their enclosing scope. The inner function holds onto the outer variable even after the outer function has returned:

function makeCounter() {
    let count = 0
    return function() {
        count++
        return count
    }
}
 
let counter = makeCounter()
counter()   // 1
counter()   // 2
counter()   // 3

Each call to makeCounter creates a new, independent count variable, so multiple counters do not interfere with each other.

Higher-Order Functions

Functions are values, so you can pass them to collection methods. This is how you work with collections in Risor since there are no loops:

let numbers = [1, 2, 3, 4, 5]
 
let doubled = numbers.map(x => x * 2)           // [2, 4, 6, 8, 10]
let evens = numbers.filter(x => x % 2 == 0)     // [2, 4]
let sum = numbers.reduce(0, (acc, x) => acc + x) // 15

Compose functions with the pipe operator for a clean data-flow style:

let double = x => x * 2
let addOne = x => x + 1
 
let result = 5 |> double |> addOne   // 11

Recursion

Without loops, recursion handles repeated computation:

function factorial(n) {
    return if (n <= 1) { 1 } else { n * factorial(n - 1) }
}
 
factorial(5)   // 120

Risor © 2026 Deep Noodle