This question already has answers here:
Why do we need funcall in Lisp?
(3 answers)
Closed 6 years ago.
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.
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
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)