The Third Commandment of The Little Schemer states:
When building a list, describe the first typical element, and then cons it onto the natural recursion.
What is the exact definition of "natural recursion"? The reason why I am asking is because I am taking a class on programming language principles by Daniel Friedman and the following code is not considered "naturally recursive":
(define (plus x y)
(if (zero? y) x
(plus (add1 x) (sub1 y))))
However, the following code is considered "naturally recursive":
(define (plus x y)
(if (zero? y) x
(add1 (plus x (sub1 y)))))
I prefer the "unnaturally recursive" code because it is tail recursive. However, such code is considered anathema. When I asked as to why we shouldn't write the function in tail recursive form then the associate instructor simply replied, "You don't mess with the natural recursion."
What's the advantage of writing the function in the "naturally recursive" form?
h(S(y))
) would be defined byg(y,h(y))
. When treating lists as a lists, the counterpart would be something more akin toh(cons(x,y)) = g(x,h(y))
. That's not quite precise, but it may have been some influence. – Jewsreverse
function is more efficient when written using an accumulator rather that when written usingappend
, which is the naturally recursive style of writing programs. I think it's a teaching tool. =) – Electivereverse(x::xs) == append(reverse(xs),[x])
, we get a very easy inductive proof, as long as we know that append works. We can see immediately that x is the last element, etc. The accumulator version is more efficient, but it might be a little bit harder (at least at an introductory level) to prove that it's correct. I'm entirely in favor of writing more efficient code; I'm just speculating on why the authors called... – Jews