Many Scheme programs rely heavily on recursion, and Scheme makes it
easy to use recursion in ways that aren't feasible in most other
languages. In particular, you can write recursive procedures
which call themselves instead of looping.

When a procedure calls itself in a way that is equivalent to iterating
a loop, Scheme automatically "optimizes" it so that it doesn't need
extra stack space. You can use recursion anywhere you could use a
loop in a conventional language. Technically, loop-like recursion is
called tail recursion, which we'll explain in detail in a
later chapter.

The basic idea is that you never have to return to a procedure if
all that procedure will do is return the same value to its caller.
For example, consider the following procedure definition:

(define (foo)
(bar)
(baz))

When foo calls baz, it is a tail call, because on return
from baz, foo will do nothing except return the returned value
to its caller. That is, the return to foo from baz
will be immediately followed by a return to whatever procedure called
foo. There's really no need to do two returns, passing
through foo on the way back. Instead, Scheme avoids saving
foo's state before the call to baz, so that baz
can return directly to foo's caller, without actually
coming back to foo.

Tail-calling allows recursion to be used for looping, because a tail
call that acts to iterates a loop doesn't save the caller's state on a
stack.

Scheme systems can implement such tail calls as a kind of GOTO that
passes arguments, without saving the state of the caller. This is not
unsafe, like language-level GOTO's, because it's only done when the
result would be the same as doing the extra returns.

Some compilers for languages such as Common Lisp and C perform a limited
form of "tail call optimization," but Scheme's treatment of tail calls,
is more general, and standardized, so you can use recursion more
freely in your programs, without fear of stack overflow if you code your
routines tail-recursively.

And of course, you can use recursion the way you would in most languages,
as well as for loops, so recursion can do both jobs. While
Scheme has conventional-looking looping constructs, they're defined in
terms of recursion.