#lang racket
は熱心な言語ですが、それは、以前の世代が、それはまだR5RS互換delay
とforce
を持っている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
の実装はそうコアがわずかに異なる表面言語と同じであるかもしれないdelay
とforce
で飾るマクロを持っていることであろう。熱心な言語で怠惰な評価を使用するのが簡単だった場合は、怠惰な言語を使用することはできません。
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
関数の引数を変更せずにこれを行う方法はありますか?議論の中では、ちょうど(/ 1 0)の代わりに(遅延(/ 1 0))になった。 – Chubbles
@Chubblesおそらく、テストと呼ばれるマクロを作成し、引数を遅らせることができます。'#lang racket'評価モデルの熱意を回避する必要がありますので、努力が必要です。 '#lang lazy'を使用するとそうなりません。 – Sylwester
@Chubblesマクロの例を追加しました。 – Sylwester