Both are recursive syntactically, but both generate iterative computational processes. In the first function:
(define (add-numbers x y)
(if (zero? y)
x
(add-numbers (add-one x) (sub-one y))))
Then, if y
is not zero, what happens is that the thing needs to evaluate (add-numbers (add-one x) (sub-one y))
, and to do this it needs to call (add-one x)
and (add-one y)
, and then call add-numbers
on the two results, with the result of the whole function being whatever this call to add-numbers
returns. The important thing is that the call to add-numbers
is the very last thing that happens. There's no need to return back to the point when that function call was made, as there's nothing more to do except return the calculated value. This means the process is iterative.
In the second version:
(define (add-numbers2 x y)
(if (zero? y)
x
(add-numbers2 (+ x 1) (- y 1))))
Well, the easy way to see that this is the same is to realize that +
and -
are just functions, so this is exactly the same thing! The only difference is that +
and -
happen to be functions defined by the implementation, rather than by you.
Here is a version which really describes a recursive computational process:
(define (add-numbers3 x y)
(if (zero? y)
x
(+ 1 (add-numbers3 x (- y 1)))))
In this version, if y
is not zero then the function has to call itself on x
and the result of subtracting 1 from y
... and then, once it's done that, it still needs to add 1 to the result of that call. So it needs to keep a memory that there is this pending operation of adding 1, and then actually do that addition when it returns from that function call. It's perhaps easier to see this using your original functions:
(define (add-numbers4 x y)
(if (zero? y)
x
(add-one (add-numbers4 x (sub-one y)))))
Now you can clearly see that when the recursive call to add-numbers4
returns there is still more work to do.