This answer gives a bit of detail behind the first part of @Daimrod's correct answer.
Your question is why this works:
(defun foo (x) `(lambda () ,x)) (message (string (funcall (foo 66))))
and this doesn't work:
(defun foo (x) '(lambda () x)) (message (string (funcall (foo 66))))
First, the quote ('
) is unnecessary in the second, because in Emacs Lisp lambda forms are self-evaluating. That is, '(lambda (...) ...)
generally acts the same as (lambda (...) ...)
.
But what does the backquote (`
), instead of quote ('
), do?
Inside a backquoted expression, a comma (,
) means replace the next expression by its value, that is, evaluate it. So this:
`(lambda () ,x)
means create and return a list whose first element is the symbol lambda
(that's not evaluated), whose second element is ()
(that's not evaluated), and whose third element is the value of variable x
. It's equivalent to evaluating this code, which uses function list
:
(list 'lambda '() x)
That's what you want: replace x
by its current value (in this case, its value inside the function foo
, that is, the value of foo
's argument).
But this:
'(lambda () x)
(and likewise, because a lambda form is self-evaluating, (lambda () x)
) returns this list: (lambda () x)
. And when that's evaluated using dynamic scoping (the default scoping regime in Emacs Lisp), x
is unbound - it has no value. So a void-variable error is raised.