I am trying to solve the last part of question 4.4 of the Structure and Interpretation of computer programming; the task is to implement or as a syntactic transformation. Only elementary syntactic forms are defined; quote, if, begin, cond, define, apply and lambda.
(or a b ... c) is equal to the first true value or false if the value is not true.
The way I want to approach it is to convert, for example (or bc) to
(if aa (if bb (if cc false)))
the problem is that a, b and c will be evaluated twice, which may give incorrect results if any of them had side effects. So I want something like let
(let ((syma a)) (if syma syma (let ((symb b)) (if symb symb (let ((symc c)) (if (symc symc false)) )) )) )
and this, in turn, can be implemented through lambda, as in exercise 4.6. Now the problem is the definition of syma, symb, and symc; if, for example, the expression b contains a reference to the syma variable, then let will destroy the binding. So we must have that syma is not a character in b or c.
Now we are trapped; the only way I can see from this hole is to have characters that cannot be in any expression passed to eval. (This includes characters that could be conveyed by other syntax conversions).
However, since I do not have direct access to the environment in the expression, I am not sure if there is a reasonable way to create such characters; I think Common Lisp has a gensym function for this purpose (which would mean a sticking state in the metacircular interpreter that would jeopardize any simultaneous use).
Am I missing something? Is there a way to implement or without using gensym? I know that Scheme has its own gigabit macrosystem, but I have not watched how it works, and I'm not sure if this worked out under it.