Consider the two cases:
(1) a
is equal to b
.
Then foo(i)
and bar(i)
must be invoked in this order. The code does so. Since the return value of bar(i)
is the same as that of foo(i)
, it is sufficient to call bar
in a tail call and let it's result return to the caller of foobar
.
(2) a
is not equal to b
.
Then foo(i)
and bar(i)
must be invoked in this order. The code does so. Since the return value of bar(i)
is different from that of foo(i)
, b
, i.e., the return value of bar(i)
must be returned to the caller. This can be achieved by a tail call of bar
and let it's result return to the caller of foobar
.
The two cases do exactly the same thing.