Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

package-use-list & other results specification

1 view
Skip to first unread message

Pascal Bourguignon

unread,
Dec 19, 2003, 12:33:15 AM12/19/03
to

The specification for PACKAGE-USE-LIST is the laconic:

Returns a list of other packages used by package.


Let's compare it with the beginning of the specification for
CONCATENATE:

concatenate returns a sequence that contains all the individual
elements of all the sequences in the order that they are supplied.


Or REMOVE:

remove, remove-if, and remove-if-not return a sequence from which
the elements that satisfy the test have been removed.


Does "Returns A list" mean that the list returned is a "new" list?
(Can the client destructively modify without any side effect this
list?)


Usually, the specifications of other functions (such as CONCATENATE or
REMOVE) add enough information to let us know that "Returns a list"
means a newly consed list. But not so in the case of PACKAGE-USE-LIST
(and may be other). So we can find implementations that do either
way: clisp returns a newly consed list, openmcl returns the attribute
of the package:

$ openmcl -n
Welcome to OpenMCL Version (Alpha: Darwin) 0.14-031108!
? (package-use-list "COMMON-LISP-USER")
(#<Package "CCL"> #<Package "COMMON-LISP">)
? (nconc (package-use-list "COMMON-LISP-USER") (list (find-package "XLIB")))
(#<Package "CCL"> #<Package "COMMON-LISP"> #<Package "XLIB">)
? (package-use-list "COMMON-LISP-USER")
(#<Package "CCL"> #<Package "COMMON-LISP"> #<Package "XLIB">)
?

I dare not call that a bug in openmcl...

In any case, it would be a great improvement if the next version of
the standard specified more formally the behavior of its functions.

--
__Pascal_Bourguignon__ . * * . * .* .
http://www.informatimago.com/ . * . .*
There is no worse tyranny than to force * . . /\ ( . *
a man to pay for what he does not . . / .\ . * .
want merely because you think it .*. / * \ . .
would be good for him. -- Robert Heinlein . /* o \ .
http://www.theadvocates.org/ * '''||''' .
SCO Spam-magnet: postm...@sco.com ******************

Thomas A. Russ

unread,
Dec 19, 2003, 12:26:48 PM12/19/03
to

Pascal Bourguignon <sp...@thalassa.informatimago.com> writes:

> The specification for PACKAGE-USE-LIST is the laconic:
>
> Returns a list of other packages used by package.

...


> Does "Returns A list" mean that the list returned is a "new" list?
> (Can the client destructively modify without any side effect this
> list?)

It means that the standard is silent about whether the list is new.
There are numerous places in the standard where such behavior is not
specified, usually in order to allow latitude for different
implementation choices to be made.

...
>
> In any case, it would be a great improvement if the next version of
> the standard specified more formally the behavior of its functions.

Would you be happier with this?

Returns a list of other packages used by package. Whether the
list is newly created or a list used internally is implementation
dependent.

It conveys the same information, but is more verbose.

By leaving it ambiguous, you allow freedom to implementors to make
different choices about how to implement things internally. One
implementation may use a vector of used packages. In that case a fresh
list must be created each time. Another may store the information in a
list, in which case requiring it to return a fresh list forces consing
even if the caller doesn't plan to destructively modify the list.

There are many places where the standard is intentionally noncommittal
in order to allow just such freedom.

--
Thomas A. Russ, USC/Information Sciences Institute

Pascal Bourguignon

unread,
Dec 19, 2003, 2:18:11 PM12/19/03
to
t...@sevak.isi.edu (Thomas A. Russ) writes:

> Pascal Bourguignon <sp...@thalassa.informatimago.com> writes:
>
> > The specification for PACKAGE-USE-LIST is the laconic:
> >
> > Returns a list of other packages used by package.
> ...
> > Does "Returns A list" mean that the list returned is a "new" list?
> > (Can the client destructively modify without any side effect this
> > list?)
>
> It means that the standard is silent about whether the list is new.
> There are numerous places in the standard where such behavior is not
> specified, usually in order to allow latitude for different
> implementation choices to be made.
>
> ...
> >
> > In any case, it would be a great improvement if the next version of
> > the standard specified more formally the behavior of its functions.
>
> Would you be happier with this?
>
> Returns a list of other packages used by package. Whether the
> list is newly created or a list used internally is implementation
> dependent.
>
> It conveys the same information, but is more verbose.

Yes. I think it would be better if the standard was more explicit. It
might seem tedious to write, but it can be generated automatically
from an abstract description.


> By leaving it ambiguous, you allow freedom to implementors to make
> different choices about how to implement things internally. One
> implementation may use a vector of used packages. In that case a fresh
> list must be created each time. Another may store the information in a
> list, in which case requiring it to return a fresh list forces consing
> even if the caller doesn't plan to destructively modify the list.
>
> There are many places where the standard is intentionally noncommittal
> in order to allow just such freedom.

This is another point. Every time you give more freedom to the
implemenations at the level of the "contracts" of the API, you
increase the complexity of all the applications. Since there are more
applications than implementations, I think the standard should avoid
as much as possible to give such freedom.

The consequence is that on implementations that DO cons a new list, my
applications will conse twice the needed amount, because I'll have to
systematically use COPY-SEQ (or other non-destructive functions).
I've not seen in the standard any way to dynamically test if the
result of such noncommittal functions is a new copy or not (the
mutable vs. non-mutable problem).


Finally, in the case of PACKAGE-USE-LIST I don't think we can expect
more than a few tens of items (usually less than ten), so I can't see
the cost of specifying that all implementation should return a fresh
copy as prohibitive.

Pascal Costanza

unread,
Dec 19, 2003, 2:26:56 PM12/19/03
to

Pascal Bourguignon wrote:

> This is another point. Every time you give more freedom to the
> implemenations at the level of the "contracts" of the API, you
> increase the complexity of all the applications. Since there are more
> applications than implementations, I think the standard should avoid
> as much as possible to give such freedom.

Keep in mind that the standard was developed the other way around: it
standardized existing implementations of Lisp. It's not that they first
devised the standard, and then all the implementations emerged.

While it might not be too costly to change such minor details of
implementation when seen in isolation, such changes add up. In this
light, it is a reasonable question to ask whether a standard has to be
that specific.


Pascal

--
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."

Kalle Olavi Niemitalo

unread,
Dec 19, 2003, 5:32:06 PM12/19/03
to
t...@sevak.isi.edu (Thomas A. Russ) writes:

> Would you be happier with this?
>
> Returns a list of other packages used by package. Whether the
> list is newly created or a list used internally is implementation
> dependent.

For a while, I thought this could also be written in the same way
as in SYMBOL-NAME:

Returns a list of other packages used by package. The
consequences are undefined if the list is ever modified.

However, that sounds like it would also promise to applications
that the implementation's UNUSE-PACKAGE will not mutate the list.

Barry Margolin

unread,
Dec 20, 2003, 12:32:14 AM12/20/03
to
In article <87vfoch...@thalassa.informatimago.com>,
Pascal Bourguignon <sp...@thalassa.informatimago.com> wrote:

> The consequence is that on implementations that DO cons a new list, my
> applications will conse twice the needed amount, because I'll have to
> systematically use COPY-SEQ (or other non-destructive functions).

Only in those cases where you need to perform destructive operations on
the resulting list. In the case of something like PACKAGE-USE-LIST,
this seems like a pretty unusual thing to do. Also, these lists tend to
be short, and it's unlikely you'd be manipulating them in an inner loop,
so the impact of the extra consing is probably negligible.

--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA

Tim Bradshaw

unread,
Dec 20, 2003, 7:46:55 AM12/20/03
to
* Pascal Bourguignon wrote:

> The consequence is that on implementations that DO cons a new list, my
> applications will conse twice the needed amount, because I'll have to
> systematically use COPY-SEQ (or other non-destructive functions).
> I've not seen in the standard any way to dynamically test if the
> result of such noncommittal functions is a new copy or not (the
> mutable vs. non-mutable problem).

Can you find a realistic example where this would matter? I know it's
fun to whine on usenet, but it's hard to imagine an application where
the extra consing because of copying lists returned from
PACKAGE-USE-LIST is a significant performance issue. In the (I
suspect) far more common case where the application is simply
*searching* the result of PACKAGE-USE-LIST, or consing new things onto
the front of them, then not requiring the implementation to copy the
list is a performance win (albeit an equally tiny one).

Are there non-silly cases where the spec does not specify if a list is
fresh or not and there are no reasons not to do so (for instance: an
implementation might reasonably want to either cons or not cons a list
based on optimisation settings or something)?

--tim

0 new messages