コードにはいくつかの間違いがあります。まず、結果を格納するために a で定義されたグローバル変数は必要ありませんlet
。再帰を進めるときに答えを構築するだけで十分です。append
この場合は使用しないでください。ソリューション テンプレートに厳密に従っていればcons
、出力リストを作成するのに a で十分です。
新しいリストを再帰的に構築するためのレシピに固執する必要があります。これは、そのレシピを使用して問題を解決する方法です。おそらく、次のようにもう少し慣用的です。
(define preplist
(lambda (x y)
(cond ((> x y) ; if the exit condition is met
empty) ; then return the empty list
(else ; otherwise
(cons x ; cons the current element
(preplist (add1 x) y)))))) ; and advance the recursion
まったく異なるアプローチは、末尾再帰ソリューションを作成することです。一定量のスタックが使用されるため、これはより効率的です。上記の設計レシピには従いませんが、あなたが考えていたソリューションに多少似ていますが、これはグローバル変数を使用せず (let
反復の名前のみ)、ソリューションが蓄積されることに注意してください。パラメータとして渡されます:
(define (preplist x y)
(let loop ((i y) ; named let for iteration
(acc empty)) ; define and initialize parameters
(if (> x i) ; if exit condition is met
acc ; return accumulated value
(loop (sub1 i) ; otherwise advance recursion
(cons i acc))))) ; and add to the accumulator
もちろん、コメントで@dyooが指摘しているように、実際の設定では、range
プロシージャと基本的に同じことを行う組み込みプロシージャを使用しpreplist
ます。