[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Problem with #T in T2.8



    Date: 19 Nov 85 12:31:29 EST (Tue)
    From: <ram%YALE-RING at YALE.ARPA>

    #F evaluates to () but #T breaks (which is why I had to replace
    these with (FALSE) and (TRUE) respectively in the #! syntax for the
    SCHEME emulator.)  Actually, #!FALSE and #!NULL work the way you
    have them, but #!TRUE doesn't...

    Incidently, why did you choose to use #T and #F (which looks like
    yet more syntax to me) as the standard way to get to the primitive
    true and false values rather than (TRUE) and (FALSE) (which to me
    look cleaner)?

[I'll forward my answer to T-Discussion since I think other people have
been confused by this.]

In T, #T and #F are external syntax for true and false *objects*, not
*expressions*.  #T and #F are not themselves supposed to be evaluable
expressions.  Evaluable expressions which give true and false values are
T and NIL, or, if you prefer, (TRUE) and (FALSE).

T    =>  any true value (e.g., T or #T or 0)
NIL  =>  any false value (there's only one, namely #F)
'#T  =>  #T
'#F  =>  #F
#T   =>  syntax error
#F   =>  syntax error

The only legitimate place for #T and #F to appear in T programs is
within quoted structure, e.g. '#T or '(A #T #F B), or occasionally in
other non-evaluated positions (#F can appear in bound variable lists to
indicate an ignored position - yes, I know this is a crock).

Scheme has analogous external syntax for true and false objects (#!TRUE
and #!FALSE), but it has the additional feature that there are
expressions written the same way (#!TRUE and #!FALSE) which evaluate to
the corresponding objects.  These expressions are analogous to the ones
for number, character, and string constants.  That these are
syntactically legal is only a convenience, since one could always write
'17, '#!TRUE, and so on.

The fact that the expression #F is a legal expression in T 2.8 is just
residual Lisp compatibility, like (car '()) => (), which might go away
or generate a warning message in future versions.  (I don't think (car
'()) => () will go away, since it's too hard to convert programs to
not depend on this.)

In the long run I think the right thing to do is to somehow make the way
that boolean and other objects evaluate (macroexpand) be a property of
the syntax table, and set the expansion of booleans differently in
scheme's syntax table.  I think I hacked some crude approximation to
this when I originally got the scheme emulator running.  You should
probably just clobber SELF-EVALUATING? (see EVAL.T) and the
corresponding procedure within TC to accept #T and #F as self-evaluating
objects.

Easier than this would be to make T behave the same as Scheme with
respect to #T and #F, but this bothers me for two reasons: (a) it seems
like an arbitrary additional feature which reduces redundancy and throws
away chances for error checking (it's bad enough that numbers
self-evaluate; where does one draw the line?), and (b) I think the empty
combination () should be a syntax error, and #F is unfortunately
indistinguishable from () (since LOAD calls the same parser that READ
does), so #F as an expression should be a syntax error, so for
consistency #T should be a syntax error.  (It would have helped if we
had distinguished #F from () back in 1981 when we had a chance.)

Jonathan