Next: , Previous: , Up: Functions   [Contents][Index]


5.9.2 Closures

A lambda expression itself is not a function; it must be associated with its module, or more correctly a lexical environment. This conjunction is called a “closure”; it is the closure that may be called as a function.

Evaluation turns a lambda expression to its closure. Consider the following example:

(lambda (x) (1+ x))
    ⇒#<closure 1780f10 @ module.foo> 
    ;; Anonymous closure is printed with internal pointer value.

(functionp (lambda (x) (1+ x)))
    ⇒ t

(functionp '(lambda (x) (1+ x)))
    ⇒ ()

(eq (lambda ()) (lambda ()))
    ⇒ () ; Each time `lambda' generates a new instance of closure.

A closure can access bindings which belong to the same module as the closure. A closure can also have its own private bindings. (They’re hidden from the outside, thus “closure”.)

N.B. It seems that define in a closure which is not top-level creates a binding in the closure’s module, NOT inside of the closure.

(define (count-0)
  (define val 0)
  (setq val (1+ val)))

(count-0)
    ⇒ 1
(count-0)
    ⇒ 1
;; Each time `define' resets the value to 0.

(define (count)
  (unless (boundp 'val)
    (define val 0))
  (setq val (1+ val)))

(count)
    ⇒ 1
(count)
    ⇒ 2 ;; Ok, but
val
    ⇒ 2 ;; Not invisible.
Function: closurep arg

Returns true if arg is a closure.

Function: closure-name fun

Returns the name of closure fun, a string. Or if it’s unnamed, nil.

Function: closure-structure fun

Returns the structure fun belongs to.

Function: set-closure-structure closure structure

Sets the structure closure belongs to to structure.

It is often useful to pass a function definition to other functions, instead of function’s name, especially for example to mapc or delete-if. It is called an “anonymous function”, and a lambda expression is all what’s needed.

The following example removes all elements from the list which are even and greater than 20.

(setq list (delete-if (lambda (x)
                        (and (zerop (% x 2)) (> x 20)))
                      list))

There’re some low-level closure handling functions. For example, in certain cases it may be necessary to create a non-constant function, for example by using backquoting (see Backquoting). In these cases the make-closure function may be used to create a function object from a lambda expression.

Function: make-closure arg

Return the closure of arg and the current lexical environment.

Function: closure-function closure

Returns the function object associated with the lexical closure closure.

Function: set-closure-function closure function

Sets the function value of closure to function.

(define (foo) 'foo-sym)
(define (bar) 'bar-sym)
(set-closure-function foo (closure-function bar))
(foo)
    ⇒ foo-sym

Next: , Previous: , Up: Functions   [Contents][Index]