From: Kaz Kylheku
Subject: Re: use-package & name conflict: why they are not deferred?
Date: 
Message-ID: <20081024153024.59@gmail.com>
On 2008-10-24, budden <········@mtu-net.ru> wrote:
> Hallo, group!
>
> Yes, I have read CL standard. But I think standard is not well defined
> in that:
>
> (defpackage :p1 (:exports :sym :sym1))
> (defpackage :p2 (:exports :sym :sym2))
> (use-package :p1)
> (use-package :p2) ; error occurs here

How is this not well-defined? 

Not well-defined means you don't know where the error should occur. Are you
sure what ``well-defined'' means?

``Well-defined'' doesn't mean ``not designed the way I want''.

> 'sym ; but read error should occur here instead

Why should it occur here, when the conflict is already known at the time
the packages are used, with 100% certainty?

> Let us compare lisp's behaviour to that of SQL:
>
> create table p1 (sym int, sym1 int)
> create table p2 (sym int, sym2 int)
>
> select sym1, sym2 from p1 inner join p2 on sym1=sym2 -- no error!
>
> select sym from p1 inner join p2 on sym1=sym2 -- error: sym is
> ambigious
>
> This behavior is more convinient and it still protects from error;

Delaying error detection is a liability. There has to be some kind of
meaningful payoff.

For instance, under dynamic typing, we delay detecting type mismatches to the
latest possible time.  We prefer this, because it allows us to program in
dynamic styles; we can write useful programs for which complete static checking
is not feasible.

However, even under dynamic typing, there is value when the compiler detects an
/obvious/ error which will not go away by run time. We don't ignore these
diagnostics, if we are lucky enough to have them.

What dynamic typing allows us is to run code that cannot be proven to be free
of errors; we don't ever want to deploy code that has been positively proven to
contain one or more type errors. The only way that kind of code can possibly be
safe is if the erroneous code is never executed: i.e. the code is unreachable,
or the program is never given inputs which cause the code to be reached. 

There are times during code refactoring when the program is like that; there
are type errors, but we carefully avoid stepping on them during the incremental
testing. We wouldn't ship the program in that half-baked state.

If you don't detect symbol clashes at package use time, you're creating a time
bomb. What if symbol "SYM" is interned at run time? Maybe it occurs in a data
file which the running software will load. Loading the data file will blow up.

> If we'd modified lisp behavior in the way I suggested, things would be
> much better, I guess.

``Much better'' is a huge overstatement.

You have to keep in mind that USE-PACKAGE is a blunt instrument within the
context of Lisp packages, which is generally a toolkit of sharp instruments.

There is no point in weakening the safety of a blunt instrument.  If doing that
makes your life ``much better'', maybe you are abusing the blunt instrument.

The only good use for USE-PACKAGE (or the corresponding :USE
directive in DEFPACKAGE) is to make the entire CL package visible from a
user-defined package.  Usually it's also possible, in addition to CL, to use
packages which all come from the Lisp implementation, because the Lisp
implementors usually ensure that they are mutually compatible for this kind of
use.

Beyond that, don't use USE-PACKAGE or :USE!   Take advantage of the blunt
instrument to get the base packages from the Lisp you are using, and then for
any user-defined stuff, bring out the scalpel: i.e. import specific symbols
from specific packages, with shadowing.
From: Barry Margolin
Subject: Re: use-package & name conflict: why they are not deferred?
Date: 
Message-ID: <barmar-93EE7D.23350024102008@mara100-84.onlink.net>
In article <·················@gmail.com>,
 Kaz Kylheku <········@gmail.com> wrote:

> On 2008-10-24, budden <········@mtu-net.ru> wrote:
> > Hallo, group!
> >
> > Yes, I have read CL standard. But I think standard is not well defined
> > in that:
> >
> > (defpackage :p1 (:exports :sym :sym1))
> > (defpackage :p2 (:exports :sym :sym2))
> > (use-package :p1)
> > (use-package :p2) ; error occurs here
> 
> How is this not well-defined? 
> 
> Not well-defined means you don't know where the error should occur. Are you
> sure what ``well-defined'' means?

I think he means "not defined well".

> 
> ``Well-defined'' doesn't mean ``not designed the way I want''.
> 
> > 'sym ; but read error should occur here instead
> 
> Why should it occur here, when the conflict is already known at the time
> the packages are used, with 100% certainty?

I think his point is that if you never actually reference SYM, the 
conflict should not cause a problem, so there's no reason to generate an 
error.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***