Procedures, Arity, Application, and apply

Fixed and dotted-arity closures use lexical scope, deterministic argument evaluation, and one application dispatcher shared by direct calls and `apply`.

When this matters

Create a procedure when one transformation has a name or must be passed to another procedure. Named shorthand is easiest to read; lambda is useful when the behavior is small and local.

See it run

LISPEX
(define (sum first . rest) (apply + first rest))
(sum 1 2 3 4)

Observed result

OUTPUT
10

Read the example

sum requires at least one argument. first receives 1, while rest receives the fresh list (2 3 4). apply combines the explicit first argument with that list and invokes + once.

How to reason about it

  • Arity mismatch is E302 before the procedure body starts.
  • A dotted rest parameter receives a fresh proper list of remaining arguments.
  • apply accepts explicit leading arguments plus one final proper list and preserves tail position.

Choose quickly

ShapeBest useArity
(define (f x) body)a named reusable procedurefixed
(lambda (x y) body)an anonymous procedure valuefixed
(lambda args body)all arguments as one listzero or more
(lambda (x . rest) body)required arguments plus a remainderat least the fixed prefix
(apply f a final-list)arguments assembled as datachecked by f

A common mistake

Applying a non-procedure is E301; an improper final apply list is a list-domain error.

Current boundaries

  • Host apply is not used to execute guest closures.

Keep going

Higher-order procedures explains passing behavior to map, filter, and fold. Bindings explains the cells a closure captures.

Higher-order procedures · Bindings and scope