6

これは簡単な質問のように思えます。おそらく、答えを見つけるための検索を見つけるのが難しいほど単純です。Scheme (具体的には、それが違いを生む場合は Guile の実装) では、引用されたものをどのように評価しますか?

これが私がやろうとしていることです。

基本的に、定義した関数が特定の順序で引数を評価されるようにする必要があります。これは、1 つの引数を評価することによって引き起こされる副作用が、他の引数の評価中に依存するためです。ただし、Scheme では、引数は任意の順序で評価できると述べているため、引数を引用符で囲み、必要な順序で手動で評価することにより、手動で強制的に評価したいと考えています。

「eval」は私がやりたいことをするはずですが、2つの問題があります:

  1. その使用はお勧めできないので、ここでやりたいことを達成するためのより良い方法があるはずだと感じています.
  2. Scheme では、eval は環境である 2 番目のパラメータを取るようです。これは私を混乱させます。ステートメントが表示されるのと同じ環境で評価したいのに、なぜ2番目のパラメーターが必要なのですか? これは可能ですか?私は eval で少し遊んでみましたが、実装によっては異なるパラメーターが必要なようです (たとえば、mit-scheme は (interaction-environment) が何であるかさえ知りません!!!)

ラムダを構築するなど、他のトリックを試しました:

(list 'lambda '() '(car (b c)))

しかし、プロシージャを生成するには、これを評価する必要があるようです。私も試しました:

(list lambda '() '(car (b c)))

しかし、これはどちらも機能しない「プリミティブ組み込みマクロ」を返します。

編集:評価の順序を制御するためにマクロが機能するように見えます: (defmacro test1 (ab) `(begin ,b ,a))

4

3 に答える 3

3

リスト構造 (Scheme プログラム テキストを表す引用符付きのネストされたリスト) を評価する必要がある場合は、 を使用する必要がありますeval。Scheme では、現在の環境であっても、2 番目の引数として環境を渡す必要があります。

(eval '(+ x y) (interaction-environment))

begin特定の順序で計算を行う必要がある場合は、 、let、または関数本体のみを使用して、副作用の評価順序を強制できます。これらは一連の評価を定義します。

(let ((x 42))
  ; eval with effects #1
  (display x)
  ; eval with effects #2
  (display (+ x 1)))

編集:式を未評価のまま渡し、特定の順序で評価を強制できる、パラメータ化されたコード ブロックが必要な場合は、次の手法のいずれかを使用できます。

  • マクロ(すでに述べたように、完全を期すために):

    > (defmacro test1 (a b) `(begin ,b ,a))
    > (test1 (display 2) (display 3)
    32
    
  • 遅延計算 (遅延評価のためのSchemeの特別な構文):

    > (define (test1 a b) (begin (force b) (force a)))
    > (test1 (delay (display 2)) (delay (display 3)))
    32
    
  • 通常のラムダの抽象化と適用

    > (define (test1 a b) (begin (b) (a)))
    > (test1 (lambda () (display 2)) (lambda () (display 3)))
    32
    
于 2011-07-09T00:02:34.873 に答える
0

あなたはラムダを渡すことで正しい軌道に乗っていました。あなたが持っている場合

(define (f x y z) ...)

...次に、次のように呼び出すことができます。

(f
  (lambda () a)
  (lambda () b)
  (lambda () c))

fこれは、すべての引数 ( abc) を未評価の形式で呼び出します。内部fでは、それらを評価する順序を選択する完全な権限があります。唯一の違いは、 、 、およびを明示的に呼び出し(x)、orのようなステートメント内でそれらの値を取得する必要があることです。これにより、副作用が 1 回だけ発生するようになります。(y)(z)definelet

ここではマクロはまったく必要ありません。ところで、どこにでもたくさんのラムダを使用することを心配しないでください。それらは非常に安価です。

于 2014-01-28T04:46:21.950 に答える