From: Pascal Bourguignon
Subject: package-use-list & other results specification
Date: 
Message-ID: <87zndpgyn8.fsf@thalassa.informatimago.com>
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: ··········@sco.com                 ******************

From: Thomas A. Russ
Subject: Re: package-use-list & other results specification
Date: 
Message-ID: <ymi65gc7m7b.fsf@sevak.isi.edu>
Pascal Bourguignon <····@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
From: Pascal Bourguignon
Subject: Re: package-use-list & other results specification
Date: 
Message-ID: <87vfochb0s.fsf@thalassa.informatimago.com>
···@sevak.isi.edu (Thomas A. Russ) writes:

> Pascal Bourguignon <····@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_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: ··········@sco.com                 ******************
From: Pascal Costanza
Subject: Re: package-use-list & other results specification
Date: 
Message-ID: <brvje2$ia3$1@newsreader3.netcologne.de>
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."
From: Barry Margolin
Subject: Re: package-use-list & other results specification
Date: 
Message-ID: <barmar-83FB83.00321520122003@netnews.attbi.com>
In article <··············@thalassa.informatimago.com>,
 Pascal Bourguignon <····@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, ······@alum.mit.edu
Arlington, MA
From: Tim Bradshaw
Subject: Re: package-use-list & other results specification
Date: 
Message-ID: <ey3u13vd5c0.fsf@lostwithiel.cley.com>
* 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
From: Kalle Olavi Niemitalo
Subject: Re: package-use-list & other results specification
Date: 
Message-ID: <87n09o5ti1.fsf@Astalo.kon.iki.fi>
···@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.