これは本当にマクロではなく、追加する特別なフォームです。 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
のように、演算子として見つけたときにはシンボルを評価せずにバインドし、それが関数であるかのように評価子を実行してから結果はです。 cond
とlet
を実装する代わりに、すでにサポートしているものに書き換える方法に関数を追加するだけです。あなたはこのようなlet
を作ることができるこのように:
((lambda (let)
(let ((a expr1) (b expr2))
(cons a b)))
(~ (bindings . body) `((lambda ,(map car bindings) ,@body) ,@(map cadr bindings))))
それはあなたが準クォートとmap
を前提としていますが、それは簡単に、より冗長なコードでこれらせずに実施することができます。 は、λ
のマクロバージョンになるようにランダムに選択されています。それが評価されると、おそらく%mclosure
構造になり、その引数を評価しないように特別に扱う必要がありますが、結果を評価してください。それ以降は、ブート環境にあらかじめ定義された%mclosure
を持つことによって特別なフォームをサポートできます。