Предположим, мы хотим реализовать следующую рекурсивную функцию на схеме:
f (n) = f (n-1) + 1 / f (n-1) [n> 0]
f (n) = 1 [n = 0]
Простой способ это сделать примерно так:
(define (f n) (if (zero? n) 1 (+ (f (- n 1)) (/ 1 (f (- n 1))))))
Но, поскольку подвыражение (f (- n 1)) повторяется, этот код не так уж и элегантен. Есть ли способ улучшить этот код, привязав имя к этому промежуточному значению?
Обратите внимание, что конструкция let здесь не может быть использована, поскольку теоретически это приводит к тому, что функция будет возвращаться навсегда. Практически это вызывает ошибку Схемы.
UPDATE
Вот мой код с let:
(define (afunc s n)
(if (> n 0)
(* .5
(let ((next (afunc s (- n 1)))
(+ next (/ s next))))
s)))
Разрывается с Плохо сформированной специальной формой: (let (... ...)) error.