[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [spr2273] porting
> Return-Path: <firstname.lastname@example.org>
> Date: Thu, 22 Nov 90 13:43:31 HST
> To: allegro-cl@ucbvax.Berkeley.EDU
> Subject: porting
> Here are two differences between lucid and allegro that I
> 1. In allegro (and some other lisps I tried) (remove foo list)
> always returns a copy of list, even if foo is
> not in list. This is not true for lucid. So
> (let ((list '(a b c)))
> (eq list (remove 'd list)))
> returns nil with allegro but t with lucid. The second edition of
> Steele makes it clear that an implementation is not required to return
> a copy if nothing is removed, so neither one is wrong. In my opinion
> it would have been a better choice to always require that remove
> return a copy of list. [...]
> 2. The effect of
> (remove-duplicates list :from-end t :test #'(lambda (x y) (mytest x y)))
> in allegro is the same as
> (remove-duplicates list :from-end t :test #'(lambda (y x) (mytest x y)))
> in lucid (and vise versa). This is pretty obscure since usually mytest
> will be some equality-like predicate so (mytest x y) = (mytest y x).
> However there are some uses of this when "mytest" is not symmetric,
> eg. you can find the minimal sets from a list of sets by apply
> remove-duplicates twice, once with :from-end t, using a test based
> on subsetp. "Common Lisp, the Reference" states clearly that allegro
> is right but Steele is less definitive.
> Ralph Freese
> Dept. of Math.
> Univ. of Hawaii
> Honolulu, HI.
Here are a few comments about the issues raised.
1. [In response to 1 above.] I would like to make clear that
in cases like this where the standard permits implementors to
either copy a sequence or not, portable code must assume the
most conservative possibility (in this case, that the returned
sequence *may* be EQ to the argument sequence). It is in
the control of the ANSI X3J13 committee to decide whether the
standard should be tightened or not.
2. [In response to 2 above] Ralph Freese is quite right that `Common
Lisp: the Reference' says explicitly that sequence elements are
passed to the test function which is the value of the :TEST argument
in the order in which the elements appear in the sequence
*regardless* of the value of the :FROM-END argument. E.g., in
the description of the :TEST keyword argument on page 827, it says:
If the arguments passed to the predicate [which is the value of
:TEST] are from the same sequence (as with DELETE-DUPLICATES),
the elements are passed in the same order as they appear in the
sequence. This is true even if the :FROM-END keyword argument
Ralph further says that Steele is less definitive. Below I give
the sentences in CLtL-1 on which we base our position and also
another sentence which supports the Lucid position. But the
important point here is that it is *not* appropriate to leave
this issue up to the implementors. I am submitting a cleanup
issue to X3J13 so that they can decide which behavior is correct.
Look at page 247 of CLtL-1 and consider the second to last paragraph
before section 14.1. It says in part:
You may depend on the order in which the arguments are given
to TESTFNC [which is the value of the :TEST or :TEST-NOT
argument]; this permits the use of a non-commutative test
functions in a predictable manner. [...] If a sequence function
gives two elements from the same sequence argument to TESTFNC,
they are given in the same order in which they appear in
The statement in `Common Lisp: the Reference' quoted above is
based on this passage from CLtL-1. On the other hand, the middle
paragraph on page 246 of CLtL-1 says in part:
For some operations it can be useful to specify the direction
in which the sequence is conceptually processed. In this case,
the basic operation normally processes the qequence in the forward
direction, and processing in the reverse direction is indicated
by a non-NIL value for the keyword argument :FROM-END.
Now, I think that the text supports the Franz interpretation more
than the Lucid one (e.g. the first quote from CLtL-1 says `appear
in the sequence' rather than `are processed') but a ruling from
X3J13 will settle the matter.
Here is an example that illustrates the issue:
(defun testfnc (x y) (< x y))
(setq lis (list 1 2))
(remove-duplicates lis :test #'testfnc) -> (2) in both Allegro CL
and Lucid Common Lisp.
(remove-duplicates lis :test #'testfnc :from-end t)
-> (1) in Allegro CL
-> (1 2) in Lucid Common Lisp
[Note that if the Allegro interpretation of the effect of
:FROM-END is correct, returning (2) in the first case and (1)
in the second is correct since the description of REMOVE-
DUPLICATES on page 255 of CLtL-1 says `if any two match,
then the one occuring earlier is discarded (but if the
:FROM-END argument is true, then the one later in the
sequence is discarded).']
CLtL-2 has no changes or comments on this particular issue (i.e.
all the text quoted appears unchanged in CLtL-2, see e.g. pages
390, 391, 401, and 402).
This matter has been given the Franz internal tracking number
[spr2273]. We would appreciate it if people who wish to comment
on the issue use that tracking number in their message.