3 ms·
In Common Lisp: a list (lambda () (print :foo)) is not code: CL-USER 10 > (let ((l '(lambda () (print :foo)))) (funcall l)) Error: Arg
by lispm 9y ago
In Common Lisp:
a list (lambda () (print :foo)) is not code:
CL-USER 10 > (let ((l '(lambda () (print :foo))))
(funcall l))
Error: Argument to apply/funcall is not a function: (LAMBDA NIL (PRINT :FOO)).
But the unquoted lambda form is code, since Common Lisp has a LAMBDA macro
CL-USER 13 > (let ((l (lambda () (print :foo))))
(funcall l))
:FOO
:FOO
The LAMBDA macro transforms it into a FUNCTION special form with an embedded lambda expression:
CL-USER 14 > (macroexpand-1 '(lambda () (print :foo)))
(FUNCTION (LAMBDA NIL (PRINT :FOO)))
Thus in Common Lisp we can evaluate:
a) the special form FUNCTION:
(FUNCTION (LAMBDA () (PRINT :FOO)))
b) the same, but using #' as a short version:
#'(LAMBDA () (PRINT :FOO))
c) or the macro LAMBDA, which expands into a)
(LAMBDA () (PRINT :FOO))
- white-flame 9y agoOne other combination in Common Lisp is that lambda expressions are usable as the head of a form, in place of a function name: ;; Call a function object held in a variable (let ((add (lambda (a b) (+ a b)))) (funcall add 1 2)) vs ;; Direct execution of a lambda expression ((lambda (a b) (+ a b)) 1 2) Macro expansion can place a literal or generated lambda expression there instead of using FUNCALL at all.
- sillysaurus3 9y agoThat's not actually a limitation of emacs lisp. It's just a design decision. I know exactly the spot in the code where they could do what you suggest, because I've often wondered why they don't. elisp gets a bad rap. But it's mostly self-inflicted. Also http://www.patrickkphillips.com/grammar/is-it-a-bad-rap-or-bad-rep/ http://www.patrickkphillips.com/grammar/is-it-a-bad-rap-or-b... A “rap sheet” is a criminal record, and a “bum rap” meant a false accusation (or even a false conviction). Even when the charge was valid, it should come as no surprise, a guilty party might claim it was a “bum rap” just to save face. Had no idea what a bad rap actually meant.
- microcolonel 9y agoIt sure is lovely that a world has been created where most people don't even need to know what "rap sheet" means.
- lisper 9y ago> Macro expansion can place a literal or generated lambda expression there instead of using FUNCALL at all. Not quite. This, for example, does not work: (defmacro foo () '(lambda (x) x)) ((foo) 1) A macro can expand into a form whose CAR is a literal lambda expression, but because there is always an equivalent LET form I can't think of a circumstance where this can do anything but obfuscate the code. Personally, I think this is a flaw in the design of CL. Long ago I proposed an extension that would allow the CAR of a form to be a macro: http://www.flownet.com/ron/lisp/combination-hook.lisp http://www.flownet.com/ron/lisp/combination-hook.lisp I think it's cool for pedagogy because it lets you do things like directly define the Y combinator in CL without a ton of FUNCALLs. But it never caught on.
- kazinator 9y agoI don't know if this is worth mentioning, but a lambda expression datum can be coerce-d into a function: (let ((l '(lambda () (print :foo)))) (funcall (coerce l 'function))) not to mention passed to eval or compile.