This is the Man or boy test Scheme code:
(define (A k x1 x2 x3 x4 x5)
(define (B)
(set! k (- k 1))
(A k B x1 x2 x3 x4))
(if (<= k 0)
(+ (x4) (x5))
(B)))
In order to simplify the evaluation process, I rewrite it to:
(define (A k x1 x2)
(define (B)
(set! k (+ k -1))
(A k B x1))
(if (> 1 k)
(x2)
(B)))
I can't understand why (A 2 (lambda () 1) (lambda () -1))
return 1.
Can anyone explain how the Scheme interpreter evaluates this expression step by step. If you can attach the environment diagrams, so much the better:)
The question is very subtle, and in the first moment I thought that the call would cause an infinte loop. But the real affair is the following:
Let's start calling F1 and F2 the two functions passed to A the first time, that is
So, after the first call of
(A 2 F1 F2)
,A
establishes the following environment, that we will nameE1
:The test is now false, so
A
callsB1
.B1
first decrementsk
inE1
, then calls againA
, passing 1, itself, andx1
, which isF1
. So this is the call with parameters substituted with their values:(A 1 B1 F1)
. And the new environment established by this call (E2
) is shown in the following picture:The test is still false, so
A
callsB2
, which first modifiesk
inE2
, then callsA
with 0, itself, andx1
(which now isB1
). So the call is(A 0 B2 B1)
, and the new set of environments is now:The test is now true, so
A
callx2
, which isB1
. NowB1
modifiesk
in its environment (which isE1
), and then callsA
with 0, itself, and the value ofx1
, which, inE1
, isF1
. So the call is(A 0 B1 F1)
and the environment established by this call is depicted in the next figure:And finally, after checking that the test is true,
A
callsx2
, that isF1
, which returns 1. At last!