tighten the rules about special forms
here be undecidable dragons
git: commit
Special forms are syntactic structures of the language, that evaluate differently than the general application rule (i.e.: resolve the function, evaluate the arguments, apply). And I certainly got them and evapply wrong, at least previously. This commit fixes the behavior. Or at least I think so.
Internally I use evapply
to evaluate both regular applications and
special forms. One important difference of special forms is that they
evaluate on pure syntactic structure: when evapply
observes
(quote A)
, it passes the list (A)
to the handler of quote
special
form, but when it sees (myfun A)
, it resolves myfun
and gets the
value from the previously bound name A
.
But what happens if myfun
itself is bound to a special form as in
(let ((myfun quote) (A 314)) (myfun A))
?
I can first resolve myfun
to quote
, and decide to not evaluate A
for the special form, then expression reduces to A
.
Or I can decide that syntactically myfun
is not a special form, and
reduce myfun A
to quote 314
, and then further reduce it to 314
.
I find the second option confusing, because biding symbol quote
to
myfun
changed the semantics of the expression. But the first option is
also very problematic, for a different reason, explained below.
Since lambdas are values in the language, I must take care to capture
all the free variables in a lambda definition when I construct it.
Furthermore, I need to take the capture decisions without evaluating
the lambda, i.e. based on its purely syntactic structure. Now imagine
the following function: (lambda (myfun) (myfun A))
.
The problem is: I cannot tell whether to capture A
until I start
evaluating an application of this lambda, because only then would I know
whether myfun
is a special form (e.g. quote
) and the answer is NO,
or whether it is a regular function and the answer is YES.
The only reasonable conclusion I draw from all these contradictions is that special forms are, ahem, special, and must not be used as values. In particular, the following expressions should be illegal in the language:
(let ((myfun quote)) ())
(((lambda () quote)) A)
This then means that the only way to use a special form is by using its
true name at the beginning of an S-expression (cond ...
, (let ...
,
and we can always decide based on syntax whether something is a special
form or not.