1

define-syntax-ruleリストを引数として受け入れ、リスト(単一の要素の場合は引用符)をラムダの本体として受け入れるにはどうすればよいでしょうか。私は次のようなことをしたいと思います:

    >(define a (lambdarize '(x y z) '(+ x y z)))
    #<procedure>
    >(a 1 2 3)
    6
    >(define b (lambdarize '(x) 'x))
    #<procedure>
    >(b 1)
    1

と をいじってみましたが、define-syntax-ruleそれ自体はプロシージャではなくマクロのように見えるため、見つけようとして困惑しました...applylambda

evalああ...そして、それは悪質なので、使用しないソリューションが欲しいです...

アップデート

答えてくれてありがとう、ライアン...それはほとんどそれでした! =) eval の問題は、現在のスコープをキャッチするのがうまくいかないことでした...このようにして、次のようなことができます

    (let ([a 1])
        (begin
            (defmethod add ((x integer?) (y integer?)) (+ x y a))
            (add 1 2)
    )

これはevalで惨めに失敗します...これは単なる学術的な例ですが、正しさの良いテストだと思います.

4

1 に答える 1

2

を使用せずに、仮パラメーターと本体が実行時の値 (S 式) として与えられる関数を作成することはできませんeval

ただし、Greg のコメントに対する回答に基づいて、defmethodマクロを変更してこの問題を回避できます。現在のアプローチでは、変数と本体の式 (プログラム用語) を受け取り、それらを実行時の値に変換してから、それらをプログラム用語として再解釈したいと考えています。代わりに、プログラム用語をlambdaマクロ内の -expression に結合するだけで、ヘルパー関数に値として渡すことができます。

(define-syntax-rule (defmethod name ((var predicate) ...) body)
  (add-to-generic name
                  (list predicate ...)
                  (lambda (var ...) body)))

変数名を残しておきたい場合 (エラー メッセージなど)、それらを引用符で囲むこともできますが、lambda-expressionとは分けます。

(define-syntax-rule (defmethod name ((var predicate) ...) body)
  (add-to-generic name
                  (list predicate ...)
                  '(var ...)                 ;; for errors, debugging, etc
                  (lambda (var ...) body)))
于 2013-05-08T16:18:35.090 に答える