From: Captain Obvious on
??>> 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.

You're forgetting that these pieces of code could be in different libraries
which do not know about each other.
E.g. you have a "twitter" library:

(in-package :twitter)

(declass user ()
((id :accessor id-of :initarg :id)))

And you have a "facebook" library:

(in-package :facebook)

(declass user ()
((id :accessor id-of :initarg :id)))

Then I want to inherit from both, making:

(defclass social-user (twitter:user facebook:user)
())

Now what?

Yes, we can prefix slot and initarg names to make them a bit longer, but
unambiguous:

(declass user ()
((user-id :accessor user-id-of :initarg :user-id)))

Oh, wait, it doesn't help at all.
Maybe this:

(declass twitter-user ()
((twitter-user-id :accessor twitter-user-id-of :initarg
:twitter-user-id)))

Yes, this helps, but now I don't know why do we have packages and classes at
all, if we're prefixing everything anyway.

Slot ID in class USER in package TWITTER is supposed to mean twitter's
user's id. Prefixing is plainly dumb.

I think a better workaround would be not to inherit from both of them. That
is, instead of subclassing both these user classes, one could have a class
which has both of them as slots.

Multi-inheritance, in general, should be carefully used. Just inheriting
from two unsuspecting classes is probably a bad idea. A legit use of
multi-inheritance is mix-ins, and apparently, mix-in classes should be
carefully written.

That's why I think it is a rare and contrived example.

??>> So this is unlikely to occur.

Definitely.

??>> But if it does, it can be solved by adding extra keywords to the
??>> initialize-instance :after method.

Doesn't always work -- e.g. twitter:user could have initialize-instance
:after method which does something with the id. If id isn't there it will be
broken.

PJB> Why do you think we HAVE to specify the initarg of each slot?

Sometimes you have to.

PJB> So that in this situation we may write:
PJB> You have different keywords named the same in two different packages!

It implies that we're authors of both foo library and bar library. But then
we probably shouldn't use same slot names.

If you have existing libraries which use keywords as initargs, you'll have
to patch them both and probably also patch all libraries which depend on it.
It is easier to just give up multiple inheritance idea.

PJB> (make-instance 'baz foo:frob 1 bar:frob 2)

This only works if you've exported frob. So if, hypothetically, issues like
these were not rare, special reader macros for keyword-like symbols could be
justified.
That reader macro could do three things which now keywords do in CL:

* defconstant so you don't need quote
* automatically export
* make keywords easily recognizable in code, so syntax highlighting could
take this into account.

From: RG on
In article <hr678c$m2$1(a)news.eternal-september.org>,
Tim Bradshaw <tfb(a)tfeb.org> wrote:

> On 2010-04-26 23:20:17 +0100, RG said:
>
> > No, what :use does is make those symbols accessible by inheritance.
> > This has much the same effect as importing all the external symbols of
> > the used package, but it specifically does NOT cause those symbols to be
> > present (which is a precisely defined term in CLHS) in the using package.
>
> This is a terribly important distinction.

It can be, for example if you unexport a symbol:

? (make-package :p1)
#<Package "P1">
? (make-package :p2)
#<Package "P2">
? (make-package :p3)
#<Package "P3">

? (export 'p1::x :p1)
T
? (export 'p2::y :p2)
T

? (import 'p1:x :p3)
T
? (use-package :p2 :p3)
T

? (symbol-package 'p3::x)
#<Package "P1">
? (symbol-package 'p3::y)
#<Package "P2">

? (unexport 'p1::x :p1)
T
? (unexport 'p2::y :p2)
T

? (symbol-package 'p3::x)
#<Package "P1">
? (symbol-package 'p3::y)
#<Package "P3">

rg
From: RG on
In article <rNOSPAMon-E3FDE4.07320827042010(a)news.albasani.net>,
RG <rNOSPAMon(a)flownet.com> wrote:

> In article <hr678c$m2$1(a)news.eternal-september.org>,
> Tim Bradshaw <tfb(a)tfeb.org> wrote:
>
> > On 2010-04-26 23:20:17 +0100, RG said:
> >
> > > No, what :use does is make those symbols accessible by inheritance.
> > > This has much the same effect as importing all the external symbols of
> > > the used package, but it specifically does NOT cause those symbols to be
> > > present (which is a precisely defined term in CLHS) in the using package.
> >
> > This is a terribly important distinction.
>
> It can be, for example if you unexport a symbol:
>
> ? (make-package :p1)
> #<Package "P1">
> ? (make-package :p2)
> #<Package "P2">
> ? (make-package :p3)
> #<Package "P3">
>
> ? (export 'p1::x :p1)
> T
> ? (export 'p2::y :p2)
> T
>
> ? (import 'p1:x :p3)
> T
> ? (use-package :p2 :p3)
> T
>
> ? (symbol-package 'p3::x)
> #<Package "P1">
> ? (symbol-package 'p3::y)
> #<Package "P2">
>
> ? (unexport 'p1::x :p1)
> T
> ? (unexport 'p2::y :p2)
> T
>
> ? (symbol-package 'p3::x)
> #<Package "P1">
> ? (symbol-package 'p3::y)
> #<Package "P3">
>
> rg

Even better example where this matters:

? (export 'p2::y :p2)
> Error: Name conflict detected by EXPORT :
> EXPORT'ing P2::Y from #1=#<Package "P2"> would cause
> a name conflict with the present symbol P3::Y in the
> package #<Package "P3">, which uses #1#.
From: Tim Bradshaw on
On 2010-04-27 15:32:08 +0100, RG said:

> In article <hr678c$m2$1(a)news.eternal-september.org>,
> Tim Bradshaw <tfb(a)tfeb.org> wrote:
>>
>> This is a terribly important distinction.
>
> It can be, for example if you unexport a symbol:

Yes, I was agreeing with you!

From: Pascal J. Bourguignon on
"Captain Obvious" <udodenko(a)users.sourceforge.net> writes:

> PJB> Why do you think we HAVE to specify the initarg of each slot?
>
> Sometimes you have to.
>
> PJB> So that in this situation we may write:
> PJB> You have different keywords named the same in two different packages!
>
> It implies that we're authors of both foo library and bar library. But
> then we probably shouldn't use same slot names.
>
> If you have existing libraries which use keywords as initargs, you'll
> have to patch them both and probably also patch all libraries which
> depend on it.
> It is easier to just give up multiple inheritance idea.

I guess the argument is that libraries should not use keyword keywords
for initargs.

> PJB> (make-instance 'baz foo:frob 1 bar:frob 2)
>
> This only works if you've exported frob.

Which is exactly the point: a library would export the initargs
keywords it wants to be public, and keep private its private initargs.


> So if, hypothetically, issues
> like these were not rare, special reader macros for keyword-like
> symbols could be justified.
> That reader macro could do three things which now keywords do in CL:
>
> * defconstant so you don't need quote
> * automatically export
> * make keywords easily recognizable in code, so syntax highlighting
> could take this into account.

Notice that it should also take two parameters: the name of the
package and the name of the symbol. It happens that we already have
a syntax, if not a reader macro, to do so: package:symbol.

You can hardly beat this syntax.

#k(package symbol) --> package:symbol

?package?symbol --> package:symbol

?symbol[?package]
that is, with an optional package, which would default to read-time *package*.

?symbol --> symbol
?symbol?package --> package:symbol


Notice that CL keyword keywords are not highlighted because they are
used as keywords, but because they are keywords, that is, symbols with
special properties. CL:T and CL:NIL ought to be highlighted the same
way.



Basically, what I'm saying is that he idea developed in this thread
just comes from a miscomprehension of what CL keywords (symbols in the
KEYWORD package) are and that there is already all we need in CL to
make the wanted alternate keywords (symbols used as keywords).
Substituting ? for ' is no progress.


--
__Pascal Bourguignon__
http://www.informatimago.com