Skip to content

Lambda expressions#

Code Example

Runnable Example in Jac and JacLib

# Lambda Expressions

# Lambda with parameters and return hint
glob add = lambda  a: int , b: int  -> int:
         a + b;

with entry {
    print(add(5, 3));
}

# Lambda without parameters
glob get_value = lambda : 42 ;

with entry {
    print(get_value());
}

# Lambda without return hint
glob multiply = lambda  x: int , y: int: x * y;

with entry {
    print(multiply(4, 5));
}

# Lambda with only return hint
glob get_default = lambda   -> int: 100 ;

with entry {
    print(get_default());
}

# Lambda with default parameters
glob power = lambda  x: int = 2 , y: int = 3:
         x ** y;

with entry {
    print(power());
    print(power(5));
    print(power(5, 2));
}

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

with entry {
    print(squared);
}

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

with entry {
    print(evens);
}

# Lambda with conditional expression
glob max_val = lambda  a: int , b: int:
         a if a > b else b;

with entry {
    print(max_val(10, 20));
    print(max_val(30, 15));
}

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

with entry {
    print(add_five(10));
}

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

with entry {
    print(sorted_words);
}
# Lambda Expressions

# Lambda with parameters and return hint
glob add = lambda  a: int , b: int  -> int:
         a + b;

with entry {
    print(add(5, 3));
}

# Lambda without parameters
glob get_value = lambda : 42 ;

with entry {
    print(get_value());
}

# Lambda without return hint
glob multiply = lambda  x: int , y: int: x * y;

with entry {
    print(multiply(4, 5));
}

# Lambda with only return hint
glob get_default = lambda   -> int: 100 ;

with entry {
    print(get_default());
}

# Lambda with default parameters
glob power = lambda  x: int = 2 , y: int = 3:
         x ** y;

with entry {
    print(power());
    print(power(5));
    print(power(5, 2));
}

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

with entry {
    print(squared);
}

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

with entry {
    print(evens);
}

# Lambda with conditional expression
glob max_val = lambda  a: int , b: int:
         a if a > b else b;

with entry {
    print(max_val(10, 20));
    print(max_val(30, 15));
}

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

with entry {
    print(add_five(10));
}

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

with entry {
    print(sorted_words);
}
from __future__ import annotations

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 | code_block )
           | KW_LAMBDA func_decl? ( COLON expression | code_block )

Description

Lambda expressions in Jac create anonymous functions with a concise syntax, suitable for short function definitions used inline or passed as arguments.

What are Lambda Expressions?

Lambda expressions are a way to create small, unnamed functions without using the full def syntax. They are ideal for simple operations that are used once, such as 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. A lambda can be written as 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 enables documentation of the lambda's return value even when 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

Lambdas are appropriate for:

  • Simple, one-line operations
  • Inline function definitions for map, filter, sorted, etc.
  • Callback functions that are used only once
  • Closures with simple logic

Regular functions are appropriate for:

  • Multiple statements or complex logic
  • Better documentation with docstrings
  • Reusable code that appears in multiple places
  • Variadic arguments or complex parameter handling