The challenge with (if (null? x) (quote ()) (cdr x))
is that it really doesn't do anything. eg. if I put that in an R6RS-program and run it nothing happens. Thus I suggest we write it:
(display (if (null? x) (quote ()) (cdr x)))
And assume this is the whole program except that x
is defined. Now if
needs to know the value of (null? x)
to determine if it is the consequent or the alternative. eg.
(null?& x
continuation)
The continuation needs to determine if it's true or not and do one of two continuations:
(null?& x
(lambda (xn)
(if& xn
continuation-consequent
continuation-alternative)))
If xn
is true the continuation should display '()
, but if it is not then it shoudl display the cdr
of x
:
(null?& x
(lambda (xn) ; 201
(if& xn
(lambda () ; 202
(display& '() halt)
(lambda () ; 203
(cdr& x (lambda (cdrx) ; 204
(display& cdrx halt)))))))
halt
stops the program. Now lets imagine we translate this to Algol eg. JS. I'll switch the order so that continuation always is the first argument. All procedures just gets an numeric id so the implementation language doesn't need to have procedures at all.
const undef = "BaNaNa";
const x = [1, 2, 3]; // change this
const stack = [200];
main:
while (true) {
const cont = stack.pop();
const cont2 = cont < 200 ? stack.pop() : undef;
switch (cont) {
case 1: // null?&
stack.push(stack.pop().length === 0, cont2);
break;
case 2: // display&
console.log(stack.pop());
stack.push(undef, cont2);
break;
case 3: // cdr&
stack.push(stack.pop().splice(1), cont2);
break;
case 4: // if&
const cont3 = stack.pop();
if (stack.pop()) {
stack.push(cont2);
} else {
stack.push(cont3);
}
break;
// continuations
case 200:
stack.push(x, 201, 1);
break;
case 201:
stack.push(203, 202, 4);
break;
case 202:
stack.push([], 1337, 2);
break;
case 203:
stack.push(x, 204, 3);
break;
case 204:
stack.push(1337, 2);
break;
// halt
case 1337:
break main;
}
}
Now we did miss out on user specified procedures and closure conventions, both which would have made this example slightly more complex. There is some missing type checking a proper Scheme would have done and I use arrays instead of real pairs.