问题
I'm trying to use a function to return a function in common lisp. However, I've run into a strange situation I'd like explained.
This is what I want to do:
(defun makefun(x) ;1
(lambda (z)
(+ x z)))
((makefun 1) 2) ;2
This results in an illegal function call. However, the following are valid:
((lambda (z) (+ 1 z)) 2) ;3
(funcall (makefun 1) 2) ;4
Why can I not use makefun as in the first example? I'd expect the call in 2 to be evaluated so it would be equivalent to line 3.
回答1:
If answered a similar question already on Stackoverflow. It's a duplicate. Would need to find it.
Anyway.
(defun makefun(x) ;1
(lambda (z)
(+ x z)))
((makefun 1) 2)
Common Lisp does not allow evaluation in the function position. It requires you to put a symbol or an actual lambda expression there.
Remember: Common Lisp has a separate function namespace. The value namespace is different. Here MAKEFUN
returns a value and this value is not available in the function namespace.
There are only two syntactic ways to call a function:
(foo 1 2)
and
((lambda (a b) (list a b)) 1 2)
See CLHS (Conses as Forms). Here we have a Lambda Form.
Adding the capability to write ((some-function-returning-function) 1 2)
would make function calling in Common Lisp more confusing:
(foo 1 2)
would use the function namespace((some-function-returning-function) 1 2)
would use the value namespace
回答2:
Common Lisp has several different namespaces, and in function forms, the functional value of the operator is used. Your lambda
example works, because lambda forms are a separate branch in the evaluation rules. You can just google for "Common Lisp namespaces" "Lisp-1 vs. Lisp-2" for more details, and there are quite a few questions and answers here on SO that cover those topics.
But, to answer your particular question, use funcall (you can also take a look at apply):
(funcall (makefun 1) 2)
来源:https://stackoverflow.com/questions/14204683/cannot-use-function-call-as-first-argument-in-s-exp