2016-10-19 8 views
0

大学のプロジェクトでは、私たちは学習スキームに取り組んでいますが、私たちは知識がほとんどない難しい課題に投げかけられています。私たちは "let"、 "cond"、 "and"などのような特定の機能を与えられ、マクロを追加するように求められました。スキームにマクロを追加する

したがって、コメントはあります。 私は「指揮一部をやってみましたし、この

((equal? (car e) 'cond) 
      (env (cdr e) env)) 

を得たが、それは正しい(スキームの非常に少ない知識)だ場合、私は考えています。これを理解する上で助けとなることは、非常に高く評価されます。ありがとう。

答えて

1

これは本当にマクロではなく、追加する特別なフォームです。 letが匿名関数呼び出しの構文砂糖であることがわかっている場合。例えば。あなたが新しいを導入する

(let ((bindings (cadr e)) 
     (body (cddr e))) 
    (eval_ `((lambda ,(map car bindings) ,@body) ,@(map cadr bindings)))) 

今本当のマクロ:

((lambda (a b) body ...) expr1 expr2) 

は、あなたがこのようなlet作品を軌道に乗るために:あなたは、あなたが変更した場合、既に評価者及び評価に

(let ((a expr1) (b expr2)) body ...) 

がサポートされています%closureのように、演算子として見つけたときにはシンボルを評価せずにバインドし、それが関数であるかのように評価子を実行してから結果はです。 condletを実装する代わりに、すでにサポートしているものに書き換える方法に関数を追加するだけです。あなたはこのようなletを作ることができるこのように:

((lambda (let) 
    (let ((a expr1) (b expr2)) 
    (cons a b))) 
    (~ (bindings . body) `((lambda ,(map car bindings) ,@body) ,@(map cadr bindings)))) 

それはあなたが準クォートとmapを前提としていますが、それは簡単に、より冗長なコードでこれらせずに実施することができます。 は、λのマクロバージョンになるようにランダムに選択されています。それが評価されると、おそらく%mclosure構造になり、その引数を評価しないように特別に扱う必要がありますが、結果を評価してください。それ以降は、ブート環境にあらかじめ定義された%mclosureを持つことによって特別なフォームをサポートできます。

関連する問題