Cannot use function call as first argument in s-ex

2020-03-30 04:07发布

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.

2条回答
Emotional °昔
2楼-- · 2020-03-30 04:25

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
查看更多
Fickle 薄情
3楼-- · 2020-03-30 04:29

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)
查看更多
登录 后发表回答