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

EQ? and procedures, numbers, etc



    Date: Thursday, 21 Nov 85 13:36:39 PST
    From: Will Clinger <willc%tekchips@tektronix.CSNET>

    RRRS says that (EQ? x x) is always true, but it would be better if the value
    returned by EQ? were undefined when applied to procedure values and numbers.

I strongly disagree.

    The current wording of RRRS forces a formal semantics of Scheme to associate
    locations with procedure values and numbers.  These locations have no
    purpose other than to make the semantics of EQ? work as in RRRS, and they
    make the semantics much uglier. The ugliness of the semantics results in 
    more complex and less effective optimizing compilers.

I have yet to see a convincing example of this claim. Note, however, that I consider
object identity to be one of the most indispensible things about symbolic processing
and would not be likely to be willing to give up the only function which predicates
such identity regardless of whether such an example could be constructed. However, 
for now perhaps you could just enumerate some of the troublesome cases for me to respond
to more specifically.

    I thought that it would be a cleaner semantics if (EQ? x x) always returned
    true, but I was wrong.  It is actually a cleaner semantics if the value of
    EQ? is unspecified when both its arguments are procedures and when both its
    arguments are numbers.  When strings are immutable (as in the essential
    subset of Scheme) EQ? should be unspecified when both its arguments are
    strings.  Similarly EQ? should be unspecified when both its arguments are
    characters (unless we want to insist that either (1) characters are
    represented uniquely (e.g. immediates) or (2) EQ? does something
    complicated).

I bet it makes things easier to be able to ignore this distinction. I don't know
if programming ease and code size are always the same as cleanliness. They are
clearly related. It's possible that even O(size) is proportional to O(clean), 
but I doubt that size is proportional to clean. Eg, consider:

 (DEFINE SUCCESSOR (X) (+ X 1))

 (DEFINE SUCCESSOR (X)
   (UNLESS (NUMBERP X) (ERROR "Don't know the successor of ~S" X))
   (+ X 1))

Certainly the first program is smaller. It is probably simpler to write.
It is not be simpler to use and may be harder to use. Whether it is cleaner
seems to me to be in a gray area.

I cite as precedent the case of CALL-WITH-CURRENT-CONTINUATION. Everyone seemed to
agree that it was easier to compile/optimize code which doesn't allow returning 
these upward. The argument for pushing it through was not that it made the 
implementation simpler, since in fact it complicated it. It was instead the fact
that it was (a) at least possible to implement and (b) much simpler to some write 
programs when this feature was available. It seems to me that the situation is
similar for EQ? -- I do not want to give up this feature. You (the compiler writer)
have to solve this problem only once. I (the programmer) will have to solve it
repeatedly if you do not solve it once for me.