From: Captain Obvious on
You can think that package sort of defines a public interface to some
program module. Usually via defpackage form which has a list of all exported
symbols. (Also some people export symbols in source code itself.)

Well, as CL spec says "External symbols are part of the package's public
interface to other packages."

Public interface of a programming module is its own business and other
modules or packages should not affect it -- that is the motivation, I think.

j> 1. If the package "P" does not exist then P::name triggers an error.
j> It seems another quite reasonable behavior might be that READ should
j> simply create the package.

Package is supposed to define some interface, it doesn't make sense to make
them automatically.

j> 2. If the package "P" exists but does not contain "NAME", then P::name
j> interns "NAME" into P. It seems another resonable behavior might be to
j> allow the caller to determine whether or not to automatically intern
j> new symbols.

I think so too, but probably it is not very important, because P::name
violates public interface and is a hack anyway.

Spec says:
"If editor::buffer is seen, the effect is exactly the same as reading buffer
with the EDITOR package being the current package."

I think it is quite consistent behaviour.

j> 3. If the packagte "P" exists and contains "NAME", but "NAME" is not
j> interned or not exported, the reader signals an error when
j> cncountering P:NAME. Another reasonable behavior might be to allow
j> the caller to opt for automatically interning and exporting the
j> symbol.

Actually it gives you this option:

"If there is no package named editor, or if no symbol named BUFFER is
present in editor, or if BUFFER is not exported by editor, the reader
signals a correctable error."

SBCL and CMUCL offer this restart option:

0: [CONTINUE] Use symbol anyway.

j> 4. All keywords go into the same package. "KEYWORD". What causes the
j> evaluator to evaluate keywords to themselves?

----
11.1.2.3.1 Interning a Symbol in the KEYWORD Package

The KEYWORD package is treated differently than other packages in that
special actions are taken when a symbol is interned in it. In particular,
when a symbol is interned in the KEYWORD package, it is automatically made
to be an external symbol and is automatically made to be a constant variable
with itself as a value.
----

j> that the a : preceed the name. Other than this extremly handy syntax,
j> is there any other reason one might want all keywords in the same
j> package?

I think so -- conflicts between different uses of same keyword are not
possible because of the ways they are used, so it makes sense to have them
all in one package, also it is very handy because you can refer to those
keywords from any package without any hasle.

Packages are needed to avoid potential conficts among different pieces of
code. E.g. one piece of code might want to associate name foo with a
function, and a different piece of code wants to associate name foo with a
different function. Conflict can be avoided if those names/functions are
defined in different packages.

But if different pieces of code want to use keyword :bar for different
purposes, that's not a problem at all.
E.g.

(in-package :frob1)
(defun foo (&key bar) ...)
(defun baz () (foo :bar 1))

(in-package :frob2)
(defun foo (frob)
(case frob
(:foo 42)
(:bar 37)))

Even if keywords are used for different purposes, that's ok, because there
is no way to "spoil" a symbol so it won't be available for a different
purpose.

j> Is there an reasonable argument to allow keywords in other packages?

You mean symbols which evaluate to themselves but are not keywords?
Well, I think in some very rare cases they might be useful, but those cases
are so rare that inclusion into language standard is not justified, as users
can implement this kind of thing themselves.

j> Restated, suppose a lisp did not support the : synax for keywords but
j> insisted that keywords by identifyable by their inital character being
j> "?". Would their be an advantage for that lisp to force all such
j> keywords into the same package?

Well, yes, the advantage is that you do not need to bother exporting them
and naming them by their home package -- it just works.

From: Captain Obvious on
j> There is no reason that I know of why a symbol cannot exist in
j> multiple
j> packages without loosing identity. If package A "uses" package B, I
j> would expect the common symbols to be identical. At least A::foo and
j> B::foo would refer to the same object. right?

But symbol has only one home package.

??>> My impression is just that it is unclear _what_
??>> you are trying to achieve.

j> Sorry, but i'm not really at liberty to explain what I'm trying to
j> achieve, but that should not be necessary in order to understand why
certain
j> choices were made in the CL specification.

You're pretty much answering your own question.

Good language should have mostly practically useful stuff.

I guess you have at least some CL programming experience and yet you can't
say why "keywords in other packages" might be useful. This probably means
that those uses are rare.

And it answers why "keywords in other packages" are not in CL spec -- they
are not important enough.
And as CL is flexible enough to allow users to implement similar things
themselves, it is not a big deal even if there is some use.

Well, with an inspiration from Pascal Costanza I've found one such case --
when symbols from different, unrelated pieces of code (and thus from
different packages) are used in one list. For example, in initarg list in
make-instance call.
For example, two classes might be defined in different packages and they
have slot with same name:

(in-package :foo)

(defclass foo ()
((frob :initarg :frob)))

(in-package :bar)

(defclass bar ()
((frob :initarg :frob)))

And you want to use both these classes as ancestors:

(in-package :baz)

(defclass baz (foo bar)
())

(make-instance 'baz :frob 1)

Now, even if slot names look same, they are different: foo::frob in first
case and bar::frob in second.
But initargs are keywords and they are same, so you cannot initialize both
foo::frob and bar::frob via initarg :frob.

But cases like this are very rare, I think.

From: Tamas K Papp on
On Mon, 26 Apr 2010 00:22:15 +0300, Captain Obvious wrote:

> Well, with an inspiration from Pascal Costanza I've found one such case
> -- when symbols from different, unrelated pieces of code (and thus from
> different packages) are used in one list. For example, in initarg list
> in make-instance call.
> For example, two classes might be defined in different packages and they
> have slot with same name:
>
> (in-package :foo)
>
> (defclass foo ()
> ((frob :initarg :frob)))
>
> (in-package :bar)
>
> (defclass bar ()
> ((frob :initarg :frob)))
>
> And you want to use both these classes as ancestors:
>
> (in-package :baz)
>
> (defclass baz (foo bar)
> ())
>
> (make-instance 'baz :frob 1)
>
> Now, even if slot names look same, they are different: foo::frob in
> first case and bar::frob in second.
> But initargs are keywords and they are same, so you cannot initialize
> both foo::frob and bar::frob via initarg :frob.
>
> But cases like this are very rare, I think.

Interesting example, thanks for sharing it.

Considerations of the keyword package aside, I think it would be bad
practice to use the same name for slots that have different
interpretations, it could lead to a lot of confusion. So this is
unlikely to occur. But if it does, it can be solved by adding extra
keywords to the initialize-instance :after method.

Tamas
From: His kennyness on
jimka wrote:
> Can someone explain the motiviation for the behavior of READ in the
> following situations.

Answer to all following questions: you have somehow confused "read" with
"defpackage" and "intern". Did I once see you on a poster for dyslexia?

kt

>
> 1. If the package "P" does not exist then P::name triggers an error.
> It seems another quite reasonable behavior might be that READ should
> simply create the package.
>
> 2. If the package "P" exists but does not contain "NAME", then P::name
> interns "NAME" into P. It seems another resonable behavior might be to
> allow the caller to determine whether or not to automatically intern
> new symbols.
>
> 3. If the packagte "P" exists and contains "NAME", but "NAME" is not
> interned or not exported, the reader signals an error when
> cncountering P:NAME. Another reasonable behavior might be to allow
> the caller to opt for automatically interning and exporting the
> symbol.
>
> 4. All keywords go into the same package. "KEYWORD". What causes the
> evaluator to evaluate keywords to themselves? Is it that they exist
> in this package? The CL syntax for keywords is that the a : preceed
> the name. Other than this extremly handy syntax, is there any other
> reason one might want all keywords in the same package? Is there an
> reasonable argument to allow keywords in other packages? Restated,
> suppose a lisp did not support the : synax for keywords but insisted
> that keywords by identifyable by their inital character being "?".
> Would their be an advantage for that lisp to force all such keywords
> into the same package?
>
> -jim
From: Stelian Ionescu on
On Mon, 26 Apr 2010 00:22:15 +0300, Captain Obvious wrote:
[snip]
> Now, even if slot names look same, they are different: foo::frob in
> first case and bar::frob in second.
> But initargs are keywords and they are same, so you cannot initialize
> both foo::frob and bar::frob via initarg :frob.
>
> But cases like this are very rare, I think.

no, but you can initialize them both in other ways: one is to remember
that named arguments(improperly called keyword arguments) need not be
keywords

(defpackage :foo (:use :cl) (:export :foo :frob))
(in-package :foo)

(defclass foo ()
((frob :initarg frob)))

(defpackage :bar (:use :cl) (:export :bar :frob))
(in-package :bar)

(defclass bar ()
((frob :initarg frob)))

(defpackage :baz (:use :cl) (:export :baz))
(in-package :baz)

(defclass baz (foo:foo bar:bar)
())

(in-package :cl-user)
(describe (make-instance 'baz:baz 'foo:frob 1 'bar:frob 2))

--
Stelian Ionescu a.k.a. fe[nl]ix
Quidquid latine dictum sit, altum videtur.
http://common-lisp.net/project/iolib