compile/lambda

Symbol: compile/lambda

Syntax (most specific forms first; NAME is optional in all groups):

Shape

Form

Named + return

(lambda NAME :: RET FORMALS BODY ...)

Named + return (type:)

(lambda NAME type: RET FORMALS BODY ...)

Anonymous + return

(lambda :: RET FORMALS BODY ...)

Anonymous + return (type:)

(lambda type: RET FORMALS BODY ...)

Named, no return

(lambda NAME FORMALS BODY ...)

Anonymous, no return

(lambda FORMALS BODY ...)

RET is a single expression (not a formal parameter). Like parameter annotations, it is evaluated in the defining scope when the function is created, and appears on the callable as __annotations__['return'] as a real object – :: int yields the int type itself, and inspect.signature(fn).return_annotation matches. An unbound name raises NameError at function creation, just like an unbound keyword default.

A string literal annotation (:: "Request", :: "pkg.Request") is the forward-reference escape hatch: it is kept as a string and resolved lazily (dotted lookup against the defining namespace) the first time __annotations__ or __signature__ is read. A name that fails to resolve stays a string and is not retried.

Formals: A list or improper list of parameter names, optionally with keyword parameters and defaults, e.g. [a b], [a b c: default-c], or a single symbol for rest. A positional parameter takes a default as a (name default) cell, [a (b 10)]; such cells follow the required positionals, as in Python, and a required name after one is a compile error, as is a name that appears twice in one formals list. Supports * and ** in formals (see gather_formals in helpers and koskari.matcher). Parameter types may use :: / type: on individual parameters (see formals helpers).

Docstring: If the first form in BODY is a string literal, it is taken as the function docstring (discover_docstring in helpers). It is attached to the fragment, stored on Code as code.extras['doc'], and appears on the callable as __doc__. A leading (begin ...) in the body is peeled only for docstring discovery; the body is still compiled in full.

Use-case: Create an anonymous or named function value. Named lambdas bind the given name in the function’s scope so the function can refer to itself (e.g. for recursion in a named let or inline (lambda NAME ...)).

See also: compile/function – named functions without a closure self-binding at creation; used by def, global def, and decorator macros.

Behaviour: Matches one of the shapes above, parses formals with gather_formals, builds a fragment that declares the parameter names, compiles the body with helper_begin, and completes it as a function. Annotation expressions (parameter types and RET) and keyword-default values are compiled in the enclosing scope; their values are consumed at function creation by BUILD_FUNCTION, which builds the keyword-defaults dict and the __annotations__ dict from name tuples carried on the instruction (see KOS_OP_BUILD_FUNCTION).

Examples:

;; Anonymous identity
(lambda [x] x)

;; Anonymous two-argument function
(lambda [a b] (+ a b))

;; Named lambda for recursion
(lambda fact [n]
  (fact ...))

;; Keyword parameter with default
(lambda [x flag: true] ...)

;; Return type (named and anonymous)
(lambda f :: int [x] x)
(lambda :: str [x] "hi")

;; Docstring + return type
(lambda g :: int [x] "doc for g" x)