Görünüşe göre herhangi bir özyinelemeli işlemi kuyruk özyinelemeye dönüştürmek için genel bir yol buldum :
- Ek bir "sonuç" parametresi ile bir yardımcı alt prosedür tanımlayın.
- Prosedürün dönüş değerine uygulanacakları bu parametreye uygulayın.
- Başlamak için bu yardımcı prosedürü çağırın. "Sonuç" parametresinin başlangıç değeri, özyinelemeli işlemin çıkış noktası değeridir, böylece elde edilen yinelemeli işlem özyinelemeli işlemin küçülmeye başladığı yerden başlar.
Örneğin, dönüştürülecek orijinal özyinelemeli yordam aşağıdadır ( SICP alıştırması 1.17 ):
(define (fast-multiply a b)
(define (double num)
(* num 2))
(define (half num)
(/ num 2))
(cond ((= b 0) 0)
((even? b) (double (fast-multiply a (half b))))
(else (+ (fast-multiply a (- b 1)) a))))
İşte dönüştürülmüş, kuyruk özyinelemeli prosedür ( SICP alıştırması 1.18 ):
(define (fast-multiply a b)
(define (double n)
(* n 2))
(define (half n)
(/ n 2))
(define (multi-iter a b product)
(cond ((= b 0) product)
((even? b) (multi-iter a (half b) (double product)))
(else (multi-iter a (- b 1) (+ product a)))))
(multi-iter a b 0))
Birisi bunu ispatlayabilir veya çürütebilir mi?
b
2'nin gücü olmayı seçmek , başlangıçta product
0'a ayarlamanın tam olarak doğru olmadığını gösterir ; ancak 1 olarak değiştirmek b
garip olduğunda işe yaramaz . Belki 2 farklı akümülatör parametresine ihtiyacınız var?