Lambda Expressions

A lambda is a short inline rule that says “given this input, produce this output”. The => arrow separates the input (left) from the output (right):

x => x * 2

This is read as: “given x, return x * 2”. The name x is a placeholder - it takes on the value of each element as the function processes the array. For example, Map([10, 20, 30], x => x * 2) produces [20, 40, 60].

Jyro supports lambdas as anonymous functions used as arguments to higher-order standard library functions such as Map, Where, Reduce, Find, All, Any, SortBy, and Each.

Syntax

x => x * 2                          # Single parameter
(x, y) => x + y                     # Multiple parameters
(acc, item) => acc + item.price      # Used with Reduce

Parentheses around the parameter list are optional for single-parameter lambdas. They are required for multiple parameters.

Single-expression body

The body of a lambda is a single expression. The value of the expression is implicitly returned.

# Valid - single expression
var doubled = Map(Data.numbers, x => x * 2)

# NOT valid - blocks are not supported in lambdas
# var doubled = Map(Data.numbers, x => { var result = x * 2; return result })

Closures

Lambdas capture variables from the enclosing scope:

var threshold = 100
var big = Where(Data.items, x => x > threshold)    # Captures 'threshold'

Common patterns

# Transform
var doubled = Map(Data.numbers, x => x * 2)
var upper = Map(Data.names, n => ToUpper(n))

# Filter
var adults = Where(Data.users, u => u.age >= 18)
var evens = Where(Data.numbers, x => x % 2 == 0)

# Aggregate
var total = Reduce(Data.items, (sum, item) => sum + item.price, 0)

# Search
var first = Find(Data.items, x => x.status == "pending")

# Check
var anyExpired = Any(Data.items, x => x.expired)
var allValid = All(Data.items, x => x.price > 0)

# Sort by computed key
var byPrice = SortBy(Data.items, x => x.price)

Lambda vs query functions

For simple single-field comparisons, the query functions (WhereByField, FindByField, etc.) are suitable. Lambdas are normally used to pass complex conditions involving multiple fields or computed values.

# Simple field comparison - query is more concise
var active = WhereByField(Data.users, "active", "==", true)

# The above as a lambda
var active = Where(Data.users, u => u.active == true)

# Complex condition - lambda is the only option
var eligible = Where(Data.users, u => u.age >= 18 and u.active and u.balance > 0)

Lambdas can express any condition that query functions can, plus multi-field logic, computed values, and function calls. Query functions are a concise shorthand for the common “filter by one field” pattern.

The one capability unique to query functions is dot-path field traversal with a dynamic field name. Because the field name is a string, it can be stored in a variable:

var field = "address.city"
var result = WhereByField(Data.users, field, "==", "Boston")

A lambda has no equivalent for nested paths:

var field = "address.city"

# Query function - traverses the dot-path "address.city"
var result = WhereByField(Data.users, field, "==", "Boston")    # Works

# Lambda - treats "address.city" as a single top-level key, not a path
var result = Where(Data.users, u => u[field] == "Boston") # Looks for a property literally named "address.city"

Lambdas vs user-defined functions

Jyro has two ways to define reusable logic: lambdas and user-defined functions. They serve different purposes:

  Lambda User-defined function
Syntax x => x * 2 func Double(x) ... end
Scope Captures variables from enclosing scope Isolated - only sees parameters and local vars
Data access Can read Data Cannot access Data (compiler error)
Body Single expression Block of statements (if, while, var, return, etc.)
Naming Anonymous - always inline Named - callable from anywhere in the script
Hoisting Not hoisted Hoisted - can be called before declaration
Use case Inline callbacks for Map, Where, Reduce, etc. Reusable named logic with explicit parameters

Lambdas are lightweight inline expressions that close over their environment. Functions enforce an explicit interface - every dependency comes through the parameter list.

# Lambda - captures 'multiplier' from the enclosing scope
var multiplier = 3
var scaled = Map(Data.values, x => x * multiplier)

# Function - 'multiplier' must be passed as an argument
func Scale(x, multiplier)
    return x * multiplier
end

var scaled = Map(Data.values, x => Scale(x, 3))

Functions and lambdas compose naturally. Define complex logic in a function, then reference it from a lambda:

func IsEligible(customer)
    if customer.age < 18 then return false end
    if customer.status != "active" then return false end
    if customer.balance < 0 then return false end
    return true
end

var eligible = Where(Data.customers, c => IsEligible(c))

Back to top

Copyright © Mesch Systems 2025-2026. All rights reserved.