[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Atoms in association lists
Date: Monday, 6 July 1987, 11:34-CDT
... I write (setq alist '((a . 1) b (c . 3)))
then try (assoc 'c alist)
In Kyoto Common Lisp and in ZetaLisp, I get an error since the second
element of alist is not a CONS. In Golden Common Lisp, I get no error.
This is an "is an error" situation. Implementations are permitted to do
whatever they want in such a situation since you are not supposed to ever
cause this situation to occur.
I like the Gold Hill implementation, however. It makes the processing of
((:gettable-instance-variables a b)
(inittable-instance-variables c d))
Nothing to do with your question, but I wouldn't use ASSOC for this anyway,
since using it implies to me that you're looping over possible keywords doing
ASSOC rather than looping over the supplied options checking validity. This
is bad for at least three reasons that come immediately to mind:
* You won't detect mis-spelled or totally bogus keywords. For example,
(ASSOC ':INITABLE-INSTANCE-VARIABLES your-list) will return NIL
both because you didn't write it in the keyword package and because
you didn't spell it right.
* It will seem as if :SETTABLE-INSTANCE-VARIABLES is missing because
(ASSOC ':SETTABLE-INSTANCE-VARIABLES your-list) will return NIL.
I guess you can MEMBER for it later, but that seems really odd to me.
* You won't correctly detect duplications. eg,
((:gettable-instance-variables a) (:gettable-instance-variables b))
which you may want to treat like:
((:gettable-instance-variables a b))
or at least you way want to warn about.
Getting back to your original question, though...
Is the GCLisp interpretation wrong?
I can't really speak for GCLisp. Even if it does this, you'd better check
their documentation carefully to see if it is documented behavior. If it's
not, they'd be within their rights to change the behavior incompatibly
between releases, leaving your code broken.
I know that Maclisp used to have a similar behavior, but it worked by
never doing an atom test before taking CAR of the alist entry. That
generally worked out fine because the (CAR symbol) returned something
which you couldn't make any other way and hence were not likely to be
searching for. (It wouldn't surprise me to find that
(ASSOC (CAR 'A) '(A)) => A
in compiled Maclisp.) Anyway, CL could surely not tolerate an
interpretation that allowed blind CAR'ing into symbols. CL implementations
represent symbols in lots of different ways, and some of them might have
interesting user-accessible objects in the slot that CAR would look in,
so asking ASSOC to ignore atoms would mean putting an explicit atom check
in the ASSOC inner loop, which might be very slow in some implementations.
Also, efficiency aside, there's an error-checking argument. Even if we
made atoms in an alist be legal, that wouldn't mean that every time an
atom occurred in an alist it was there intentionally. Ill-formed alists
are easy to construct. If we made it legal to have atoms at toplevel in
an alist, an interesting class of program bugs that could have been
detected would not be detectable because we could not tell whether the
atom was there by design or by accident. In fact, entry to the debugger
is not always bad. The KCL and Zetalisp versions are doing you a favor
by flagging a buggy situation in your code; GCLisp is apparently not
doing you that favor.
If so, aside from RPLACD problems, wouldn't the GCLisp be slightly
I doubt any claimed usefulness would be worth the price in lost efficiency
and error checking. By the way, there are no RPLACD problems.
(ASSOC 'B '((A 3) B (C 4)))
returns NIL, but so does
(ASSOC 'B '((A 3) (C 4)))
You must always either do an ATOM check on the result of an ASSOC or
know absolutely for sure that the thing you're looking for is going to
be in the list before you do the RPLACD. Any RPLACD problem you're
alluding to was either already present before you brought up this issue
or was just imagined.