0

If I call the following lambda in the REPL, everything works as I'd expect:

CL-USER> (funcall (lambda (x) x) 3)
3
CL-USER> ((lambda (x) x) 3)
3

Now, if I nest the lambda into another lambda, I can't call it without funcall anymore.

CL-USER> (funcall (funcall (lambda () (lambda (x) x))) 3)
3
CL-USER> (funcall ((lambda () (lambda (x) x))) 3)
3
CL-USER> (((lambda () (lambda (x) x))) 3)
; in: ((LAMBDA () (LAMBDA (X) X))) 3
;     (((LAMBDA () (LAMBDA (X) X))) 3)
; 
; caught ERROR:
;   illegal function call
; 
; compilation unit finished
;   caught 1 ERROR condition
; Evaluation aborted on #<SB-INT:COMPILED-PROGRAM-ERROR {1009F09D13}>.

I believe the answer must be very simple, but I haven't been able to figure it out. Why does that happen?

Daniel
  • 11,332
  • 9
  • 44
  • 72

1 Answers1

6

The first position in a function call is not evaluated normally. It can either be a symbol, and its function binding will be used, or it can be a lambda expression, and that anonymous function will be called.

You can't put other expressions there. So you can't put an expression that returns a function. That's why funcall is needed, it's the way to call a function whose value comes from evaluating an expression.

((lambda () (lambda (x) x))) is not a lambda expression or a symbol, it's an ordinary expression that returns a function. So it can't be used at the beginning of a function call.

Barmar
  • 741,623
  • 53
  • 500
  • 612