この回答は、@Daimrodの正解の最初の部分の背後にある詳細を示しています。
あなたの質問は、なぜこれが機能するのかということです。
(defun foo (x) `(lambda () ,x)) (message (string (funcall (foo 66))))
これは機能しません:
(defun foo (x) '(lambda () x)) (message (string (funcall (foo 66))))
'
まず、 EmacsではLispラムダ形式は自己評価型であるため、2番目の引用符( )は不要です。つまり、'(lambda (...) ...)
通常はと同じように動作し(lambda (...) ...)
ます。
しかし、quote( )`
の代わりにbackquote()は何をしますか?'
バッククォートされた式の中で、コンマ(,
)は、次の式をその値で置き換える、つまり評価することを意味します。したがって、この:
`(lambda () ,x)
lambda
は、最初の要素がシンボル(評価されていない)、2番目の要素が()
(評価されていない)、3番目の要素が変数の値であるリストを作成して返すことを意味しますx
。これは、関数を使用するこのコードを評価することと同じですlist
。
(list 'lambda '() x)
それがあなたが望むものです:現在の値(この場合、関数内の値、つまり's引数の値)に置き換えます。 x
foo
foo
でも、これ:
'(lambda () x)
(同様に、ラムダ形式は自己評価であるため、(lambda () x)
)は次のリストを返します(lambda () x)
。そして、それが動的スコープ(Emacs Lispのデフォルトのスコープレジーム)を使用して評価された場合、x
バインドされていません-それは価値がありません。そのため、void-variableエラーが発生します。