many
は何を調べてみましょう。まず、あなたはそれを定義した:
(define (many n fn)
(cond
[(= n 0) true]
[else (many (sub1 n)
(local ((define k (time fn)))
k))]))
そして、それを呼び出す:
> (many 3 (add1 41))
cpu time: 0 real time: 0 gc time: 0
cpu time: 0 real time: 0 gc time: 0
cpu time: 0 real time: 0 gc time: 0
#t
>
をここで再帰的にmany
呼び出し自体たときに、すべての繰り返しで何が起こるか:many
の
(define (many 3 42)
(cond
[(= 3 0) true]
[else (many (sub1 3)
(local ((define k (time 42)))
42))]))
(define (many 2 42)
(cond
[(= 2 0) true]
[else (many (sub1 2)
(local ((define k (time 42)))
42))]))
(define (many 1 42)
(cond
[(= 1 0) true]
[else (many (sub1 1)
(local ((define k (time 42)))
42))]))
(define (many 0 42)
(cond
[(= 0 0) true]
[else (many (sub1 0)
(local ((define k (time 42)))
42))]))
あなたの定義は再帰的に自分自身を呼び出します最初の(time fn)
アプリケーションの結果値ですが、正しくはありません。なぜなら、あなたのタイミング情報を収集したいからですプロシージャのアプリケーションではなく、値(この場合は(add1 41)
の値)ではありません。
(define (many n fn)
(cond
[(= n 0) fn]
[else (many (sub1 n)
(local ((define k (time fn)))
k))]))
を、あなたは以下を得るでしょう::ちょうどmany
のあなたの定義でfn
とtrue
を代用
> (many 3 (add1 41))
cpu time: 0 real time: 0 gc time: 0
cpu time: 0 real time: 0 gc time: 0
cpu time: 0 real time: 0 gc time: 0
cpu time: 0 real time: 0 gc time: 0
42
>
あなたはすべての再帰呼び出しのfn
が42
に等しいことがわかります。これは、多くのFP言語で評価のApplicative orderが使用され、の最初の呼び出しが発生する前に(add1 41)
が評価されるために発生します。それは第二引数(fn
)だとして
したがって、私たちはに機能を確保するためにlambda
を使用する必要がありますが(が我々の場合にはサンク)の多くに渡されます。
(define (many n fn)
(time (fn))
(if (= n 0)
true
(many (sub1 n) fn)))
出力例:
> (many 3 (lambda() (fact 10000)))
cpu time: 2734 real time: 2828 gc time: 1922
cpu time: 906 real time: 953 gc time: 171
cpu time: 891 real time: 953 gc time: 204
cpu time: 938 real time: 984 gc time: 251
#t
>
あなたが(fn)
上記参照として機能(lambda() (fact 10000)
(サンク)の結果のアプリケーションを実行し、time
すでにスキームにおける機能アプリケーションは式周り()
として表現される知っていますあなたが渡したいもの(式)を正確に取得し、正しいタイミング情報を表示します。
希望に役立ちます。私が間違っているなら私を訂正してください。
あなたは関数を渡すのではなく、式の評価の結果を '()'の中に入れます。 –