[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Changes to MEMBER, ASSOC, etc.
- To: INFO-LISPM-MIT@MIT-OZ
- Subject: Changes to MEMBER, ASSOC, etc.
- From: KMP@MIT-OZ
- Date: Sun ,19 Jun 83 20:18:00 EDT
- Mail-from: KMP created at 19-Jun-83 20:18:19
RMS failed to note in his message the following relevant points.
* The proposed definitions for MEMBER, ASSOC, etc. are compatible with all
the cases of the current ASSOC except in the case of searching for list
or string in list structure. Since Maclisp has no strings, Maclisp
compatibility is affected only in the case where people do
(MEMBER '(B C) '((A B) (B C) (C D)))
which in Maclisp used to return ((B C) (C D)) and under the proposed
definition would return NIL. On the LispM, the additional case of doing
(MEMBER "BAR" '("FOO" "BAR" "BAZ"))
which used to return ("BAR" "BAZ") would return NIL. Under the proposed
standard, this would return NIL.
* In both of the cases written above, you can simply mechanically rewrite
your code. eg,
(MEMBER '(B C) '((A B) (B C) (C D)) :TEST #'EQUAL)
or (MEMBER "BAR" '("FOO" "BAR" "BAZ") :TEST #'EQUAL)
In the cases where you've written
(MEMBER C '(#/A #/B #/C))
or (MEMBER N '(1 2 3 4))
or (MEMBER X '(1.0 2.0 3.0))
you need change nothing, you'll just find that in some implementations your
code may run a little faster.
The only thing that's in question is what the default test is.
* The reason for changing the default test (which will be by a new function
EQL, which is like EQ except it can also compare characters or numbers)
is that it will allow searches for numbers and characters (which is believed
to be the most common use of MEMBER) to be more conveniently expressed.
eg, it used to be that
(MEMQ C '(#/A #/B #/C #/D))
was guaranteed to work only on the LispM because in Maclisp numbers were not
necessarily EQ and could not be searched for in some cases by MEMQ. (It
happens to work in some cases, but not all of them). The only alternative
previously was to write
(MEMBER C '(#/A #/B #/C #/D))
which compiles inefficiently because it invokes an EQUAL test rather than
a simpler test. Similar arguments can be made about searching for flonums.
In the rarer cases of searching for strings or s-expressions, the intent
of the current proposed definition is that you'd then use the clumsier
case of (MEMBER thing list :TEST test), specifying #'EQUAL, #'STRING-EQUAL,
The :TEST argument will remain; that functionality is not in question. The
real questions which RMS is getting at are the following two:
(A) If you had no code you were worried about keeping compatible and you were
just writing code from scratch, do you think EQL or EQUAL would be the more
reasonable default predicate for MEMBER to use.
(B) If you have code which you want to run as easily as possible, do you
consider the cost of locating the places which require this small change
from (MEMBER x y) to (MEMBER x y :TEST #'EQUAL) to be too much of a price
to pay for item A.
Keep in mind that this will likely not be the only incompatible change
proposed by Common Lisp, so if you're thinking about the binary question
of "Will my code run without my messing with it?" there is a fair chance
the answer will be no anyway.