誰か教えてくださいこれはラケット(v5.1.1)のバグです、教えてくださいRacket v5.1.1のスコープバグ?
それは範囲の問題となる継ぎ目です。
(コードと以下の出力を参照)
例-1からのリターンは、それがなければならず、それは、例えば、2及び実施例3で しない限り、Xをインクリメント取得していない されていることを示しています。
関数example-2は、復帰命令をdoitから削除したexample-1 の単なるコピーに過ぎません。
関数の例-3は、(あなたが見ることができるように)それがあるとして、Xを示し、同様のコピー であるが、それ自体では何も変わりません 追加のパラメータを持っていますが、私はテストするときには、 のcond文で値です増加した。
さらに、私がexample-1 から何も返さず、今返されているものを印刷すると、 がインクリメントされているxが表示されます。
(define (example-1 lst)
(letrec([x 0]
[doit (lambda()
(reverse
(foldl
(lambda (v store)
(set! x (add1 x))
(cons v store))
'()
lst)))])
(let*([results (doit)])
(list x results)
)))
(define (example-2 lst)
(letrec([x 0]
[doit (lambda()
(foldl
(lambda (v store)
(set! x (add1 x))
(cons v store))
'()
lst))])
(let*([results (doit)])
(list x results))))
(define (example-3 lst id)
(letrec([x 0]
[doit (lambda()
(reverse
(foldl
(lambda (v store)
(set! x (add1 x))
(cons v store))
'()
lst)))])
(let*([results (doit)])
(cond [(= 1 id) 'junk])
(list x results)
)))
(printf "example-1 : ~a~n" (example-1 '(a b c)))
(printf "example-2 : ~a~n" (example-2 '(a b c)))
(printf "example-3 : ~a~n" (example-3 '(a b c) 1))
出力:
example-1 : (0 (a b c))
example-2 : (3 (c b a))
example-3 : (3 (a b c))
これはスコープの問題ではなく、JITの問題です。この問題は、 'reverse'が使用されたときにのみ発生し、無駄な' cond'が取り出された場合にのみ発生します。過度に積極的な最適化が行われていたようだ。 –
dlm:これで修正されました。 –