soegaard の答えは正しいです。これは伝統的な展開です。しかし、drscheme はスマートです。
次のコードは、実行時に同等であることがわかりました。
元のソース:
(define ((substitute lv value) e)
(cond [(LogicVar? e)
(type-case LogicVar e
[lv-any (id) (if (symbol=? id (lv-any-id lv))
value
e)]
[lv-cons (f r)
(lv-cons ((substitute lv value) f)
((substitute lv value) r))])]
[(cons? e)
(cons ((substitute lv value) (car e))
((substitute lv value) (cdr e)))]
[else e]))
最適化の試み:
(define (substitute lv value)
(local ([define inner
(lambda (e)
(cond [(LogicVar? e)
(type-case LogicVar e
[lv-any (id) (if (symbol=? id (lv-any-id lv))
value
e)]
[lv-cons (f r)
(lv-cons (inner f)
(inner r))])]
[(cons? e)
(cons (inner (car e))
(inner (cdr e)))]
[else e]))])
inner))
この関数を頻繁に (1 回だけでなく複数回) 使用するコードは、両方のバージョンで 1800 ミリ秒で実行されます。さらに興味深いことに、このバージョン (何が起こっているかを視覚化したもの):
(define (substitute lv value)
(local ([define inner
(lambda (e)
(cond [(LogicVar? e)
(type-case LogicVar e
[lv-any (id) (if (symbol=? id (lv-any-id lv))
value
e)]
[lv-cons (f r)
(lv-cons ((substitute lv value) f)
((substitute lv value) r))])]
[(cons? e)
(cons ((substitute lv value) (car e))
((substitute lv value) (cdr e)))]
[else e]))])
inner))
2000 ミリ秒で実行されます。したがって、substitute 内での replace の呼び出しがそれぞれラムダを作成していた場合、確実に速度が低下しますが、ショートカット表記の場合はそうではないようです。