Skip to content

Lambda expressions#

Code Example

Runnable Example in Jac and JacLib

# Lambda Expressions

with entry {
    # Lambda with parameters and return hint
    add = lambda a: int, b: int -> int : a + b;
    print(add(5, 3));

    # Lambda without parameters
    get_value = lambda : 42;
    print(get_value());

    # Lambda without return hint
    multiply = lambda x: int, y: int : x * y;
    print(multiply(4, 5));

    # Lambda with only return hint
    get_default = lambda -> int : 100;
    print(get_default());

    # Lambda with default parameters
    power = lambda x: int = 2, y: int = 3 : x ** y;
    print(power());
    print(power(5));
    print(power(5, 2));

    # Lambda as argument to function
    numbers = [1, 2, 3, 4, 5];
    squared = list(map(lambda x: int : x ** 2, numbers));
    print(squared);

    # Lambda in filter
    evens = list(filter(lambda x: int : x % 2 == 0, numbers));
    print(evens);

    # Lambda with conditional expression
    max_val = lambda a: int, b: int : a if a > b else b;
    print(max_val(10, 20));
    print(max_val(30, 15));

    # Lambda returning lambda
    make_adder = lambda x: int : (lambda y: int : x + y);
    add_five = make_adder(5);
    print(add_five(10));

    # Lambda in sort key
    words = ["apple", "pie", "a", "cherry"];
    sorted_words = sorted(words, key=lambda s: str : len(s));
    print(sorted_words);
}
# Lambda Expressions

with entry {
    # Lambda with parameters and return hint
    add = lambda a: int, b: int -> int : a + b;
    print(add(5, 3));

    # Lambda without parameters
    get_value = lambda : 42;
    print(get_value());

    # Lambda without return hint
    multiply = lambda x: int, y: int : x * y;
    print(multiply(4, 5));

    # Lambda with only return hint
    get_default = lambda -> int : 100;
    print(get_default());

    # Lambda with default parameters
    power = lambda x: int = 2, y: int = 3 : x ** y;
    print(power());
    print(power(5));
    print(power(5, 2));

    # Lambda as argument to function
    numbers = [1, 2, 3, 4, 5];
    squared = list(map(lambda x: int : x ** 2, numbers));
    print(squared);

    # Lambda in filter
    evens = list(filter(lambda x: int : x % 2 == 0, numbers));
    print(evens);

    # Lambda with conditional expression
    max_val = lambda a: int, b: int : a if a > b else b;
    print(max_val(10, 20));
    print(max_val(30, 15));

    # Lambda returning lambda
    make_adder = lambda x: int : (lambda y: int : x + y);
    add_five = make_adder(5);
    print(add_five(10));

    # Lambda in sort key
    words = ["apple", "pie", "a", "cherry"];
    sorted_words = sorted(words, key=lambda s: str : len(s));
    print(sorted_words);
}
from __future__ import annotations
from jaclang.runtimelib.builtin import *
add = lambda a, b: a + b
print(add(5, 3))
get_value = lambda: 42
print(get_value())
multiply = lambda x, y: x * y
print(multiply(4, 5))
get_default = lambda: 100
print(get_default())
power = lambda x=2, y=3: x ** y
print(power())
print(power(5))
print(power(5, 2))
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print(squared)
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)
max_val = lambda a, b: a if a > b else b
print(max_val(10, 20))
print(max_val(30, 15))
make_adder = lambda x: lambda y: x + y
add_five = make_adder(5)
print(add_five(10))
words = ['apple', 'pie', 'a', 'cherry']
sorted_words = sorted(words, key=lambda s: len(s))
print(sorted_words)
Jac Grammar Snippet
lambda_expr: KW_LAMBDA func_decl_params? (RETURN_HINT expression)? COLON expression

Description

Lambda expressions in Jac create anonymous functions with a concise syntax, perfect for short function definitions that you need to use inline or pass as arguments.

What are Lambda Expressions?

Lambda expressions are a way to create small, unnamed functions without using the full def syntax. They're ideal for simple operations that you only need once, like transforming data in a map or filter operation.

Basic Lambda Syntax

The general structure of a lambda expression follows this pattern:

Component Description Required
lambda keyword Marks the start of a lambda expression Yes
Parameters Input parameters with optional type hints No
-> return type Type hint for the return value No
: separator Separates signature from body Yes
Expression Single expression to evaluate and return Yes

Lambda with Full Type Annotations

Line 5 shows a lambda with complete type annotations. The expression lambda a: int, b: int -> int : a + b defines a function that takes two integer parameters and returns their sum. This is equivalent to:

The lambda version is more concise and can be assigned to a variable (line 5) or passed directly as an argument.

Lambda Without Parameters

Lines 9-10 demonstrate the simplest form of lambda: one that takes no parameters and just returns a constant value. The syntax lambda : 42 creates a function that always returns 42 when called.

Lambda Without Return Type Hints

Lines 13-14 show that type hints are optional. You can write lambda x: int, y: int : x * y without specifying the return type. Jac will infer the return type from the expression.

Lambda with Only Return Type

Lines 17-18 demonstrate specifying just the return type without parameters: lambda -> int : 100. This is useful when you want to document what the lambda returns even though it takes no inputs.

Default Parameter Values

Lines 21-24 show how lambdas can have default parameter values, just like regular functions:

Call Values Used Result
power() (line 22) x=2, y=3 (defaults) 8
power(5) (line 23) x=5, y=3 (y default) 125
power(5, 2) (line 24) x=5, y=2 25

Lambdas as Function Arguments

One of the most common uses for lambdas is passing them as arguments to higher-order functions.

Lines 27-29 demonstrate using a lambda with the map function to square each number in a list. The lambda lambda x: int : x ** 2 is applied to each element.

Lines 32-33 show using a lambda with filter to select only even numbers. The lambda lambda x: int : x % 2 == 0 returns true for even numbers.

Lambdas with Conditional Expressions

Lines 36-38 demonstrate that the expression body of a lambda can be a conditional (ternary) expression. The lambda lambda a: int, b: int : a if a > b else b returns the maximum of two values.

Lambda Returning Lambda

Lines 41-43 show a more advanced pattern: a lambda that returns another lambda. This creates closures where the inner lambda captures variables from the outer lambda. Line 41 creates a function that returns an "adder" function, and line 42 creates a specific adder that adds 5 to its input.

graph LR
    A[make_adder(5)] --> B[Returns: lambda y: 5 + y]
    B --> C[add_five(10)]
    C --> D[Returns: 15]

Lambda as Sort Key

Lines 46-48 demonstrate using a lambda as a key function for sorting. The sorted function uses the lambda lambda s: str : len(s) to determine the sort order, sorting strings by their length rather than alphabetically.

Lambda Limitations

Important things to know about lambdas in Jac:

Feature Supported in Lambda?
Single expression Yes
Multiple statements No
Assignments No (except walrus :=)
Type annotations Yes
Default parameters Yes
Variadic arguments (*args, **kwargs) No
Control flow statements (if/for/while as statements) No
Conditional expressions (ternary) Yes

For complex logic requiring multiple statements or control flow, use regular def functions instead.

When to Use Lambdas

Use lambdas when you need: - Simple, one-line operations - Inline function definitions for map, filter, sorted, etc. - Callback functions that are used only once - Closures with simple logic

Use regular functions when you need: - Multiple statements or complex logic - Better documentation with docstrings - Reusable code that appears in multiple places - Variadic arguments or complex parameter handling