I want to create a macro that returns a lambda, but I keep getting compile errors. When you macroexpand regular lambdas you get the following:
(print (macroexpand '(LAMBDA (X) (+ 1 X))))
=> #'(LAMBDA (X) (+ 1 X))
Now, let's say I want to create a macro that expands to a lambda, for example:
(defmacro test (x) `(lambda (x) (+ 1 x)))
If I print the expansion of that macro I get the expected expansion:
(print (macroexpand '(test x)))
=> #'(LAMBDA (X) (+ 1 X))
Exactly the same as a regular lambda. But when I try to use the "test" macro I still have to use "funcall" to make it work.
(print ((LAMBDA (X) (+ 1 X)) 1))
=> 2
(print (funcall (test x) 1))
=> 2
(print ((test x) 1))
=> Execution of a form compiled with errors.
Form:
((TEST X) 1)
Compile-time error:
illegal function call
How is this possible?
The test
macro expands to a regular lambda, and my understanding is that after the expansion, lisp should not be able to know that it even came from a macro, it should be indistinguishable from a lambda.
How is common lisp able to use regular lambdas in the operator position of expressions without using "funcall" and how can I do the same?
Does anyone know what's going on here?
The operator position of an expression is not treated as an expression, so it doesn't undergo macro expansion like the arguments do.
It works for LAMBDA
because the syntax of the operator position specifically allows for lambda expressions there. The fact that there's a macro named LAMBDA
is a coincidence, it's not used to implement this. It's specified in the CLHS description of Lambda Forms:
A lambda form is similar to a function form, except that the function name is replaced by a lambda expression.
Lambda forms are mostly a legacy feature for compatibility with earlier dialects. And the LAMBDA
macro was a Common Lisp innovation, which was created just as a convenience so we wouldn't have to type #'
whenever we use a lambda expression as a value. This is unrelated to the use of lambda expressions in lambda forms.