2017-11-21 19 views
1

私は#langラケット内に滞在しています。 。 私が評価されてから、関数の引数を遅らせる方法を把握しようとしています - 私は、渡される引数を変更することはできません 例えば、私が渡したいと言うが、このような何かを:ラケットで関数の引数を遅延/遅延評価するにはどうすればよいですか?

(define (a e) 6)

それから私は、私は、この引数の評価を遅らせることができますどのようにこの引数

(a (/ 1 0))

と呼びたいですか?

私は(関数A内)のようなものをやってみました:

(define (a e) (define E (lambda() e)) 6)

しかし、これはまだ最初の引数を評価します。何かアドバイス?

答えて

1

#lang racketは熱心な言語ですが、それは、以前の世代が、それはまだR5RS互換delayforceを持っているR5RSスキームだったのですとおり

あなたができる特殊な形式なし
(define (test delayed-e) 6) 
(test (delay (/ 1 0))) 
; ==> 6 

(test (thunk (/ 1 0))) 
; ==> 6 

;; the same as 
(test (lambda() (/ 1 0))) 
; ==> 6 

言語を評価する前に値をラップする必要があるため、関数を呼び出すときに両方とも実行する必要があることに注意してください。 #lang lazyのような怠惰な言語では、コードを素朴に書くことができ、正しいことができます。

#lang lazy 

(define (test e) 6) 
(test (/ 1 0)) 
; ==> 6 

#lang lazyの実装はそうコアがわずかに異なる表面言語と同じであるかもしれないdelayforceで飾るマクロを持っていることであろう。熱心な言語で怠惰な評価を使用するのが簡単だった場合は、怠惰な言語を使用することはできません。

EDIT

マクロは、実際のコード上での計算を行うための方法です。したがって、あなたの代わりにマクロあなたの関数を作った場合、あなたはそれはあなたが好きなものは何でもに変身可能性があり:

(define-syntax test 
    (syntax-rules() 
    ((_ ignored-edpression) 6))) 

(test (/ 1 0)) 
; ==> 6 

ない、これは6でコードを置き換えることを知っておくことが重要です。代わりに、それはラップさせることができます:

(define-syntax define-lazy 
    (syntax-rules() 
    ((_ (name args ...) body ...) 
    (begin 
     (define (impl args ...) 
     body ...) 
     (define-syntax name 
     (syntax-rules() 
      ((_ margs (... ...)) (impl (delay margs) (... ...))))))))) 

(define-lazy (test e) 6) 
(test (/ 1 0)) 
; ==> 6 

あなたはこれがそれに(test (/1 0))を拡張するものを見れば最初の例のようになります。怠惰な言語とは異なり、forceには明示的に本体の引数が必要です。

(define-lazy (my-if p c a) 
    (if (force p) 
     (force c) 
     (force a))) 

(my-if (< 3 4) 10 (/ 1 0)) 
; ==> 10 
+0

関数の引数を変更せずにこれを行う方法はありますか?議論の中では、ちょうど(/ 1 0)の代わりに(遅延(/ 1 0))になった。 – Chubbles

+0

@Chubblesおそらく、テストと呼ばれるマクロを作成し、引数を遅らせることができます。'#lang racket'評価モデルの熱意を回避する必要がありますので、努力が必要です。 '#lang lazy'を使用するとそうなりません。 – Sylwester

+0

@Chubblesマクロの例を追加しました。 – Sylwester