returning a lambda function in clisp, then evaluating it
Suppose I have this wonderful function foo
[92]> (defun foo () (lambda() 42))
FOO
[93]> (foo)
#<FUNCTION :LAMBDA NIL 42>
[94]>
Now, suppose I want to actually use foo and retu开发者_JS百科rn 42.
How do I do that? I've been scrounging around google and I can't seem to come up with the correct syntax.
You want the FUNCALL
function:
* (defun foo () (lambda () 42))
FOO
* (funcall (foo))
42
The relevant terms here are "Lisp-1" and "Lisp-2".
Your attempt at calling would work in a Lisp-1 like e.g. Scheme or Clojure. Common Lisp is a Lisp-2 however which roughly means that variable names and function names are separate.
So, in order to call the function bound to a variable you either need to use the special forms funcall
or apply
as others have pointed out or set the function value of the symbol foo
rather than the variable value.
The former basically takes the variable value of the symbol, assumes/checks that value is a function and then calls the function (with whatever arguments you passed to funcall
/apply
.
You don't really want to do the latter as that is quite silly in all but very specialised cases, but for completness sake this is roughly how you'd do it:
CL-USER> (setf (symbol-function 'foo) (lambda () 42))
#<FUNCTION (LAMBDA ()) {C43DCFD}>
CL-USER> (foo)
42
You should also want to look into the labels
and flet
special forms (which are commonly used) - there you actually do use the latter methods (these forms create a temporary function binding for symbols).
So your problem would there look like this:
(flet ((foo ()
42))
(foo))
i.e. here you temporarily bind the function value of the symbol foo
to the function returning 42. Within that temporary context you can then call (foo)
like regular global functions.
Your function foo
returns a function. Use the funcall
function to apply a function to arguments, even if the argument set is empty.
Here you can see that foo
returns a value of type function
:
CL-USER> (let ((f (foo)))
(type-of f))
FUNCTION
CL-USER> (let ((f (foo)))
(funcall f))
42
CL-USER> (type-of (foo))
FUNCTION
CL-USER> (funcall (foo))
42
Another option besides FUNCALL is APPLY:
(apply (foo) nil)
FUNCALL is the idiomatic way here, but you'll need APPLY when you have a list of parameters.
精彩评论