2011-01-26 5 views
1
(defun make-it-5 (num) 
    (setq num 5)) 
(setq a 0) 
(make-it-5 a) 
;; now a is still 0, not 5. 

上記のコードでは、(setq a 5)も(setq 0 5)も起こっていないようです。 (setq a 5)が発生した場合、aは5に変更されていますが、aはまだ0です。(setq 0 5)が発生した場合、Lispエラーが発生しています。何が起こるのですか?それが私の質問です。その名の通りメイクそれ-5作品を作る方法をグーグルと不思議でここに来た人、あなたのいくつかのためにdefqでパラメータ変数をsetqするとどうなりますか? (Emacs)

一つの方法は、

(defmacro make-it-7 (num) ; defmacro instead of defun 
    `(setq ,num 7)) 
(setq a 0) 
(make-it-7 a) 
;; now a is 7. 

別で、お勧めです:

(defun make-it-plus (num-var) 
    (set num-var (+ 1 (symbol-value num-var))) ; `set' instead of `setq' 
) 
(setq a 0) 
(make-it-plus 'a) ; 'a instead of a 
;; now a is 1. 
+0

質問は少し混乱しています。両方を提供する2つの選択肢は、lisp(emacs-lisp)のより詳細な理解を必要とします。私はあなたがそれらの仕事の仕方を理解していないと推測しています... –

答えて

7

短い答えは、make-it-5機能にローカルなバインディングである(setq num 5)changes the binding fornumです。

次のようになります。 evaluationの概念に精通していることを確認することをお勧めします。

(make-it-5 a)が評価されると、インタプリタは式の最初の要素で関数を探します。この場合、最初の要素はシンボル(make-it-5 - つまり、named functionを意味します)であるため、シンボルのfunction cellが表示されます。注:このルックアップはそれ自身を繰り返すことができます。Symbol Function Indirectionを参照してください。

残りの式の要素が評価され、値が見つけられます。この場合、ただ1つのシンボル(a)があるので、インタープリタはthe contents of its value cellを返します。これは0です。

インタープリタは、関数を引数のリストに適用します。これには、local bindings between its arguments to the values passed inが含まれます。この場合、記号numと値0の間のlocal bindingが作成されます。次に、関数の本体がその環境で評価されます。

本文は、setqの「呼び出し」である単一の式です。 setqspecial formであり、最初の引数は評価されませんが、シンボルを参照して、make-it-5内に作成されたバインディングであるmost local existing bindingを設定するため、「コール」を引用符で囲みます。

したがって、シンボルnumのバインディングは、make-it-5のローカルに変更されています。

関連する問題