lambda
In Common Lisp, you can use a lambda expression to create an anonymous function — a function with no name. Instead of registering a function globally with defun, use lambda when you want to express a one-off operation as a function. It is widely used as a foundation of functional programming: called directly with funcall, or passed to higher-order functions such as mapcar and sort.
Basic syntax of lambda
| Element | Description |
|---|---|
(lambda (params...) body...) | The basic form for creating an anonymous function. The value of the last expression in the body becomes the return value. |
#'(lambda ...) | Prefixing with #' (the function shorthand) extracts the lambda as a function object. |
| Parameter list | Supports &optional, &key, and &rest, just like defun. |
| Closure | Captures variables from the scope at the time of definition. Variables from let or defvar can be referenced. |
Calling with funcall
| Syntax | Description |
|---|---|
(funcall function-object args...) | Calls a function object stored in a variable. A typical pattern is to bind a lambda to a variable using let and then call it with funcall. |
((lambda ...) args...) | A lambda expression can also be called directly by placing it at the head of a form (self-application form). However, using funcall is more common for readability. |
(apply function-object list) | Calls a function with its arguments supplied as a list. Use this when the number of arguments is determined at runtime. |
Combining with higher-order functions
| Function | Description |
|---|---|
mapcar | Applies a lambda to each element of a list and returns a new list of the results. |
remove-if | Removes elements from a list for which a lambda returns true. |
sort | Sorts a list by passing a lambda as the comparison function. |
find-if | Returns the first element in a list for which a lambda returns true. |
Sample code
lambda.lisp
; ========================================
; lambda.lisp — lambda examples with KOF characters
; Demonstrates lambda (anonymous functions) and funcall
; ========================================
; ----------------------------------------
; Basics: bind a lambda to a variable and call it with funcall
; ----------------------------------------
; Assigns an anonymous function to the variable greet using let
; Passes the variable and arguments to funcall to invoke it
; ----------------------------------------
(format t "=== Calling a lambda with funcall ===~%")
(let ((greet (lambda (name)
; Takes a name and prints a greeting
(format t "~A, reporting in!~%" name))))
(funcall greet "Kyo Kusanagi")
(funcall greet "Iori Yagami")
(funcall greet "Terry Bogard"))
; ----------------------------------------
; lambda with multiple parameters
; ----------------------------------------
; Example of an anonymous function that takes two arguments
; ----------------------------------------
(format t "~%=== lambda with multiple parameters ===~%")
(let ((show-fighter (lambda (name power)
; Formats and prints the character name and power level
(format t "~A — Power: ~A~%" name power))))
(funcall show-fighter "Kyo Kusanagi" 9500)
(funcall show-fighter "Iori Yagami" 9800)
(funcall show-fighter "Terry Bogard" 9200)
(funcall show-fighter "Mai Shiranui" 8800)
(funcall show-fighter "Krizalid" 9900))
; ----------------------------------------
; Transforming a list with mapcar and lambda
; ----------------------------------------
; mapcar applies a function to each element of a list
; and returns the resulting list
; ----------------------------------------
(format t "~%=== Transforming a list with mapcar + lambda ===~%")
(defvar *fighters*
(list "Kyo Kusanagi" "Iori Yagami" "Terry Bogard" "Mai Shiranui" "Krizalid"))
; Adds the "Chosen: " prefix to each character name
(defvar *labeled*
(mapcar (lambda (name)
(format nil "Chosen: ~A" name))
*fighters*))
(dolist (s *labeled*)
(format t "~A~%" s))
; ----------------------------------------
; Filtering a list with remove-if and lambda
; ----------------------------------------
; Removes elements for which the lambda returns true
; ----------------------------------------
(format t "~%=== Filtering a list with remove-if + lambda ===~%")
; Each entry is a cons cell of (character-name . power-level)
(defvar *power-table*
(list (cons "Kyo Kusanagi" 9500)
(cons "Iori Yagami" 9800)
(cons "Terry Bogard" 9200)
(cons "Mai Shiranui" 8800)
(cons "Krizalid" 9900)))
; Removes characters with a power level below 9500
(defvar *high-power*
(remove-if (lambda (entry)
; Uses cdr to get the right side of the cons cell (power level)
(< (cdr entry) 9500))
*power-table*))
(format t "Characters with power level 9500 or above:~%")
(dolist (entry *high-power*)
(format t " ~A (~A)~%" (car entry) (cdr entry)))
; ----------------------------------------
; Sorting a list with sort and lambda
; ----------------------------------------
; sort is a destructive operation — pass a copy-list copy to be safe
; ----------------------------------------
(format t "~%=== Sorting a list with sort + lambda ===~%")
; Sorts by power level in descending order (highest first)
(defvar *sorted*
(sort (copy-list *power-table*)
(lambda (a b)
; Compares cdr values with > to sort in descending order
(> (cdr a) (cdr b)))))
(format t "Power ranking:~%")
(let ((rank 1))
(dolist (entry *sorted*)
(format t " #~A: ~A (~A)~%" rank (car entry) (cdr entry))
(setf rank (+ rank 1))))
; ----------------------------------------
; Closures — capturing variables from the outer scope
; ----------------------------------------
; A lambda "closes over" variables from its defining scope
; and retains access to them later. This is called a closure.
; ----------------------------------------
(format t "~%=== Closure ===~%")
; Returns a greeting function with the given prefix captured inside
(defun make-greeter (prefix)
"Returns a greeting function with prefix embedded."
(lambda (name)
; prefix retains the value from when make-greeter was called
(format t "~A~A!~%" prefix name)))
(let ((kof-greeter (make-greeter "KOF Fighter: "))
(boss-greeter (make-greeter "Boss: ")))
(funcall kof-greeter "Kyo Kusanagi")
(funcall kof-greeter "Mai Shiranui")
(funcall boss-greeter "Krizalid"))
; ----------------------------------------
; apply — calling a function with arguments as a list
; ----------------------------------------
; apply receives arguments as a list
; (apply fn '(arg1 arg2)) is equivalent to (funcall fn arg1 arg2)
; ----------------------------------------
(format t "~%=== Calling a lambda with apply ===~%")
(let ((max-power (lambda (a b)
; Returns the larger of two power level values
(if (> a b) a b))))
(format t "Kyo(9500) vs Iori(9800) — higher: ~A~%"
(apply max-power '(9500 9800)))
(format t "Terry(9200) vs Krizalid(9900) — higher: ~A~%"
(apply max-power '(9200 9900))))
sbcl --script lambda.lisp === Calling a lambda with funcall === Kyo Kusanagi, reporting in! Iori Yagami, reporting in! Terry Bogard, reporting in! === lambda with multiple parameters === Kyo Kusanagi — Power: 9500 Iori Yagami — Power: 9800 Terry Bogard — Power: 9200 Mai Shiranui — Power: 8800 Krizalid — Power: 9900 === Transforming a list with mapcar + lambda === Chosen: Kyo Kusanagi Chosen: Iori Yagami Chosen: Terry Bogard Chosen: Mai Shiranui Chosen: Krizalid === Filtering a list with remove-if + lambda === Characters with power level 9500 or above: Kyo Kusanagi (9500) Iori Yagami (9800) Krizalid (9900) === Sorting a list with sort + lambda === Power ranking: #1: Krizalid (9900) #2: Iori Yagami (9800) #3: Kyo Kusanagi (9500) #4: Terry Bogard (9200) #5: Mai Shiranui (8800) === Closure === KOF Fighter: Kyo Kusanagi! KOF Fighter: Mai Shiranui! Boss: Krizalid! === Calling a lambda with apply === Kyo(9500) vs Iori(9800) — higher: 9800 Terry(9200) vs Krizalid(9900) — higher: 9900
Summary
The lambda form in Common Lisp creates an anonymous function — a function without a name. You write it as (lambda (parameter-list) body...) and either pass it to funcall or use it directly as an argument to higher-order functions such as mapcar, remove-if, and sort. Use apply to call a function with its arguments supplied as a list. Because a lambda acts as a closure, capturing variables from the scope in which it was defined, you can naturally write functions like make-greeter that return a function with configuration baked in.
For defining named functions, see defun. For higher-order list functions, see the pages for mapcar and remove_if.
If you find any errors or copyright issues, please contact us.