2017-03-19 16 views
0

私の質問はかなり単純です(誤解を招くほど)。 Common LispではCommon Lisp EVAL関数の見積もり

、私は次のコマンドを実行したとき、私は対応する結果を得る:一方で、私は少し異なる何かを得る、次のコマンドを実行している場合

(eval '''boo) => 'boo 

を。

(eval (eval '''boo)) => boo 

私の質問はこれです:最初のコマンドのevalは、可変シンボルから2重引用符「オフ削る」と出力の1つのマークでそれを離れた場合、どのように2つの入れ子eval機能を取ることは可能です合計3つの引用符をオフにしますか?

これはエラーで以下の結果ため、特に混乱して:

(eval 'boing) => ERROR. BOING is unbound. 

答えて

3

eval関数です。その引数は、evalが適用される前に評価されます。だからこそ、evalは2つの引用符を削り取っているようです。 1つは関数アプリケーションの暗黙の評価によって除去され、もう1つはアプリケーション自体evalによって除去されます。

(eval (eval '''boo))を呼び出すと、から返される値'booに外側evalが適用されます。等価は(eval ''boo)です。

を試すと、evalが適用される前に引数が評価されるため、evalboingを評価しようとして間違っています。 evalを適用する前に、その引数を評価しませんevalのマクロバージョンと

コントラストこの...

? (defmacro meval (form) `(eval ',form))   
MEVAL 
? (meval 'foo) 
FOO 
? (meval '''foo) 
''FOO 
7

'boo(quote boo)の略称です。コードでは、quoteは、それが何であれそれ以上のものを評価する特別な形式です。従ってboo。この値がデータの周りを渡され、コードはなくなったが、シンボルfooを作成するにはquoteが必要です。

'''booは、(quote (quote (quote boo)))の略語です。それを評価するとき、まったく同じようになり、それは(quote (quote boo))になります。第2の要素が2つの要素のリストである2つの要素を持つリスト。

evalは最初に引数を評価する関数なので、関数が行うと思われる結果を評価します。従って、(quote (quote foo))は、最初の評価の後に(quote foo)となり、evalは、シンボルfooを残して2番目のものを取り去ります。

fooの場合は、グローバル名前空間の変数fooでバインドされた値を取得するはずです。したがって:

(defparameter *test* 5) 
(eval '*test*) 
; ==> 5 

引数が評価後*test*なり(quote *test*)ですので。evalはシンボルを参照し、結果として値5をフェッチします。 *test*が縛られていないと、あなたはエラーを受け取ります。

(defparameter *test-symbol* '*test) 
(eval *test-symbol*) 

ここに同じです。関数*test-symbol*はシンボル*test*と評価されているため、evalが表示され、値5が取得されます。

(defparameter *result* (eval '''foo)) 
*result* 
; ==> (quote foo) but often the REPL shows 'foo 
(consp *result*) 
; ==> t 
(length *result*) 
; ==> 2 
(car *result*) 
; ==> quote 
(cadr *result*) 
; ==> foo 

時々、私は初心者が'('(a) '(b))のようなことをするのを見ます。これは、あなたがデータとしてリスト((quote (a)) (quote (b)))で終わると評価されたときのような間違いであり、まれに意図されています。 list引数のような機能を使用する場合は評価され、あなたが適切に引用する必要があります:

(list '(a) *result* '(b)) 
; ==> ((a) (quote foo) (b)) 
4

最初の質問:

Evaluating (eval '''boo) 

    Evaluating '''boo 
    Result: ''boo 

    Calling Function EVAL with ''boo 
    Function EVAL returns 'boo 

Result: 'boo 

2番目の質問:

Evaluating (eval (eval '''boo)) 

    Evaluating (eval '''boo) 

     Evaluating '''boo 
     Result: ''boo 

     Calling EVAL with ''boo 
     Function EVAL returns 'boo 

    Calling Function EVAL with 'boo 
    Function EVAL returns boo 

Result: boo 
関連する問題