function-lambda-expression
function-lambda-expression Function
Syntax:
function-lambda-expression function→ lambda-expression, closure-p, name
Arguments and Values:
function—a function.
lambda-expression—a lambda expression or nil.
closure-p—a generalized boolean.
name—an object.
Description:
Returns information about function as follows:
The primary value, lambda-expression, is function’s defining lambda expression, or nil if the information is not available. The lambda expression may have been pre-processed in some ways, but it should remain a suitable argument to compile or function. Any implementation may legitimately return nil as the lambda-expression of any function.
The secondary value, closure-p, is nil if function’s definition was enclosed in the null lexical environment or something non-nil if function’s definition might have been enclosed in some non-null lexical environment. Any implementation may legitimately return true as the closure-p of any function.
The tertiary value, name, is the “name” of function. The name is intended for debugging only and is not necessarily one that would be valid for use as a name in defun or function, for example. By convention, nil is used to mean that function has no name. Any implementation may legitimately return nil as the name of any function.
Examples:
The following examples illustrate some possible return values, but are not intended to be exhaustive:
(function-lambda-expression #’(lambda (x) x))
→ NIL, *false*, NIL
<i><sup>or</sup>→</i> NIL, <i>true</i>, NIL
<i><sup>or</sup>→</i> (LAMBDA (X) X), <i>true</i>, NIL
<i><sup>or</sup>→</i> (LAMBDA (X) X), <i>false</i>, NIL
(function-lambda-expression
(funcall #’(lambda () #’(lambda (x) x))))
→ NIL, *false*, NIL
<i><sup>or</sup>→</i> NIL, <i>true</i>, NIL
<i><sup>or</sup>→</i> (LAMBDA (X) X), <i>true</i>, NIL
<i><sup>or</sup>→</i> (LAMBDA (X) X), <i>false</i>, NIL
(function-lambda-expression
(funcall #’(lambda (x) #’(lambda () x)) nil))
→ NIL, *true*, NIL
<i><sup>or</sup>→</i> (LAMBDA () X), <i>true</i>, NIL
<i><sup>not</sup> →</i> NIL, <i>false</i>, NIL
<i><sup>not</sup> →</i> (LAMBDA () X), <i>false</i>, NIL
(flet ((foo (x) x))
(setf (symbol-function ’bar) #’foo)
(function-lambda-expression #’bar))
→ NIL, *false*, NIL
<i><sup>or</sup>→</i> NIL, <i>true</i>, NIL
<i><sup>or</sup>→</i> (LAMBDA (X) (BLOCK FOO X)), <i>true</i>, NIL
<i><sup>or</sup>→</i> (LAMBDA (X) (BLOCK FOO X)), <i>false</i>, FOO
<i><sup>or</sup>→</i> (SI::BLOCK-LAMBDA FOO (X) X), <i>false</i>, FOO
(defun foo ()
(flet ((bar (x) x))
#’bar))
(function-lambda-expression (foo))
→ NIL, *false*, NIL
<i><sup>or</sup>→</i> NIL, <i>true</i>, NIL
<i><sup>or</sup>→</i> (LAMBDA (X) (BLOCK BAR X)), <i>true</i>, NIL
<i><sup>or</sup>→</i> (LAMBDA (X) (BLOCK BAR X)), <i>true</i>, (:INTERNAL FOO 0 BAR)
<i><sup>or</sup>→</i> (LAMBDA (X) (BLOCK BAR X)), <i>false</i>, "BAR in FOO"
Notes:
Although implementations are free to return “nil, true, nil” in all cases, they are encouraged to return a lambda expression as the primary value in the case where the argument was created by a call to compile or eval (as opposed to being created by loading a compiled file).
Data and Control
Expanded Reference: function-lambda-expression
Retrieving a Lambda Expression
function-lambda-expression returns three values: the lambda expression (or nil), a boolean indicating whether the function was closed over non-null environment, and the name of the function (or nil). Implementations are not required to return the lambda expression.
;; Results are implementation-dependent; the lambda may or may not be available
(function-lambda-expression #'(lambda (x) (1+ x)))
;; => (LAMBDA (X) (1+ X)) ; implementation-dependent
Named Functions
For named functions defined with defun, the third value is typically the function name.
(defun double (x) (* x 2))
(multiple-value-bind (lambda-expr closure-p name)
(function-lambda-expression #'double)
(list :lambda lambda-expr :closure-p closure-p :name name))
;; => (:LAMBDA NIL :CLOSURE-P NIL :NAME DOUBLE) ; implementation-dependent
Closures May Not Return the Lambda
When a function closes over variables, the second return value indicates this, and the lambda expression is often unavailable.
(let ((counter 0))
(let ((incrementer (lambda () (incf counter))))
(multiple-value-list (function-lambda-expression incrementer))))
;; => (NIL T NIL) ; implementation-dependent
Compiled Functions
Compiled functions frequently return nil for the lambda expression since the source may not be retained after compilation.
(multiple-value-list
(function-lambda-expression (compile nil (lambda (x) (* x x)))))
;; => (NIL T NIL) ; implementation-dependent