From: Peter Seibel
Subject: Using keywords as :initargs?
Date: 
Message-ID: <m3n0cwjslq.fsf@javamonkey.com>
While reading through some old c.l.l. posts on Google I saw someone
speculating that it might be a good coding style to *not* use keywords
as the :initargs in DEFCLASS forms.

I.e. prefer this:

  (defclass foo ()
    ((some-slot :initarg some-slot)))

  (make-instance 'foo 'some-slot 10)

to this:

  (defclass foo ()
    ((some-slot :initarg :some-slot)))

  (make-instance 'foo :some-slot 10)

The reason, as I understood it, is that if class A defined in one
package uses a keyword symbol as an initarg and class B in another
package uses the same keyword it's going to make it difficult to write
a third class that extends both A and B, while if they had each used a
symbol in the same package as the class name, then there will be no
problem with writing the class that extends them both.

So, two questions: 1) did I understand the issue correctly and 2) does
anyone actually use this approach? It seemed a bit strange at first
but actually makes a lot of sense.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp

From: Kenny Tilton
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <jEMbb.17886$u67.280@twister.nyc.rr.com>
Peter Seibel wrote in message ...
>While reading through some old c.l.l. posts on Google I saw someone
>speculating that it might be a good coding style to *not* use keywords
>as the :initargs in DEFCLASS forms.
>
>I.e. prefer this:
>
>  (defclass foo ()
>    ((some-slot :initarg some-slot)))
>
>  (make-instance 'foo 'some-slot 10)
>
>to this:
>
>  (defclass foo ()
>    ((some-slot :initarg :some-slot)))
>
>  (make-instance 'foo :some-slot 10)
>
>The reason, as I understood it, is that if class A defined in one
>package uses a keyword symbol as an initarg and class B in another
>package uses the same keyword it's going to make it difficult to write
>a third class that extends both A and B, ....

Great, now I am going to be afraid to fall asleep tonight because of the
nightmares I'll have in which I am trying to multiply inherit from two
classes with different semantics for slots with the same initarg. What makes
me think solving the initarg conflict just delays the catastrophic collapse
of the whole idea? This reminds me of the complaint about the admittedly
flawed class precedence list calculation; to expose the flaw requires
astonishingly bad OO design. But if one wants to defer the catastrophe,
would something like this work?:

(defclass cells::a ()
  ((cells::x :initform 'a :accessor cells::x :initarg :x)))

(defclass cl-user::b ()
  ((cl-user::x :initform 'b :accessor cl-user::x :initarg :x)))

(defclass c (cells::a cl-user::b)
  ((cells::x :initform 'ax :accessor ax :initarg :ax)
   (cl-user::x :initform 'bx :accessor bx :initarg :bx)))

(describe (make-instance 'c :ax 1 :bx 2))
=>
#<c @ #x2126639a> is an instance of #<standard-class c>:
 The following slots have :instance allocation:
  x   1
  x   2


kenny
From: Thomas F. Burdick
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <xcv4qz446xu.fsf@famine.OCF.Berkeley.EDU>
> Peter Seibel <·····@javamonkey.com> writes:
>
> The reason, as I understood it, is that if class A defined in one
> package uses a keyword symbol as an initarg and class B in another
> package uses the same keyword it's going to make it difficult to
> write a third class that extends both A and B, while if they had
> each used a symbol in the same package as the class name, then there
> will be no problem with writing the class that extends them both.
>
> So, two questions: 1) did I understand the issue correctly

Pretty much.  Above, instead of "there will be no problem", I'd have
said that you "don't create a gratuitous problem".  I get really lazy
when I code, and tend to pick the simplest, most generic names for
things, that I can get away with.  The package system makes this a
virtue, instead of a vice.  By choosing keywords for names of things
in your package, you're gratuitously avoiding the package system.  If
you name your exported slot FOO:BAR, and its acccessor function
FOO:BAR, why would you suddenly go and name its initarg :BAR?  The
answer is probably because that's what you say in examples when you
were first learning CLOS, so you internalized it, and it became
natural.

> and 2) does anyone actually use this approach? It seemed a bit
> strange at first but actually makes a lot of sense.

Yep, and not only that, but I sometimes define classes that take
advantage of that property.  I don't go out of my way, but once you
leave the door open to yourself, it just pops up sometimes.

"Kenny Tilton" <·······@nyc.rr.com> writes:
>
> Great, now I am going to be afraid to fall asleep tonight because of the
> nightmares I'll have in which I am trying to multiply inherit from two
> classes with different semantics for slots with the same initarg. What makes
> me think solving the initarg conflict just delays the catastrophic collapse
> of the whole idea?

A kneejerk response, perhaps?  Or maybe you use bigger packages than I
do?  Admittedly, I do have a COM.TOMADE.BINARY-IO package, and a
separate COM.TOMADE.TEXT-UTILS package?

> This reminds me of the complaint about the admittedly flawed class
> precedence list calculation; to expose the flaw requires
> astonishingly bad OO design. But if one wants to defer the
> catastrophe, would something like this work?:

Ick.  Why do you want to fake a package system when we've got a
working one?  One way I like to organize my code is to have a bunch of
packages that implement first-level functionality, and then a layer of
higher-level ones that combine the first-level packages, to create the
system the application is written in (it makes porting easier, too).
Combined with my lazyness when it comes to naming, well ... (see above)

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Peter Seibel
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <m365jkjnon.fsf@javamonkey.com>
"Kenny Tilton" <·······@nyc.rr.com> writes:

> Peter Seibel wrote in message ...
> >While reading through some old c.l.l. posts on Google I saw someone
> >speculating that it might be a good coding style to *not* use keywords
> >as the :initargs in DEFCLASS forms.
> >
> >I.e. prefer this:
> >
> >  (defclass foo ()
> >    ((some-slot :initarg some-slot)))
> >
> >  (make-instance 'foo 'some-slot 10)
> >
> >to this:
> >
> >  (defclass foo ()
> >    ((some-slot :initarg :some-slot)))
> >
> >  (make-instance 'foo :some-slot 10)
> >
> >The reason, as I understood it, is that if class A defined in one
> >package uses a keyword symbol as an initarg and class B in another
> >package uses the same keyword it's going to make it difficult to write
> >a third class that extends both A and B, ....
> 
> Great, now I am going to be afraid to fall asleep tonight because of the
> nightmares I'll have in which I am trying to multiply inherit from two
> classes with different semantics for slots with the same initarg. What makes
> me think solving the initarg conflict just delays the catastrophic collapse
> of the whole idea? This reminds me of the complaint about the admittedly
> flawed class precedence list calculation; to expose the flaw requires
> astonishingly bad OO design.

Dunno about that. It's not crazy to imagine that to independent
developers might both write classes with that contain a slot with a
generic name like, say, 'name'. If it ever makes sense to inherit from
both those classes, it's bad news if they are using keyword symbols as
their initargs but no problem if they use proper symbols. Then the
fact that the two slot names are string= is just punny as opposed to a
major hassle.

To look at it the other way: what's the argument in favor of using
keyword symbols for initargs?

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Thomas F. Burdick
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <xcvzngw2s7e.fsf@famine.OCF.Berkeley.EDU>
Peter Seibel <·····@javamonkey.com> writes:

> To look at it the other way: what's the argument in favor of using
> keyword symbols for initargs?

AFAICT, it consists of an irrational belief that it's easier to type
#\: than #\'

(Fellow partisans: email me offline to find a time to meet in Berkeley
to coordinate this attack :)

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Pascal Bourguignon
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <87d6dsvv32.fsf@thalassa.informatimago.com>
···@famine.OCF.Berkeley.EDU (Thomas F. Burdick) writes:

> Peter Seibel <·····@javamonkey.com> writes:
> 
> > To look at it the other way: what's the argument in favor of using
> > keyword symbols for initargs?
> 
> AFAICT, it consists of an irrational belief that it's easier to type
> #\: than #\'

Not at all. With 'initarg you can write:

(defclass subclass (a:class-a b:class-b)  ())
(make-instance 'subclass  'a:slot val-a 'b:slot val-b)

with keywords you would be stuck.


But the  point is not there.   The point is  that encapsulation should
not prevent developers have access  (read and write) to the sources of
each other, or to do some previous analysis and planning.


Also, you  have two  cases: either the  fields are  synonymous because
they're the  same thing, and  then it should  be moved up in  a common
ancestor of the mixins, or  they're something different, and they they
should be named differently.


-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Kenny Tilton
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <WBPbb.20168$u67.10807@twister.nyc.rr.com>
Peter Seibel wrote in message ...
>"Kenny Tilton" <·······@nyc.rr.com> writes:
>
>> Peter Seibel wrote in message ...
>> >While reading through some old c.l.l. posts on Google I saw someone
>> >speculating that it might be a good coding style to *not* use keywords
>> >as the :initargs in DEFCLASS forms.
>> >
>> >I.e. prefer this:
>> >
>> >  (defclass foo ()
>> >    ((some-slot :initarg some-slot)))
>> >
>> >  (make-instance 'foo 'some-slot 10)
>> >
>> >to this:
>> >
>> >  (defclass foo ()
>> >    ((some-slot :initarg :some-slot)))
>> >
>> >  (make-instance 'foo :some-slot 10)
>> >
>> >The reason, as I understood it, is that if class A defined in one
>> >package uses a keyword symbol as an initarg and class B in another
>> >package uses the same keyword it's going to make it difficult to write
>> >a third class that extends both A and B, ....
>>
>> Great, now I am going to be afraid to fall asleep tonight because of the
>> nightmares I'll have in which I am trying to multiply inherit from two
>> classes >>>with different semantics<<<  for slots with the same initarg.
>
>Dunno about that. It's not crazy to imagine that to independent
>developers might both write classes with that contain a slot with a
>generic name like, say, 'name'.

Ah, but with different semantics for name? Like, in one case it's the name
of the thing, and in the other class it's the thing's name? And we have to
keep these same names separate? :)

I'll need an example. like maybe the class Burdick inherits from both
GourmetChef and GangMember, both of which have the slot "name" but which
must be different so Five-O can't track the blood down from his street name.
Except then the class GangMember sucks, it should use streetName for that
slot if it means to denote something other than homey's legalName.

btw, no reaction to my demonstration that the conflict can be avoided by
restating the slots in the inheriting class?

Why the keywords? This did not go over very well with ACL.

(defun test (one &key 'two)
  (list one two))

ie, keyword args use keywords. make-instance is a generic function that
takes keywords. Using symbols is just a stunt, and it breaks
initialize-instance and its ilk: now the intended keywords have to be parsed
out of a &rest parameter. This is progress? Breaking initialize-instance and
shared-initialize rather than restating the slots and overriding the
conflicting initargs for which I doubt a good example can be given?

As for avoiding the package system, right, let's eliminate the keyword
package and never use &key.

:)

kenny
From: Peter Seibel
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <m3y8wghyz4.fsf@javamonkey.com>
"Kenny Tilton" <·······@nyc.rr.com> writes:

> Peter Seibel wrote in message ...
> >"Kenny Tilton" <·······@nyc.rr.com> writes:
> >
> >> Peter Seibel wrote in message ...
> >> >While reading through some old c.l.l. posts on Google I saw someone
> >> >speculating that it might be a good coding style to *not* use keywords
> >> >as the :initargs in DEFCLASS forms.
> >> >
> >> >I.e. prefer this:
> >> >
> >> >  (defclass foo ()
> >> >    ((some-slot :initarg some-slot)))
> >> >
> >> >  (make-instance 'foo 'some-slot 10)
> >> >
> >> >to this:
> >> >
> >> >  (defclass foo ()
> >> >    ((some-slot :initarg :some-slot)))
> >> >
> >> >  (make-instance 'foo :some-slot 10)
> >> >
> >> >The reason, as I understood it, is that if class A defined in one
> >> >package uses a keyword symbol as an initarg and class B in another
> >> >package uses the same keyword it's going to make it difficult to write
> >> >a third class that extends both A and B, ....
> >>
> >> Great, now I am going to be afraid to fall asleep tonight because of the
> >> nightmares I'll have in which I am trying to multiply inherit from two
> >> classes >>>with different semantics<<<  for slots with the same initarg.
> >
> >Dunno about that. It's not crazy to imagine that to independent
> >developers might both write classes with that contain a slot with a
> >generic name like, say, 'name'.
> 
> Ah, but with different semantics for name? Like, in one case it's the name
> of the thing, and in the other class it's the thing's name? And we have to
> keep these same names separate? :)

If the two classes were developed independently, sure. I wouldn't be
surprised at all if two different classes that used a generic slot
name like 'name' (or, if you like better, 'id') happened to have
different enough semantics associated with each slot that a class that
inherited from them both would need to keep the slots distinct and
initialize them separately. I guess the slots will remain distinct as
long as the symbols are in different packages and you can resolve the
:initarg conflict by recreating the slots in the inheriting class. But
why is that better; if we had just used unique names in the first
place we wouldn't have to bother with that renaming just because of a
name conflict. (I'm not necessarily disagreeing with you--if, as you
claim, in the grand scheme of things these conflicts are rare that it
hardly matters what solution we use since the problem never comes up
in practice. But it was a wiser person than me who put the idea in my
head so I wanted to see what had come of it.)

> I'll need an example. like maybe the class Burdick inherits from both
> GourmetChef and GangMember, both of which have the slot "name" but which
> must be different so Five-O can't track the blood down from his street name.
> Except then the class GangMember sucks, it should use streetName for that
> slot if it means to denote something other than homey's legalName.
>
> btw, no reaction to my demonstration that the conflict can be avoided by
> restating the slots in the inheriting class?

Hmmm. What happens if someone does use the old initarg when calling
make-instance? Where does the value get stashed? Both? Neither? (Seems
like it's both but I'm too tired right now to run it to ground.)

> Why the keywords? This did not go over very well with ACL.
> 
> (defun test (one &key 'two)
>   (list one two))
> 
> ie, keyword args use keywords.

Well, you have to use the correct syntax:

  CL-USER(254): (defun test (one &key ((two two))) (list one two))
  TEST
  CL-USER(255): (test 1 'two 2)
  (1 2)

Okay, so that's not so pretty. But the only intrinsic relation between
&key and keywords is that if you don't specify the keyword argument it
defaults to using the string= symbol in the keyword package. In
retrospect you could imagine that things might work just as well if

  (defun test (one &key two) ...)

caused the "keyword" to be the symbol 'two' in whatever package the
DEFUN was read in, rather than the keyword package. (Of course I've
already had my nightcap for tonight so there may be some reason that's
totally wrong that I'm missing at the moment.)

> make-instance is a generic function that takes keywords. Using
> symbols is just a stunt, and it breaks initialize-instance and its
> ilk: now the intended keywords have to be parsed out of a &rest
> parameter.

What? Why does initialize-instance break?

  (defclass foo ()
    ((slot :initarg slot :accessor slot)
     (twice-slot :accessor twice-slot)))

  (defmethod initialize-instance ((obj foo) &key ((slot slot-value)))
    (call-next-method)
    (setf (slot-value obj 'twice-slot) (* 2 slot-value)))

  CL-USER(273): (with-slots (slot twice-slot) (make-instance 'foo 'slot 10)
                  (format t "slot: ~d; twice-slot: ~d~%" slot twice-slot))
  slot: 10; twice-slot: 20
  NIL

That may not be as convenient but it's not broken.

> This is progress? Breaking initialize-instance and shared-initialize
> rather than restating the slots and overriding the conflicting
> initargs for which I doubt a good example can be given?

Sorry--I'm too tired to think of a good one. You may be right, there
may be none.

> As for avoiding the package system, right, let's eliminate the keyword
> package and never use &key.

So the last (never use &key) doesn't follow from the penultimate
(eliminate the keyword package).

> :)

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Kenny Tilton
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <zhXbb.22929$u67.7788@twister.nyc.rr.com>
Peter Seibel wrote in message ...
>"Kenny Tilton" <·······@nyc.rr.com> writes:
>
>> Peter Seibel wrote in message ...
>> >"Kenny Tilton" <·······@nyc.rr.com> writes:
>> >
>> >> Peter Seibel wrote in message ...
>> >> >While reading through some old c.l.l. posts on Google I saw someone
>> >> >speculating that it might be a good coding style to *not* use
keywords
>> >> >as the :initargs in DEFCLASS forms.
>> >> >
>> >> >I.e. prefer this:
>> >> >
>> >> >  (defclass foo ()
>> >> >    ((some-slot :initarg some-slot)))
>> >> >
>> >> >  (make-instance 'foo 'some-slot 10)
>> >> >
>> >> >to this:
>> >> >
>> >> >  (defclass foo ()
>> >> >    ((some-slot :initarg :some-slot)))
>> >> >
>> >> >  (make-instance 'foo :some-slot 10)
>> >> >
>> >> >The reason, as I understood it, is that if class A defined in one
>> >> >package uses a keyword symbol as an initarg and class B in another
>> >> >package uses the same keyword it's going to make it difficult to
write
>> >> >a third class that extends both A and B, ....
>> >>
>> >> Great, now I am going to be afraid to fall asleep tonight because of
the
>> >> nightmares I'll have in which I am trying to multiply inherit from two
>> >> classes >>>with different semantics<<<  for slots with the same
initarg.
>> >
>> >Dunno about that. It's not crazy to imagine that to independent
>> >developers might both write classes with that contain a slot with a
>> >generic name like, say, 'name'.
>>
>> Ah, but with different semantics for name? Like, in one case it's the
name
>> of the thing, and in the other class it's the thing's name? And we have
to
>> keep these same names separate? :)
>
>If the two classes were developed independently, sure. I wouldn't be
>surprised at all if two different classes that used a generic slot
>name like 'name' (or, if you like better, 'id')

OK, and in one class the id has to be a number and in the other case it has
to be a symbol? You know that picture of Rosemary Wood demonstrating how she
might have created the 18.5 minute gap? :)

btw, this is Lisp, objects reliably have identities, they do need IDs. And
variables are untyped, so if /either/ class insists on the ID being of a
certain type it sucks.

The theme I am trying to develop is that this agonizing over initargs is a
language-lawyer thang, not something that can arise reasonably in practice.

>... you can resolve the
>:initarg conflict by recreating the slots in the inheriting class. But
>why is that better; if we had just used unique names in the first
>place

Because:

   (make-instance 'landscape :tell 'trees :from 'forest)

...is so much more readable than:

   (make-instance 'landscape 'tell 'trees 'from 'forest)

Your co-conspirator Burdick may have deleted the keyword package from his
copy of CMUCL, but it got there for a reason.

>Hmmm. What happens if someone does use the old initarg when calling
>make-instance? Where does the value get stashed? Both? Neither? (Seems
>like it's both but I'm too tired right now to run it to ground.)

No, it's the fantasy "someone" who gets stashed in the dumpster out back for
banking on the implementation underlying this very confused class.

>
>> Why the keywords? This did not go over very well with ACL.
>>
>> (defun test (one &key 'two)
>>   (list one two))
>>
>> ie, keyword args use keywords.
>
>Well, you have to use the correct syntax:
>
>  CL-USER(254): (defun test (one &key ((two two))) (list one two))

yeah, yeah, yeah, I figured there was some trick.

>Okay, so that's not so pretty.

Oh, but now we are 99 44/100% Package Pure! :)

>,,, But the only intrinsic relation between
>&key and keywords is that if you don't specify the keyword argument it
>defaults to using the string= symbol in the keyword package. In
>retrospect you could imagine that things might work just as well if
>
>  (defun test (one &key two) ...)
>
>caused the "keyword" to be the symbol 'two' in whatever package the
>DEFUN was read in, rather than the keyword package. (Of course I've
>already had my nightcap for tonight so there may be some reason that's
>totally wrong that I'm missing at the moment.)

Remember, the name of the book is Practical Lisp. keywords are neato. That's
practical, this fantasy dual-not-dual ID slot is not.

>That may not be as convenient but it's not broken.

:) Hey, this is a flamewar, don't expect me to limit myself to accurate
statements.

kenny
From: Thomas F. Burdick
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <xcvr8272agy.fsf@famine.OCF.Berkeley.EDU>
"Kenny Tilton" <·······@nyc.rr.com> writes:

> Peter Seibel wrote in message ...
>
> >If the two classes were developed independently, sure. I wouldn't be
> >surprised at all if two different classes that used a generic slot
> >name like 'name' (or, if you like better, 'id')
> 
> OK, and in one class the id has to be a number and in the other case it has
> to be a symbol? You know that picture of Rosemary Wood demonstrating how she
> might have created the 18.5 minute gap? :)
> 
> btw, this is Lisp, objects reliably have identities, they do need IDs.

In the image, sure.  That's why one class's ID slot might work on
EQL-ness.  But what about an object-store?  It might need a numeric ID
for objects.

> >Hmmm. What happens if someone does use the old initarg when calling
> >make-instance? Where does the value get stashed? Both? Neither? (Seems
> >like it's both but I'm too tired right now to run it to ground.)
> 
> No, it's the fantasy "someone" who gets stashed in the dumpster out back for
> banking on the implementation underlying this very confused class.

I'm with you on that one.  But I also like writing mixin classes.  Do
I really have to do:

  (defclass foo-mixin ()
    ((x :initarg :foo-mixin-x ...) ...))

just because X might be a semi-generic name?  I write my *-mixin
classes carefully, so they can be mixed in with totally unrelated
classes.  What if I have some code:

  (defmethod blatz-copy ((thing foo-mixin) ...)
    ...
    (make-instance (class-of thing) :x 0 ...))

Maybe THING is of a class that did the :foo-x/:bar-x initarg thing.
What happens with the :X argument?  Something should get stuffed
somewhere, but I think it's the belligerent style.

> Remember, the name of the book is Practical Lisp. keywords are neato.

And your keyword-args-to-functions point is only tangential.

> That's practical, this fantasy dual-not-dual ID slot is not.
> 
> >That may not be as convenient but it's not broken.
> 
> :) Hey, this is a flamewar, don't expect me to limit myself to accurate
> statements.

In light of this being a mostly-ironic flamewar, and a fairly
reaonable discussion of engineering techniques, I have an example,
from Testa, where we used the benefits of my technique.  I don't want
to dig it up now because the power is out (why does California feel so
much like the third world recently?), but I'll get it tomorrow.  If I
don't, feel free to attack me for having a vaporware argumentation
module...

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Kenny Tilton
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <3F710FA6.8D42E51@nyc.rr.com>
"Thomas F. Burdick" wrote:
> ...but I'll get it tomorrow.  

As in "there is not enough room in the margin"? <g> Well, I just found
out I am giving two talks at ILC2003, one on Cells and one on the
RoboCells framework, so I'll just have to leave it at...

X? You want to call a slot X and not have name clashes? Because you
intend to do it more than once? And have it mean different things? Oh.
Never mind.

:)

-- 

 clinisys, inc
 http://www.tilton-technology.com/
 ---------------------------------------------------------------
"[If anyone really has healing powers,] I would like to call
them about my knees."
                    --  Tenzin Gyatso, the Fourteenth Dalai Lama
From: Thomas F. Burdick
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <xcvvfrj2b8t.fsf@famine.OCF.Berkeley.EDU>
"Kenny Tilton" <·······@nyc.rr.com> writes:

> Peter Seibel wrote in message ...
>
> >Dunno about that. It's not crazy to imagine that to independent
> >developers might both write classes with that contain a slot with a
> >generic name like, say, 'name'.
> 
> Ah, but with different semantics for name? Like, in one case it's the name
> of the thing, and in the other class it's the thing's name? And we have to
> keep these same names separate? :)

Sure, the package system helps you out here.  I know that *you* are a
big fan of accessor functions (as opposed to using WITH-SLOTS) -- so
you surely[*] must know that GANG:NAME is one function, and
GOVERNMENT:NAME is another.  To turn your question around, do you
really think having two *functions* with the same name, in different
packages is unreasonable?  Surely[*] not!  So why this sudden infatuation
with slot names?

> I'll need an example. like maybe the class Burdick inherits from both
> GourmetChef and GangMember, both of which have the slot "name" but which
> must be different so Five-O can't track the blood down from his street name.
> Except then the class GangMember sucks, it should use streetName for that
> slot if it means to denote something other than homey's legalName.

No, class Mobb-Member doesn't suck, because its slot is named
GANG:NAME, and the accessor function is called GANG:NAME.  Years ago,
I read a book about a chef in La Cosa Nostra, who bounced from boss to
boss during the gang wars in NYC.  Lets say I wrote a game about the
gang wars.  I've got a Person class, a GOVERNMENT package, a Persona
class in that package, which inherits from Person.  A lot of
immigrants might be instances of Person, but not Government:Persona
(no matter what right-wingers might tell you).  Let's say we've got
Occupations:Chef, and Occupations:Legitimate-Mixin (which inherits
from Government:Persona).  Now we introduce a character who is an
Occupations:Legitimate-Chef, *and* a Gang:Persona.  To access
someone's Gang:Name, I use (duh) Gang:Name.  To access someone's
government name, I use Government:Name.  That's a perfectly alright
class hierarchy, right?  I thought so.

So why you gotta go and screw everything up with weird initargs?

Now, to give you a challenge -- if you use the style of programming,
where you always access slots through their accessor functions
(allowing easy portable hacks � la Cells), slots are just a particular
way to implement an attribute of an object.  So, essentially, slot
names are accessor names.  Is there something wrong with having an
INTERVAL package, where I have interval arithmetic?  How about a MOD
package where I have modular arithmetic?  Should I really have to name
my modular addition function MOD:MOD+ ?!?!?!

> btw, no reaction to my demonstration that the conflict can be avoided by
> restating the slots in the inheriting class?

If you call MAKE-INSTANCE on a class object (not just a class name),
you can allow instances of a subclass there, too.  If your call passes
in an initarg for :x, then the :foo-x/:bar-x thing won't work.

> As for avoiding the package system, right, let's eliminate the keyword
> package and never use &key.

No no, the "" package (aka, "KEYWORD", at least in my CMUCL) is great.
As are &key arguments.  And I love me some defun.  And I'm all chill
with deftype.  However, surely[*] you know that there are inextensible
facilities, right?  Whereas defclass lets you define extensible types.
So, while:

  (deftype (thing &key a b c) ...)

might be fine, this is because the list of keywords is fixed: :A, :B,
and :C.  Surely[*] you know that one of the points of defclass is to let
you *extend* classes, right?

[*] Unnecessary sarcasm due to belligerent declaration of (flame) war.
Those more sensitive than Kenny may wish to filter this message
through the following regular expression: [Ss]urely[^?!.]*[?!.]

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Kenny Tilton
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <3F713204.15EFDCAB@nyc.rr.com>
"Thomas F. Burdick" wrote:


> [*] Unnecessary sarcasm due to belligerent declaration of (flame) war.
> Those more sensitive than Kenny may wish to filter this message
> through the following regular expression: [Ss]urely[^?!.]*[?!.]

Oh, sure, /now/ you respond in detail, after learning my hands are tied
by having to prepare two talks, one paper, and RoboCup team in a pear
tree. Look, just stop calling me Shirley.

:)

kenny

ps. the gang slot should be streetName or nickname or alias, the Person
slots should be surname, givenName, etc. They stopped using single
letters for variable names for a reason. Tilton's Law: spend more time
on your data names than on your algorithm. You are robbing your users of
information by being too lazy to think up precise names which will
perforce be less likely to collide. And by god, if you have a variable
X, the slot better describe a point on the X-axis.

:)

-- 

 clinisys, inc
 http://www.tilton-technology.com/
 ---------------------------------------------------------------
"[If anyone really has healing powers,] I would like to call
them about my knees."
                    --  Tenzin Gyatso, the Fourteenth Dalai Lama
From: Peter Seibel
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <m34qz2gnu8.fsf@javamonkey.com>
Kenny Tilton <·······@nyc.rr.com> writes:

> "Thomas F. Burdick" wrote:
> 
> 
> > [*] Unnecessary sarcasm due to belligerent declaration of (flame) war.
> > Those more sensitive than Kenny may wish to filter this message
> > through the following regular expression: [Ss]urely[^?!.]*[?!.]
> 
> Oh, sure, /now/ you respond in detail, after learning my hands are tied
> by having to prepare two talks, one paper, and RoboCup team in a pear
> tree. Look, just stop calling me Shirley.

I guess this is a good time for me to pile back on then. ;-) Consider
the effect of default-initargs. That can't be fixed back up be
redeclaring the slots, I don't believe.

  (defpackage :foo (:use :cl) (:export :object :slot ))
  (in-package :foo)
  (defclass object () ((slot :initarg :slot)) (:default-initargs :slot 10))


  (defpackage :bar (:use :cl) (:export :object :slot ))
  (in-package :bar)
  (defclass object () ((slot :initarg :slot)) (:default-initargs :slot 20))

Note the different default-initarg in :bar's version of object.

  (in-package :cl-user)
  (defclass foo (foo:object bar:object) ())
  (slot-value (make-instance 'foo) 'foo:slot)
  10
  (slot-value (make-instance 'foo) 'bar:slot)
  10

Whoops, That's not the default value we wanted!

Obviously if I had used initforms on the slots, rather than
default-initargs I wouldn't have this problem. But the it's harder to
write initialize-instance because your beloved keyword argument would
be nil instead of getting the default value.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Kenny Tilton
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <3F71DC79.515ED4D4@nyc.rr.com>
Peter Seibel <·····@javamonkey.com> wrote in message
news:<··············@javamonkey.com>...
> "Kenny Tilton" <·······@nyc.rr.com> writes:
> > This is progress? Breaking initialize-instance and shared-initialize
> > rather than restating the slots and overriding the conflicting
> > initargs for which I doubt a good example can be given?
> 
> Sorry--I'm too tired to think of a good one. You may be right, there
> may be none.

Ok, it's been 42 hours of rest. Let's see what you came up with:

Peter Seibel <·····@javamonkey.com> wrote
> (defclass object () ((slot :initarg :slot)) (:default-initargs :slot 10))

Slot? You have a slot called slot? Can we go back to X?

:)

kenny

ps. default-initargs are for slots defined in a superclass and not
restated in the class being defined. You should be using :initform in
the above real world example (on any world named World <g>).

pps. Shouldn't the class name above be Class?

-- 

 clinisys, inc
 http://www.tilton-technology.com/
 ---------------------------------------------------------------
"[If anyone really has healing powers,] I would like to call
them about my knees."
                    --  Tenzin Gyatso, the Fourteenth Dalai Lama
From: Peter Seibel
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <m3vfrif3ml.fsf@javamonkey.com>
Kenny Tilton <·······@nyc.rr.com> writes:

> Peter Seibel <·····@javamonkey.com> wrote in message
> news:<··············@javamonkey.com>...
> > "Kenny Tilton" <·······@nyc.rr.com> writes:
> > > This is progress? Breaking initialize-instance and shared-initialize
> > > rather than restating the slots and overriding the conflicting
> > > initargs for which I doubt a good example can be given?
> > 
> > Sorry--I'm too tired to think of a good one. You may be right, there
> > may be none.
> 
> Ok, it's been 42 hours of rest. Let's see what you came up with:
> 
> Peter Seibel <·····@javamonkey.com> wrote
> > (defclass object () ((slot :initarg :slot)) (:default-initargs :slot 10))
> 
> Slot? You have a slot called slot? Can we go back to X?

No. I like SLOT. In fact, I like it so much, I think I'll start
calling all my slots SLOT. In fact, I'm going to create a new package
for every slot I need, just so I can call every slot SLOT. Even
different slots in the same class. I mean, that's what they are,
right? Slots?

> :)

:-P

> ps. default-initargs are for slots defined in a superclass and not
> restated in the class being defined.

That's my point--these two classes each defined slots, with no
expectation that they would be (or would need to be) "restated",
providing a default value using the mechanism that makes it easier to
write an INITIALIZE-INSTANCE method. But then when they do get mixed
together by someone who may not even realize that there's a conflict
(say one of the classes use the slot internally but doesn't publish it
as part of the API, thus doesn't publish the initarg) they get broken
because of the nameclash due to shoving all initargs into the same
namespace.

> You should be using :initform in the above real world example (on
> any world named World <g>).

Why? Doesn't that just make it harder to write INITIALIZE-INSTANCE?

> pps. Shouldn't the class name above be Class?

Probably. ;-)

-Peter

P.S. BTW, I admire the subtle way (this is, after all, a nice subtle
flame war) you quoted me out of context. ;-) That wasn't intended to
be my response to your request for a real world example. But you knew
that.

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Kenny Tilton
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <UFncb.16586$nU6.3614775@twister.nyc.rr.com>
Peter Seibel wrote:

> 
>>ps. default-initargs are for slots defined in a superclass and not
>>restated in the class being defined.
> 
> 
> That's my point--these two classes each defined slots, with no
> expectation that they would be (or would need to be) "restated",

You're joking, right? You are so worried about this issue that you will 
use unexported symbols for initargs, yet you will use default-initarg 
where you should use initform because you do not expect anyone to take 
advantage of features put into CLOS precisely so folks could use classes 
and substitute their own options for the slots they are inheriting?

Has it occurred to you that using a default-initarg prevents them from 
using initform for restated slots?

>>You should be using :initform in the above real world example (on
>>any world named World <g>).
> 
> 
> Why? Doesn't that just make it harder to write INITIALIZE-INSTANCE?

how?

> P.S. BTW, I admire the subtle way (this is, after all, a nice subtle
> flame war) you quoted me out of context. ;-) 

Yeah, I'm pretty proud of that one. I thought about prefacing it with 
"No, really, all this language lawyer stuff is pointless until you come 
up with a real-world example.", but that would have taken a lot of the 
zing out my cheap shot.

Only after that did I notice you were using :default-initargs improperly 
and dropped that in as a postscript, but now I am really looking forward 
to seeing what others think about default-initargs being only so a class 
can specify one without restating aninherited slot.


kenny
From: Peter Seibel
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <m3fzilg60z.fsf@javamonkey.com>
Kenny Tilton <·······@nyc.rr.com> writes:

> Peter Seibel wrote:
> 
> >
> >>ps. default-initargs are for slots defined in a superclass and not
> >>restated in the class being defined.
> > That's my point--these two classes each defined slots, with no
> > expectation that they would be (or would need to be) "restated",
> 
> You're joking, right? You are so worried about this issue that you
> will use unexported symbols for initargs, yet you will use
> default-initarg where you should use initform because you do not
> expect anyone to take advantage of features put into CLOS precisely
> so folks could use classes and substitute their own options for the
> slots they are inheriting?

Okay, so what are default-initargs for then?

> Has it occurred to you that using a default-initarg prevents them from
> using initform for restated slots?

Yes. Seems like that's the point.

> >>You should be using :initform in the above real world example (on
> >>any world named World <g>).
> > Why? Doesn't that just make it harder to write INITIALIZE-INSTANCE?
> 
> how?

  (defclass foo ()
    ((slot :initarg :slot :accessor derived-slot :initform 10)
     (derived-slot :accessor derived-slot)))

  (defmethod initialize-instance :after ((obj foo) &key slot &allow-other-keys)
    (setf (derived-slot obj) (* 2 slot)))


  * (make-instance 'foo :slot 10)
  #<FOO @ #x7235a102>
  * (make-instance 'foo)
  Error: `NIL' is not of the expected type `NUMBER'
    [condition type: TYPE-ERROR]

  Restart actions (select using :continue):
   0: Return to Debug Level 1 (an "abort" restart).
   1: Return to Top Level (an "abort" restart).
   2: Abort entirely from this process.


versus:

  (defclass foo ()
    ((slot :initarg :slot :accessor derived-slot)
     (derived-slot :accessor derived-slot))
    (:default-initargs :slot 10))

  * (make-instance 'foo :slot 10)
  #<FOO @ #x72378002>
  * (make-instance 'foo)
  #<FOO @ #x7237791a>


Obviously, if you write the INITIALIZE-INSTANCE method to pull the
value off the object rather than using the keyword argument to
INITIALIZE-INSTANCE you're okay. Is that how you write it?

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Kenny Tilton
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <Otrcb.16607$nU6.3704060@twister.nyc.rr.com>
Peter Seibel wrote:
> Kenny Tilton <·······@nyc.rr.com> writes:
> 
> 
>>Peter Seibel wrote:
>>
>>
>>>>ps. default-initargs are for slots defined in a superclass and not
>>>>restated in the class being defined.
>>>
>>>That's my point--these two classes each defined slots, with no
>>>expectation that they would be (or would need to be) "restated",
>>
>>You're joking, right? You are so worried about this issue that you
>>will use unexported symbols for initargs, yet you will use
>>default-initarg where you should use initform because you do not
>>expect anyone to take advantage of features put into CLOS precisely
>>so folks could use classes and substitute their own options for the
>>slots they are inheriting?
> 
> 
> Okay, so what are default-initargs for then?

I've taken the liberty of making your code a little more self-documenting:

(defclass class ()
    ((slot :accessor accessor :initarg initarg)))

(defclass c1ass (class)
    ()
    (:default-initarg initarg :initarg))

(defclass elass (class)
    ()
    (:default-initarg initarg :imtarg))

(defclass e1ass (c1ass elass)())

(accessor (make-instance 'class))
=> :initarg

(not tested)

ie, it is how (a) one specifies a value all instances of a subclass 
should have for an inherited slot such that one wins over any less 
specific class in the CPL that might have specified a default-initarg. 
This is in the context, mind you, where everyone intends for all the 
slots named slot to be the slot slot.

:)


>>>>You should be using :initform in the above real world example (on
>>>>any world named World <g>).
>>>
>>>Why? Doesn't that just make it harder to write INITIALIZE-INSTANCE?
>>
>>how?
> 
> 
>   (defclass foo ()
>     ((slot :initarg :slot :accessor derived-slot :initform 10)
>      (derived-slot :accessor derived-slot)))
> 
>   (defmethod initialize-instance :after ((obj foo) &key slot &allow-other-keys)
>     (setf (derived-slot obj) (* 2 slot)))

ha-ha, you got me, I thought I could read a line of two or Lisp pretty 
well, but that example is so fucked up I actually had to run it and 
stare at it /and!!!/ poke around in the backtrace before I realized the 
depth to which you had sunk to make things appear broken. Good one!

So the semantics of derived-slot are not that it is twice the value of 
the slot slot, but twice the value of the initarg (default or to 
make-instance) supplied for slot? Why don't you also divide by the line 
number at which the make-instance form appears in the source? Then you'd 
have a point.

There is a reason no one specializes (initialize-instance :before), you 
know.  The correct code (is:

       ..... (* 2 (slot-value obj 'slot))

Lame effort, btw, reusing the accessor name to screen me from using the 
slot value instead of the initarg value. I see the gloves are really off 
now. :)

kenny
From: Peter Seibel
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <m3vfrhej80.fsf@javamonkey.com>
Kenny Tilton <·······@nyc.rr.com> writes:

> Peter Seibel wrote:
> > Kenny Tilton <·······@nyc.rr.com> writes:
> >
> >>Peter Seibel wrote:
> >>
> >>
> >>>>ps. default-initargs are for slots defined in a superclass and not
> >>>>restated in the class being defined.
> >>>
> >>>That's my point--these two classes each defined slots, with no
> >>>expectation that they would be (or would need to be) "restated",
> >>
> >>You're joking, right? You are so worried about this issue that you
> >>will use unexported symbols for initargs, yet you will use
> >>default-initarg where you should use initform because you do not
> >>expect anyone to take advantage of features put into CLOS precisely
> >>so folks could use classes and substitute their own options for the
> >>slots they are inheriting?
> > Okay, so what are default-initargs for then?
> 
> I've taken the liberty of making your code a little more self-documenting:
> 
> (defclass class ()
>     ((slot :accessor accessor :initarg initarg)))
> 
> (defclass c1ass (class)
>     ()
>     (:default-initarg initarg :initarg))
> 
> (defclass elass (class)
>     ()
>     (:default-initarg initarg :imtarg))
> 
> (defclass e1ass (c1ass elass)())
> 
> (accessor (make-instance 'class))
> => :initarg
> 
> (not tested)
> 
> ie, it is how (a) one specifies a value all instances of a subclass
> should have for an inherited slot such that one wins over any less
> specific class in the CPL that might have specified a default-initarg.
> This is in the context, mind you, where everyone intends for all the
> slots named slot to be the slot slot.
> 
> :)
> 
> 
> >>>>You should be using :initform in the above real world example (on
> >>>>any world named World <g>).
> >>>
> >>>Why? Doesn't that just make it harder to write INITIALIZE-INSTANCE?
> >>
> >>how?
> >   (defclass foo ()
> >     ((slot :initarg :slot :accessor derived-slot :initform 10)
> >      (derived-slot :accessor derived-slot)))
> >   (defmethod initialize-instance :after ((obj foo) &key slot
> > &allow-other-keys)
> >     (setf (derived-slot obj) (* 2 slot)))
> 
> ha-ha, you got me, I thought I could read a line of two or Lisp pretty
> well, but that example is so fucked up I actually had to run it and
> stare at it /and!!!/ poke around in the backtrace before I realized
> the depth to which you had sunk to make things appear broken. Good one!

Ah crumb. That is pretty funny. Unfortunately I didn't mean to do
that. Giving them both the same accessor was a total thinko. I
actually wasn't trying to confuse you. Not that you're likely to
believe that now.

> So the semantics of derived-slot are not that it is twice the value of
> the slot slot, but twice the value of the initarg (default or to
> make-instance) supplied for slot? Why don't you also divide by the
> line number at which the make-instance form appears in the source?
> Then you'd have a point.

I'm sure I'm past any hope of redemption with you, but my point was
simply that if you wanted to use keyword arguments in
INITIALIZE-INSTANCE. Here's another shot at. And as a token of my good
will I'll stop using SLOT as a slot name:

  (defclass foo ()
    ((bar :initarg :bar :accessor bar :initform 10)
     (baz :accessor baz)))

  CL-USER(720): (defmethod initialize-instance :after ((obj foo) &key bar &allow-other-keys)
                  (setf (baz obj) (* 2 bar)))
  #<STANDARD-METHOD INITIALIZE-INSTANCE :AFTER (FOO)>
  CL-USER(721): (make-instance 'foo)
  Error: `NIL' is not of the expected type `NUMBER'
    [condition type: TYPE-ERROR]

  Restart actions (select using :continue):
   0: Return to Top Level (an "abort" restart).
   1: Abort entirely from this process.
  [1] CL-USER(722): 

> There is a reason no one specializes (initialize-instance :before),
> you know.  The correct code (is:
> 
>        ..... (* 2 (slot-value obj 'slot))

But I used :after.

> Lame effort, btw, reusing the accessor name to screen me from using
> the slot value instead of the initarg value. I see the gloves are
> really off now. :)

Actually my gloves just slipped off. Oops.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Kenny Tilton
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <rLscb.17119$nU6.3738570@twister.nyc.rr.com>
Peter Seibel wrote:

> Kenny Tilton <·······@nyc.rr.com> writes:
> 
> 
>>Peter Seibel wrote:
>>
>>>Kenny Tilton <·······@nyc.rr.com> writes:
>>>
>>>
>>>>Peter Seibel wrote:
>>>>
>>>>
>>>>
>>>>>>ps. default-initargs are for slots defined in a superclass and not
>>>>>>restated in the class being defined.
>>>>>
>>>>>That's my point--these two classes each defined slots, with no
>>>>>expectation that they would be (or would need to be) "restated",
>>>>
>>>>You're joking, right? You are so worried about this issue that you
>>>>will use unexported symbols for initargs, yet you will use
>>>>default-initarg where you should use initform because you do not
>>>>expect anyone to take advantage of features put into CLOS precisely
>>>>so folks could use classes and substitute their own options for the
>>>>slots they are inheriting?
>>>
>>>Okay, so what are default-initargs for then?
>>
>>I've taken the liberty of making your code a little more self-documenting:
>>
>>(defclass class ()
>>    ((slot :accessor accessor :initarg initarg)))
>>
>>(defclass c1ass (class)
>>    ()
>>    (:default-initarg initarg :initarg))
>>
>>(defclass elass (class)
>>    ()
>>    (:default-initarg initarg :imtarg))
>>
>>(defclass e1ass (c1ass elass)())
>>
>>(accessor (make-instance 'class))
>>=> :initarg
>>
>>(not tested)
>>
>>ie, it is how (a) one specifies a value all instances of a subclass
>>should have for an inherited slot such that one wins over any less
>>specific class in the CPL that might have specified a default-initarg.
>>This is in the context, mind you, where everyone intends for all the
>>slots named slot to be the slot slot.
>>
>>:)
>>
>>
>>
>>>>>>You should be using :initform in the above real world example (on
>>>>>>any world named World <g>).
>>>>>
>>>>>Why? Doesn't that just make it harder to write INITIALIZE-INSTANCE?
>>>>
>>>>how?
>>>
>>>  (defclass foo ()
>>>    ((slot :initarg :slot :accessor derived-slot :initform 10)
>>>     (derived-slot :accessor derived-slot)))
>>>  (defmethod initialize-instance :after ((obj foo) &key slot
>>>&allow-other-keys)
>>>    (setf (derived-slot obj) (* 2 slot)))
>>
>>ha-ha, you got me, I thought I could read a line of two or Lisp pretty
>>well, but that example is so fucked up I actually had to run it and
>>stare at it /and!!!/ poke around in the backtrace before I realized
>>the depth to which you had sunk to make things appear broken. Good one!
> 
> 
> Ah crumb. That is pretty funny. Unfortunately I didn't mean to do
> that. Giving them both the same accessor was a total thinko. I
> actually wasn't trying to confuse you. Not that you're likely to
> believe that now.

Oh, no, that was my first take, that it was a typo. But then when I went 
to correct your code and saw I could not use the accessor, I figured you 
were just paying me back for taking the example out of context last time. :)

> 
> 
>>So the semantics of derived-slot are not that it is twice the value of
>>the slot slot, but twice the value of the initarg (default or to
>>make-instance) supplied for slot? Why don't you also divide by the
>>line number at which the make-instance form appears in the source?
>>Then you'd have a point.
> 
> 
> I'm sure I'm past any hope of redemption with you, but my point was
> simply that if you wanted to use keyword arguments in
> INITIALIZE-INSTANCE. Here's another shot at. And as a token of my good
> will I'll stop using SLOT as a slot name:
> 
>   (defclass foo ()
>     ((bar :initarg :bar :accessor bar :initform 10)
>      (baz :accessor baz)))
> 
>   CL-USER(720): (defmethod initialize-instance :after ((obj foo) &key bar &allow-other-keys)
>                   (setf (baz obj) (* 2 bar)))
>   #<STANDARD-METHOD INITIALIZE-INSTANCE :AFTER (FOO)>
>   CL-USER(721): (make-instance 'foo)
>   Error: `NIL' is not of the expected type `NUMBER'
>     [condition type: TYPE-ERROR]
> 
>   Restart actions (select using :continue):
>    0: Return to Top Level (an "abort" restart).
>    1: Abort entirely from this process.
>   [1] CL-USER(722): 

OK, I guess my wisecrack about the line number was too obscure. It is 
simply insane to think that somehow:

     (setf (baz obj) (* 2 (bar obj)))

...would not be correct. It would mean that the semantics of baz depend 
on WHERE THE VALUE BAR CAME FROM!!!!!

"OK, let's see, if we get an initarg for BAR at make-instance time (or 
via default-initarg, of course) then we want baz to be twice it. But we 
don't any truck with the value in the slot, so we'll fall over if ..."

  AFLAC!!!!!

The major premise here is that this language lawyer stuff is tiresome 
unless it maps onto plausible use of the language. The example I gave a 
few laughs back was that, yeah, the CPL algorithm of CLOS is broken, and 
if I ran the circus I'd have everyone change theirs tomorrow just to 
flush out some really godforsaken OO design. Then there'd be an option 
they could specify to get the old algorithm.

> 
> 
>>There is a reason no one specializes (initialize-instance :before),
>>you know.  The correct code (is:
>>
>>       ..... (* 2 (slot-value obj 'slot))
> 
> 
> But I used :after.

Yes, yes, again I was too terse. The reason we do not do :before methods 
is that those would run before shared-initialize (abandon all hope ye 
who go there), after which initforms and initargs default or otherwise 
are in place and you can (and should) use the slot values.

kenny
From: Peter Seibel
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <m3r825ed6p.fsf@javamonkey.com>
Kenny Tilton <·······@nyc.rr.com> writes:

> > I'm sure I'm past any hope of redemption with you, but my point was
> > simply that if you wanted to use keyword arguments in
> > INITIALIZE-INSTANCE. Here's another shot at. And as a token of my good
> > will I'll stop using SLOT as a slot name:
> >   (defclass foo ()
> >     ((bar :initarg :bar :accessor bar :initform 10)
> >      (baz :accessor baz)))
> >   CL-USER(720): (defmethod initialize-instance :after ((obj foo)
> > &key bar &allow-other-keys)
> >                   (setf (baz obj) (* 2 bar)))
> >   #<STANDARD-METHOD INITIALIZE-INSTANCE :AFTER (FOO)>
> >   CL-USER(721): (make-instance 'foo)
> >   Error: `NIL' is not of the expected type `NUMBER'
> >     [condition type: TYPE-ERROR]
> >   Restart actions (select using :continue):
> >    0: Return to Top Level (an "abort" restart).
> >    1: Abort entirely from this process.
> >   [1] CL-USER(722):
> 
> OK, I guess my wisecrack about the line number was too obscure. It is
> simply insane to think that somehow:
> 
>      (setf (baz obj) (* 2 (bar obj)))
> 
> ...would not be correct. It would mean that the semantics of baz
> depend on WHERE THE VALUE BAR CAME FROM!!!!!
> 
> "OK, let's see, if we get an initarg for BAR at make-instance time (or
> via default-initarg, of course) then we want baz to be twice it. But
> we don't any truck with the value in the slot, so we'll fall over if
> ..."

Okay. I actually just brought this up because of something I read at 

 <http://www.cs.northwestern.edu/academics/courses/325/readings/graham/chap11-notes.html>

which someone posted earlier today. It seems seems to a be an
otherwise good set of notes on Graham's _ANSI Common Lisp_. But maybe
I need to go back over it all with a bit more of a critical eye. (He
claims that :default-initargs are more commonly used than :initform
for the reson I tried to demonstrate here.) But you've convinced me,
he's probably misguided. (Unless of course one *did* want to write
before methods on INITIALIZE-INSTANCE.)

(I think it struck me as being relevant to this discussion because it
seemed that your original argument in favor of using keywords initargs
was that it was easier to then use them as keyword parameters to
INITIALIZE-INSTANCE. But that might have been a hasty leap from your
original point.)

>   AFLAC!!!!!

?

> The major premise here is that this language lawyer stuff is
> tiresome unless it maps onto plausible use of the language. The
> example I gave a few laughs back was that, yeah, the CPL algorithm
> of CLOS is broken, and if I ran the circus I'd have everyone change
> theirs tomorrow just to flush out some really godforsaken OO design.
> Then there'd be an option they could specify to get the old
> algorithm.

So I admit that I'm a bit of a language lawyer but I'm more like a
trial lawyer--I want to win cases, i.e. successfully write software. I
want to know what's possible/legal (that's the language lawyer bit) so
I have the full range of options at my disposal; I don't want to be
trapped into doing what's customary just because I didn't realize
there was another option that could have kept me out of (bad software)
jail.

From my point of view you still haven't given me a good reason why you
*want* to use keywords as your initargs rather than symbols. Yes, I
understand you *can* sort out the potential name conflict by restating
the slots but is there an advantage to everyone using symbols in the
same package, increasing the chance of a name conflict and thus the
need to restate slots that otherwise wouldn't have a problem
coexisting.

I'm happy to agree that this kind of name conflict is unlikely to
arise frequently, particularly if one is using good design sense. And
I'm even happy to agree that given that and given weight of custom in
favor of using keyword initargs that it's the best thing to do--they
payoff (avoiding potential but rare name conflicts) may just no be
worth the cost (bucking the tide of convention).

But that's different than there being a strong reason to reason to
favor keywords. Anyway, like I said originally, I didn't make up this
idea--I came across it in one of the old posts of one of our Wise
Elders; I was hoping that someone--maybe the Elder himself--would say,
yeah, that seemed like a good idea until I really tried it and then it
turned out to be a disaster for the following reasons. Or, yup--I
decided that was a good idea and I've been using it for the past N
years with great success. Or even, no you dolt, that's not what I
meant.

But thanks for all your, er, friendly feedback. ;-)

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Kenny Tilton
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <e1Bcb.13628$lZ6.4014341@twister.nyc.rr.com>
Peter Seibel wrote:
> Kenny Tilton <·······@nyc.rr.com> writes:
> 
> Okay. I actually just brought this up because of something I read at 
> 
>  <http://www.cs.northwestern.edu/academics/courses/325/readings/graham/chap11-notes.html>

Where Chris Riesbeck concluded:
> Note that we could define the after method on initialize-instance to work with either class definition as follows:
> 
> (defmethod initialize-instance :after 
>            ((c circle) &rest args)
>   (setf (circle-area c) 
>         (* pi (circle-radius c) (circle-radius c))))

Yes!!

> This definition has two disadvantages:

uh-oh.

>     * It's slightly more costly to access a slot than a keyword value.

"slightly more costly to access a slot"? oh, my. where do I begin?

Mr. Riesbeck continued:
>     * It doesn't generalize to before methods, where the slots haven't been created yet. 

No they haven't, have they? So what the %^$#& would I be doing working 
on the instance before it has been through shared initialize?!

Well, it means I do not accept initforms and initargs as sufficient to 
author a new instance. If I do, I could let the instance be formed and 
/then/ extend the initialization with computations which can "see" other 
slots (yes, via the heavy-lifting of slot-value <sigh>) and even, say if 
a "parent" slot was one of the slots, an entire family tree into which 
an instance is being installed.

The only reason to look at the runtime initargs is if one wants to 
ensure something about the authoring itself, or to facilitate the 
authoring in some way. In the CliniSys app one is permitted to specify a 
NULL "luw" slot for instances in the perisstent CLOS ODB, but we do not 
want that to happen by accident, so we check luw-supplied-p (the second 
optional value for a keyword param).

I also managed to use Cells with the persistent CLOS ODB, but one does 
not want Cell structures bouncing thru the slot over to an 
implementation-internal slot with an assoc for all Cells as usually 
happens because the persistent ODB does Interesting Things when it sees 
a value hit a persistent slot. So I used an /around/ method to head off 
Cells arriving as initargs and then call-next-method with the argument 
list showing nothing for the persistent slot and a new assoc for the 
internals slot.

>>  AFLAC!!!!!
> 
> 
> ?

Priceless series of TV commercials in which a duck walks around trying 
in vain to tell people about a product that solves the problem they are 
discussing. Parallel to my frustration imprecise.

> trial lawyer--I want to win cases, i.e. successfully write software. I
> want to know what's possible/legal (that's the language lawyer bit) so
> I have the full range of options at my disposal; 

Yes, :initarg <symbol> is valid. So is :initarg nil. I wonder what that 
does. NOP?

> I don't want to be
> trapped into doing what's customary just because I didn't realize
> there was another option that could have kept me out of (bad software)
> jail.

This is where I need a plausible example of how to land in jail with 
keyword initargs.

> 
> From my point of view you still haven't given me a good reason why you
> *want* to use keywords as your initargs rather than symbols. 

You like (make-instance 'landscape 'tell 'trees 'from 'forest)?

Yes, I
> understand you *can* sort out the potential name conflict by restating
> the slots but is there an advantage to everyone using symbols in the
> same package, increasing the chance of a name conflict ...

AFLAC!! Is it hte chance I have of running afoul of the CPL flaw? 
(That's my answer in the form of a question.)

and thus the
> need to restate slots that otherwise wouldn't have a problem
> coexisting.

And there /is/ a workaround even if it comes up, which it won't since no 
one is offering a plausible example.

> 
> I'm happy to agree that this kind of name conflict is unlikely to
> arise frequently, particularly if one is using good design sense. And
> I'm even happy to agree that given that and given weight of custom in
> favor of using keyword initargs that it's the best thing to do--they
> payoff (avoiding potential but rare name conflicts) may just no be
> worth the cost (bucking the tide of convention).

Yes, that is a fair statement of my position.

> 
> But that's different than there being a strong reason to reason to
> favor keywords. 

(a) well, in the end, I really am just having fun in this thread

(b) I think readability and custom matter a lot, more than most, and 
certainly enough to put the burden of proof on someone intending to 
avail themself of this eminently legal feature.

> But thanks for all your, er, friendly feedback. ;-)

Sorry for not using enough smileys and coming across as seriously 
antagonistic. Burdick is the one I am really after.

:)

kenny
From: Thomas F. Burdick
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <xcvvfrgvco3.fsf@famine.OCF.Berkeley.EDU>
Kenny Tilton <·······@nyc.rr.com> writes:

> Peter Seibel wrote:
>
> > But thanks for all your, er, friendly feedback. ;-)
> 
> Sorry for not using enough smileys and coming across as seriously 
> antagonistic. Burdick is the one I am really after.
> 
> :)

Hey, good timing.  The power's on, the weather's cool (so it's likely
to stay on), and I dug up the example I promised.

First, the context.  After spending lots and lots of time discussion
the problem that Testa tries to solve, we (my research partner Eddy
and I) ended out with something of a specialized vocabulary when
talking among ourselves about the problem.  We had several precise,
well-defined terms with names that seem generic to outside observers:
eg, "chunk".  We toyed with calling "chunk" "upsilon", or "aleph" or
something, but went with "chunk" because we're American, and quite
that mathy..

We have a MACHO package, which parses Mach-O object files (with much
machismo, naturally).  One class this package exports is
macho:chunk.  Another package, IR (intermediate representation),
contains a class ir:cps-function.  Chunks contain one or more
CPS-functions, so the ir:cps-function class contains a pointer to its
containing chunk, and calls this slot (not surprisingly), CHUNK.  You
call the accessor method IR:CHUNK to coerce something into a chunk,
whether the thing you're coercing is a chunk, or something like a
cps-function, in which case you'll get the appropriate CHUNK.  I wrote
the IR package, and Eddy wrote the MACHO package.

When writing the SOURCE-TO-IR package together, we made a class that
is only used internally to that package, which inherits from both
MACHO:MACHO-FILE (the parser class), and IR:CPS-FUNCTION.  The
SOURCE-TO-IR package doesn't use-package MACHO nor IR.  We happily
used the MACHO:CHUNK accessor to get the chunk (in the Mach-O parsing
sense) from the object, and the IR:CHUNK function to get the chunk (in
the IR sense).  If we were handling both in one function, we'd
obviously keep them in non-confusingly named variables like
macho-chunk, or ir-chunk.

The class heirarchy was fine, and the design worked just fine.  We
didn't fine the use of "chunk" confusing at the time, nor later when
going back over the code.  If we had used keyword initargs, we would
have created an unnecessary namespacing problem.

> This is where I need a plausible example of how to land in jail with 
> keyword initargs.

There you go, not only plausible, but real, in actual, running code.

> > From my point of view you still haven't given me a good reason why you
> > *want* to use keywords as your initargs rather than symbols. 
> 
> You like (make-instance 'landscape 'tell 'trees 'from 'forest)?

Wow, you're really into symbol processing -- you actually initialize
instances with most slots set to a constant set of symbols?  I don't
suppose you ever use keywords, do you ...

(make-instance 'landscape :tell :trees :from :forest)?

I find myself generally doing something more like:

  (let* ((trees (find-some-trees ...))
         (forest (forest-containing-trees trees)))
    (make-instance 'landscape 'tell trees 'from forest))

I look at the arguments to MAKE-INSTANCE as being
(class &rest plist &key &allow-other-keys).

> > But that's different than there being a strong reason to reason to
> > favor keywords. 
> 
> (a) well, in the end, I really am just having fun in this thread

(*shock*!)

> (b) I think readability and custom matter a lot, more than most, and 
> certainly enough to put the burden of proof on someone intending to 
> avail themself of this eminently legal feature.

I don't see any sacrifice to readability in using the same symbol for
slot names and slot initargs.  As for it being a break with custom --
I think that using keywords is the dominant custom, but I first saw
non-keyword symbol being used in Lisp code, not any essay or post --
so it's probably a living minority custom.  Fortunately, partisans of
both customs can read eachothers' code without problems, and even use
it, with some slight potential for problems with mixins in the case of
a certain group's code ;-)

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Kenny Tilton
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <aZLcb.16438$lZ6.4202525@twister.nyc.rr.com>
Thomas F. Burdick wrote:

> Kenny Tilton <·······@nyc.rr.com> writes:
> 
> 
>>Peter Seibel wrote:
>>
>>
>>>But thanks for all your, er, friendly feedback. ;-)
>>
>>Sorry for not using enough smileys and coming across as seriously 
>>antagonistic. Burdick is the one I am really after.
>>
>>:)
> 
> 
> Hey, good timing.  The power's on, the weather's cool (so it's likely
> to stay on), and I dug up the example I promised.
> 
> First, the context.  After spending lots and lots of time discussion
> the problem that Testa tries to solve, we (my research partner Eddy
> and I) ended out with something of a specialized vocabulary when
> talking among ourselves about the problem.  We had several precise,
> well-defined terms with names that seem generic to outside observers:
> eg, "chunk".  We toyed with calling "chunk" "upsilon", or "aleph" or
> something, but went with "chunk" because we're American, and quite
> that mathy..
> 
> We have a MACHO package, which parses Mach-O object files (with much
> machismo, naturally).  One class this package exports is
> macho:chunk.  Another package, IR (intermediate representation),
> contains a class ir:cps-function.  Chunks contain one or more
> CPS-functions, so the ir:cps-function class contains a pointer to its
> containing chunk, and calls this slot (not surprisingly), CHUNK.  You
> call the accessor method IR:CHUNK to coerce something into a chunk,

uh-oh. coerce? you do not mean the the Lisp coerce, do you? Besides, I 
am thinking the IR:CHUNK accessor /reads/ a slot. Returning nil or a 
chunk. What do you do, a JIT chunk creation? I'm lost.

> whether the thing you're coercing is a chunk, or something like a
> cps-function, in which case you'll get the appropriate CHUNK.

I need a lot of help with this coercing business.

   I wrote
> the IR package, and Eddy wrote the MACHO package.
> 
> When writing the SOURCE-TO-IR package together, we made a class that
> is only used internally to that package, which inherits from both
> MACHO:MACHO-FILE (the parser class), and IR:CPS-FUNCTION.  The
> SOURCE-TO-IR package doesn't use-package MACHO nor IR.  We happily
> used the MACHO:CHUNK accessor ...

What macho:chunk accessor? I only know about a macho::chunk class. The 
room is getting dark...

to get the chunk (in the Mach-O parsing
> sense) from the object, and the IR:CHUNK function to get the chunk (in
> the IR sense).  

macho:chunk parses an object and /computes/ a chunk? The 
source-to-ir:whatever class has points to two chunks? Does IR use Macho? 
I think you are going to win this argument.


>... If we were handling both in one function, we'd
> obviously keep them in non-confusingly named variables like
> macho-chunk, or ir-chunk.
> 
> The class heirarchy was fine, and the design worked just fine.  We
> didn't fine the use of "chunk" confusing at the time, nor later when
> going back over the code.  If we had used keyword initargs, we would
> have created an unnecessary namespacing problem.
> 
> 
>>This is where I need a plausible example of how to land in jail with 
>>keyword initargs.
> 
> 
> There you go, not only plausible, but real, in actual, running code.

That does not prove anything. One can create a real class with 
counter-intuitive behavior that exposes the flaw in the CPL algorithm. 
But my bet is that that hierarchy would be a lousy one and that fixing 
it would also elim the counter-intuitive inheritance.

Anyway, I did not see how the unnamed internal class got two chunks (if 
it did!)


> 
> 
>>>From my point of view you still haven't given me a good reason why you
>>>*want* to use keywords as your initargs rather than symbols. 
>>
>>You like (make-instance 'landscape 'tell 'trees 'from 'forest)?
> 
> 
> Wow, you're really into symbol processing -- you actually initialize
> instances with most slots set to a constant set of symbols?  I don't
> suppose you ever use keywords, do you ...
> 
> (make-instance 'landscape :tell :trees :from :forest)?

Just once, I think, and boy was it confusing to look at.

kenny
From: Thomas F. Burdick
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <xcv65jg2i7a.fsf@famine.OCF.Berkeley.EDU>
Kenny Tilton <·······@nyc.rr.com> writes:

> What do you do, a JIT chunk creation? I'm lost.

Yeah, sorry, I should have mentioned that.  We decided that using a
push-based dataflow sucked.  So we made everything work so that you
could create a minimal structure, and start pulling on things -- you
access them if they exist, or they're created otherwise.  So if an
IR:CPS-FUNCTION already has an IR:CHUNK associated with it, you get
that -- otherwise, it's created.  Judicious comments like "need to
make sure any other CPS-FUNCTIONs that should see this CHUNK, do" keep
you from breaking code later, and give you tons of freedom when using
the interface.  Plus, we got a reduction in algorithmic complexity (we
only compute things we need).

> What macho:chunk accessor? I only know about a macho::chunk class. The 
> room is getting dark...

Hmm, lemme try again, using more pseudocode, and less prose:

  (in-package :macho)
  (export '(chunk parser ...))

  (defclass chunk ...)

  (defclass parser (...)
    ((chunk :initarg chunk :accessor chunk) ...))



  (in-package :ir)

  (defclass chunk ...)

  (defgeneric chunk (thing)
    (:documentation
      "Return a CHUNK.  If given a chunk, return it.  Otherwise, find the chunk
  associated with THING, creating it if needed, and return it."))

  (defclass cps-function (...)
    ((chunk :initarg chunk :accessor chunk) ...))

  (defmethod chunk :around ((thing cps-function))
    (if (slot-boundp thing 'chunk)
      (call-next-method)
      #| find or create CHUNK for THING |# ...))



  (in-package :source-to-ir)

  (defclass cps-constructor (macho:parser ir:cps-function ...) ...)

> I think you are going to win this argument.

I knew that from the start ;-)

> > The class heirarchy was fine, and the design worked just fine.  We
> > didn't fine the use of "chunk" confusing at the time, nor later when
> > going back over the code.  If we had used keyword initargs, we would
> > have created an unnecessary namespacing problem.
 [...]
> > There you go, not only plausible, but real, in actual, running code.
> 
> That does not prove anything. One can create a real class with 
> counter-intuitive behavior that exposes the flaw in the CPL algorithm. 
> But my bet is that that hierarchy would be a lousy one and that fixing 
> it would also elim the counter-intuitive inheritance.

Ahem, I see you're ignoring my assertion that what I did was
reasonable, not counterintuitive.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Kenny Tilton
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <CwWcb.44780$u67.3323@twister.nyc.rr.com>
Thomas F. Burdick wrote:

> Kenny Tilton <·······@nyc.rr.com> writes:
> 
> 
>>What do you do, a JIT chunk creation? I'm lost.
> 
> 
> Yeah, sorry, I should have mentioned that.  We decided that using a
> push-based dataflow sucked.  So we made everything work so that you
> could create a minimal structure, and start pulling on things -- you
> access them if they exist, or they're created otherwise.  So if an
> IR:CPS-FUNCTION already has an IR:CHUNK associated with it, you get
> that -- otherwise, it's created. 

You need Cells. (I am going to implement a lazy evaluation option today.)

  Judicious comments like "need to
> make sure any other CPS-FUNCTIONs that should see this CHUNK, do" keep
> you from breaking code later, and give you tons of freedom when using
> the interface.  Plus, we got a reduction in algorithmic complexity (we
> only compute things we need).
> 
> 
>>What macho:chunk accessor? I only know about a macho::chunk class. The 
>>room is getting dark...
> 
> 
> Hmm, lemme try again, using more pseudocode, and less prose:
> 
>   (in-package :macho)
>   (export '(chunk parser ...))
> 
>   (defclass chunk ...)
> 
>   (defclass parser (...)
>     ((chunk :initarg chunk :accessor chunk) ...))
> 
> 
> 
>   (in-package :ir)
> 
>   (defclass chunk ...)
> 
>   (defgeneric chunk (thing)
>     (:documentation
>       "Return a CHUNK.  If given a chunk, return it.  Otherwise, find the chunk
>   associated with THING, creating it if needed, and return it."))

Here's your problem. The comment. It means you need to fix something. 
(That is what every comment means.) The function should be called 
ENSURE-CHUNK. The accessor should just be an accessor.

Where do I send the invoice for fixing your code? :)

>>I think you are going to win this argument.
> 
> 
> I knew that from the start ;-)

It ain't over till it's over. Why does the parser need a slot for the 
chunk? Didn't anyone tell you Lisp was a functional language? :)

> Ahem, I see you're ignoring my assertion that what I did was
> reasonable, not counterintuitive.

No, I thought that "it runs" was being offered as "sufficient".


Game on!

kenny
From: Thomas F. Burdick
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <xcvbrt7s5ze.fsf@famine.OCF.Berkeley.EDU>
Kenny Tilton <·······@nyc.rr.com> writes:

> Thomas F. Burdick wrote:
> 
> > Kenny Tilton <·······@nyc.rr.com> writes:
> > 
> >>What do you do, a JIT chunk creation? I'm lost.

[ For the record, the above line is Kenny "Mr Dataflow" Tilton being
  confused by the idea of reversing the ordinary path of dataflow. ]

> > Yeah, sorry, I should have mentioned that.  We decided that using a
> > push-based dataflow sucked.  So we made everything work so that you
> > could create a minimal structure, and start pulling on things -- you
> > access them if they exist, or they're created otherwise.  So if an
> > IR:CPS-FUNCTION already has an IR:CHUNK associated with it, you get
> > that -- otherwise, it's created. 
> 
> You need Cells. (I am going to implement a lazy evaluation option today.)

When we made the switch I was thinking, "*damn* I could use KR or
Cells or something here."  But there's always something to be said for
not overwhelming your fresh-from-C++ research partner with too many
new language constructs at once.  (And it works, he's now a
card-carrying CLOS and CL bigot).

> >   (defgeneric chunk (thing)
> >     (:documentation
> >       "Return a CHUNK.  If given a chunk, return it.  Otherwise, find the chunk
> >   associated with THING, creating it if needed, and return it."))
> 
> Here's your problem. The comment. It means you need to fix something. 
> (That is what every comment means.) The function should be called 
> ENSURE-CHUNK. The accessor should just be an accessor.

I always put docstrings on my APIs.  Without them, I wouldn't be able
to use my DocoBrowse tool!  The verbosity of that one was for your
benefit, though, I just wrote "Return the appropriate CHUNK." in the
real code.  I suppose it could also be called ENSURE-CHUNK, but we
wanted the consuming code to be able to just treat the structure like
it already exists, and keep all the ENSURE-this, PARSE-that pretty
confined.

> Where do I send the invoice for fixing your code? :)

Just send me any email over 100k, and it'll automatically get send to
/dev/null :)
[ is that virus/worm mostly over yet? ]

> >>I think you are going to win this argument.
> > 
> > I knew that from the start ;-)
> 
> It ain't over till it's over.

Hmm, maybe I should be careful with my ironic arrogance.  (More than
three years after I bought it,) I've been reading _Les particules
�l�mentaires_ by Michel Houellebecq, and I think it's desensitizing me
to arrogance.

> Why does the parser need a slot for the chunk? Didn't anyone tell
> you Lisp was a functional language? :)

They started, but they fainted with horror when I showed them my
all-in-one-big-PROG-form parsers.

> > Ahem, I see you're ignoring my assertion that what I did was
> > reasonable, not counterintuitive.
> 
> No, I thought that "it runs" was being offered as "sufficient".

I see your reading comprehension is matched only by the style of your
code :)

> Game on!

(You just noticed?)

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Kenny Tilton
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <JTkdb.18473$lZ6.4863728@twister.nyc.rr.com>
Thomas F. Burdick wrote:

> Kenny Tilton <·······@nyc.rr.com> writes:
> 
> 
>>Thomas F. Burdick wrote:
>>
>>
>>>Kenny Tilton <·······@nyc.rr.com> writes:
>>>
>>>
>>>>What do you do, a JIT chunk creation? I'm lost.
> 
> 
> [ For the record, the above line is Kenny "Mr Dataflow" Tilton being
>   confused by the idea of reversing the ordinary path of dataflow. ]

For the record, Thomas "Lights Out" Burdick lives on the Left Coast 
where flipping the light switch up does not always make the lights go 
on, but when the light comes on later he notices the switch is always 
up, so he understandably has lost track of the direction of the arrow 
between cause and effect.


> When we made the switch I was thinking, "*damn* I could use KR or
> Cells or something here."  But there's always something to be said for
> not overwhelming your fresh-from-C++ research partner with too many
> new language constructs at once.  (And it works, he's now a
> card-carrying CLOS and CL bigot).

One word:  http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey

> Just send me any email over 100k, and it'll automatically get send to
> /dev/null :)
> [ is that virus/worm mostly over yet? ]

Seems quieter, but still a steady presence. I upgraded Netscape and it 
is a lot handier with spam than the prior version.


kt
From: Rob Warnock
Subject: worms  [was: Re: Using keywords as :initargs? ]
Date: 
Message-ID: <jOucnce84Y7vduiiXTWc-w@speakeasy.net>
Kenny Tilton  <·······@nyc.rr.com> wrote:
+---------------
| Thomas F. Burdick wrote:
| > Just send me any email over 100k, and it'll automatically get send to
| > /dev/null :)
| > [ is that virus/worm mostly over yet? ]
| 
| Seems quieter, but still a steady presence.
+---------------

I'm still getting about 150 MB/day (~1000 copies of the worm) clogging
up my DSL line, admittedly better than the ~250 MB/day I *was* getting.
But a two-line Postfix "header_check" filter is now keeping it out of
my mailbox, at least.

Does nothing for the "backscatter", of course. [Heaping imprecations
upon all of those other stupid mail relays that detect and "clean"
messages of worms but then SEND THEM TO YOU ANYWAY!! (*sheesh!*)]


-Rob

-----
Rob Warnock, PP-ASEL-IA		<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Thomas F. Burdick
Subject: Re: worms  [was: Re: Using keywords as :initargs? ]
Date: 
Message-ID: <xcvzngpzvlg.fsf@famine.OCF.Berkeley.EDU>
····@rpw3.org (Rob Warnock) writes:

> Kenny Tilton  <·······@nyc.rr.com> wrote:
> +---------------
> | Thomas F. Burdick wrote:
> | > Just send me any email over 100k, and it'll automatically get send to
> | > /dev/null :)
> | > [ is that virus/worm mostly over yet? ]
> | 
> | Seems quieter, but still a steady presence.
> +---------------
> 
> I'm still getting about 150 MB/day (~1000 copies of the worm) clogging
> up my DSL line, admittedly better than the ~250 MB/day I *was* getting.
> But a two-line Postfix "header_check" filter is now keeping it out of
> my mailbox, at least.

I wonder if this will eventually mean the end of people hosting their
own mailservers on the small end of a DSL connection.

I should really do something more sophisticated with my attachment
filtering -- like maybe allow attachments from people whom I have a
mail from in one of my boxes.  Look at that -- this came back around
to being vaguely on-topic; I use Emacs/VM, so if anyone wants a copy,
watch gnu.emacs.vm.info, I'll post it when I write it.

> Does nothing for the "backscatter", of course. [Heaping imprecations
> upon all of those other stupid mail relays that detect and "clean"
> messages of worms but then SEND THEM TO YOU ANYWAY!! (*sheesh!*)]

Tell me about it.  SpamAssasin's bayesian filter thinks highly of
them, but for some reason thinks that my homeboys talk like spam
(probably, but it's the other way around!) -- so, it got turned off.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Paolo Amoroso
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <87zngqxctm.fsf@plato.moon.paoloamoroso.it>
Thomas F. Burdick writes:

> Just send me any email over 100k, and it'll automatically get send to
> /dev/null :)
> [ is that virus/worm mostly over yet? ]

Yes, but prepare for the next one.


Paolo
-- 
Paolo Amoroso <·······@mclink.it>
From: Kenny Tilton
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <nTXcb.45759$u67.22187@twister.nyc.rr.com>
Thomas F. Burdick wrote:

>>>The class heirarchy was fine, and the design worked just fine.  We
>>>didn't fine the use of "chunk" confusing at the time, nor later when
>>>going back over the code.

Because you were forever mentally translating between chunk-being-parsed 
(well, OK, I do not know what that slot is because you gave it a 
nickname instead of a proper name) and chunk-to-which-I-belong.

As for your hierarchy being fine, hey, you ended up with a class with 
two slots called chunk with different semantics. Guilty! Guilty! Guilty!

Where is the problem? Could be a lot of places. I have to trust you that 
it makes sense for cps-constructor to be both a parser and cps-function, 
but that is one possible flaw. Using the same name for both 
chunk-being-made and chunk-to-which-I-belong is flat wrong; expose 
semantics in the data name. And the parser probably should not have a 
slot for the chunk it is generating (or modifying or simply being 
steered by parameter-like). If you are generating a chunk:

     (parse-this-bad-boy parser bad-boy)

should return a chunk. If a chunk mediates parsing:

     (parse-this-bad-boy parser bad-boy :ala-chunk this-chunk)

If you don't like passing things around:

     (with-machismo (parser :ala-chunk this-chunk) ;; bind specials here
        ....)

I was wondering why you had so many packages. You are using them to bail 
you out of the consequences of your design.

Tilton's Law: Something like a class ending up with two slots of the 
same name with different semantics is a message from the problem that 
you have made a wrong turn.

Tilton's Law: The difference between a good programmer and a bad 
programmer is how they react when they get a message from the problem. 
If they go forward, such that the message ("dude, you have a class with 
two slots of the same name with different semantics") still holds, that 
is bad. It's like putting black tape over a low-oil indicator when it 
comes on. If they turn back and redo things such that the message simply 
goes away, that is good.

Tilton's Law: When you make the message go away, you will find other 
benefits from the refactoring. You will delete more code than you write. 
Corollary: If you are writing more code than you are deleting, back it 
all out and try again.

kenny
From: Pascal Bourguignon
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <87brtaov17.fsf@thalassa.informatimago.com>
···@famine.OCF.Berkeley.EDU (Thomas F. Burdick) writes:

> "Kenny Tilton" <·······@nyc.rr.com> writes:
> 
> > Peter Seibel wrote in message ...
> >
> > >Dunno about that. It's not crazy to imagine that to independent
> > >developers might both write classes with that contain a slot with a
> > >generic name like, say, 'name'.
> > 
> > Ah, but with different semantics for name? Like, in one case it's the name
> > of the thing, and in the other class it's the thing's name? And we have to
> > keep these same names separate? :)
> 
> Sure, the package system helps you out here.  I know that *you* are a
> big fan of accessor functions (as opposed to using WITH-SLOTS) -- so
> you surely[*] must know that GANG:NAME is one function, and
> GOVERNMENT:NAME is another.  To turn your question around, do you
> really think having two *functions* with the same name, in different
> packages is unreasonable?  Surely[*] not!  So why this sudden infatuation
> with slot names?

Because of  the point OP made:  keywords are not in  the packages GANG
and GOVERNMENT, but in the package KEYWORD.  So you cannot distinguish
an initarg keyword of one package from the same of another package.

So OP suggested the use of:

(defclass government:government (entity:entity)
  (
    (name :accessor name ;; no problem here, it's government:name
          :initarg 'name ;; instead of :name, to keep it as government:name
                         ;; rather than keyword:name
    ))
  ())

(defclass gang:gang (entity:entity)
  (
    (name :accessor name ;; no problem here, it's gang:name
          :initarg 'name ;; instead of :name, to keep it as gang:name
                         ;; rather than keyword:name
    ))
  ())

That way, it's not possible to write:

(defclass bushgov:bushgov (government:government  gang:gang)
    ()
    ())

and:

(make-instance 'bushgov:bushgov 
        'gang:name       "The Liar King"
        'government:name "White Face")


> To access someone's Gang:Name, I use (duh) Gang:Name.  To access
> someone's government name, I use Government:Name.  That's a
> perfectly alright class hierarchy, right?  I thought so.

What do you mean? You want to use DEFUN functions rather than methods,
ie.  generic  functions  declared  with DEFGENERIC  and  defined  with
DEFMETHOD?  How coarse!


Clearly, when programming in OO, you have a NAME generic function that
you can apply on whatever object:

(list (NAME MrPresident) (NAME Boss) (NAME Chief))

 
> So why you gotta go and screw everything up with weird initargs?

Initargs work only in MAKE-INSTANCE.  Think about MAKE-INSTANCE rather
than about functions!

 
> > btw, no reaction to my demonstration that the conflict can be avoided by
> > restating the slots in the inheriting class?
> 
> If you call MAKE-INSTANCE on a class object (not just a class name),
> you can allow instances of a subclass there, too.  If your call passes
> in an initarg for :x, then the :foo-x/:bar-x thing won't work.

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
From: Thomas F. Burdick
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <xcvsmmkvch1.fsf@famine.OCF.Berkeley.EDU>
[ I think I may not have been communicating at my best when I wrote
the post you replied to.  I was attempting to be a partisan of the
school that does not use keywords for initargs ]

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

> What do you mean? You want to use DEFUN functions rather than methods,
> ie.  generic  functions  declared  with DEFGENERIC  and  defined  with
> DEFMETHOD?  How coarse!

No no, by "accessor functions", I mean the ones that are created by
using DEFCLASS.  They're generic functions, that you can add methods
to.

> Clearly, when programming in OO, you have a NAME generic function that
> you can apply on whatever object:
> 
> (list (NAME MrPresident) (NAME Boss) (NAME Chief))
> 
>  
> > So why you gotta go and screw everything up with weird initargs?
> 
> Initargs work only in MAKE-INSTANCE.  Think about MAKE-INSTANCE rather
> than about functions!

I know.  I'm saying that you have a certain attribute of a class,
named FOO:BAR.  You access it with an accessor function named FOO:BAR,
or possibly you do (with-slots (foo:bar ...) object ...).  Suddenly,
when referring to it in calls to MAKE-INSTANCE, its name gets changed
to KEYWORD:BAR!!!

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Joe Marshall
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <1xu7wiz9.fsf@ccs.neu.edu>
Peter Seibel <·····@javamonkey.com> writes:

> While reading through some old c.l.l. posts on Google I saw someone
> speculating that it might be a good coding style to *not* use keywords
> as the :initargs in DEFCLASS forms.
>
> I.e. prefer this:
>
>   (defclass foo ()
>     ((some-slot :initarg some-slot)))
>
>   (make-instance 'foo 'some-slot 10)
>
> to this:
>
>   (defclass foo ()
>     ((some-slot :initarg :some-slot)))
>
>   (make-instance 'foo :some-slot 10)
>
> The reason, as I understood it, is that if class A defined in one
> package uses a keyword symbol as an initarg and class B in another
> package uses the same keyword it's going to make it difficult to write
> a third class that extends both A and B, while if they had each used a
> symbol in the same package as the class name, then there will be no
> problem with writing the class that extends them both.
>
> So, two questions: 1) did I understand the issue correctly and 2) does
> anyone actually use this approach? It seemed a bit strange at first
> but actually makes a lot of sense.

Yes, you understand it...but....

The idea of the package system is to allow different namespaces to
co-exist, not to modularize code.  So assuming that the package system
has been used the way it is intended, it would be highly unusual for
you to *want* to inherit something from two different packages.  (For
example, would you want to create something that is a  MACSYMA:INTEGRATOR 
and a  SHRDLU:YELLOW-BLOCK ?)

But of course, there are reasons that you might want to inherit across
package boundaries.  Putting the initargs in the same package as the
class may help, but it won't solve the problem:

  (defclass button ()
    ((function :initarg 'function))) ;; The function performed by this button. 

;;; in another package

  (defclass integral ()
    ((function :initarg 'function))) ;; The kernel function of this integral.

You not only have to make sure that you use a local symbol, you also
have to ensure that you never export the symbol.

Kenny Tilton's idea of re-defining the slots in the subclass should work
just fine to get you around the screw cases.
From: Peter Seibel
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <m37k3zih9n.fsf@javamonkey.com>
Joe Marshall <···@ccs.neu.edu> writes:

> Putting the initargs in the same package as the class may help, but
> it won't solve the problem:
> 
>   (defclass button ()
>     ((function :initarg 'function))) ;; The function performed by this button. 
> 
> ;;; in another package
> 
>   (defclass integral ()
>     ((function :initarg 'function))) ;; The kernel function of this integral.
> 
> You not only have to make sure that you use a local symbol, you also
> have to ensure that you never export the symbol.

Yup. That problem occured to me later.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Thomas F. Burdick
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <xcvn0cu3oid.fsf@famine.OCF.Berkeley.EDU>
Peter Seibel <·····@javamonkey.com> writes:

> Joe Marshall <···@ccs.neu.edu> writes:
> 
> > Putting the initargs in the same package as the class may help, but
> > it won't solve the problem:
> > 
> >   (defclass button ()
> >     ((function :initarg 'function))) ;; The function performed by this button. 
> > 
> > ;;; in another package
> > 
> >   (defclass integral ()
> >     ((function :initarg 'function))) ;; The kernel function of this integral.
> > 
> > You not only have to make sure that you use a local symbol, you also
> > have to ensure that you never export the symbol.
> 
> Yup. That problem occured to me later.

But this is just the same problem you always get with the package
system.  It's a bad idea to name a slot/function/type/anything
COMMON-LISP:FUNCTION.  No, I'm not Paul Dietz, so I don't have the
external symbols of COMMON-LISP memorized -- I just expect my
implementation to warn me if I do something like this.  (I'll be glad
to eventually move to a CMUCL with package locks, so I can retire my
hack to do this).

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Paul F. Dietz
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <zPCdnW7uZ7OfnuyiU-KYhA@dls.net>
Thomas F. Burdick wrote:
>  No, I'm not Paul Dietz, so I don't have the
> external symbols of COMMON-LISP memorized -- I just expect my
> implementation to warn me if I do something like this.

Nor do I. :)

	Paul
From: Thomas F. Burdick
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <xcvbrta23bs.fsf@famine.OCF.Berkeley.EDU>
"Paul F. Dietz" <·····@dls.net> writes:

> Thomas F. Burdick wrote:
> >  No, I'm not Paul Dietz, so I don't have the
> > external symbols of COMMON-LISP memorized -- I just expect my
> > implementation to warn me if I do something like this.
> 
> Nor do I. :)

Heh :)

Let me rephrase that...

Even Paul Dietz doesn't have the external symbol of ... blah blah ...

(As a subscriber to the cmucl and sbcl devel lists, this comes as
something of a surprise...)

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Marco Antoniotti
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <3F71B05E.2020600@cs.nyu.edu>
Paul F. Dietz wrote:
> Thomas F. Burdick wrote:
> 
>>  No, I'm not Paul Dietz, so I don't have the
>> external symbols of COMMON-LISP memorized -- I just expect my
>> implementation to warn me if I do something like this.
> 
> 
> Nor do I. :)
> 

Liar!  We all know that you have also memorized the entire EXT package 
of CMUCL. :)

Cheers
--
Marco
From: ·············@comcast.net
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <vfrib3he.fsf@comcast.net>
···@famine.OCF.Berkeley.EDU (Thomas F. Burdick) writes:

> Peter Seibel <·····@javamonkey.com> writes:
>
>> Joe Marshall <···@ccs.neu.edu> writes:
>> 
>> > Putting the initargs in the same package as the class may help, but
>> > it won't solve the problem:
>> > 
>> >   (defclass button ()
>> >     ((function :initarg 'function))) ;; The function performed by this button. 
>> > 
>> > ;;; in another package
>> > 
>> >   (defclass integral ()
>> >     ((function :initarg 'function))) ;; The kernel function of this integral.
>> > 
>> > You not only have to make sure that you use a local symbol, you also
>> > have to ensure that you never export the symbol.
>> 
>> Yup. That problem occured to me later.
>
> But this is just the same problem you always get with the package
> system.  It's a bad idea to name a slot/function/type/anything
> COMMON-LISP:FUNCTION.  No, I'm not Paul Dietz, so I don't have the
> external symbols of COMMON-LISP memorized -- I just expect my
> implementation to warn me if I do something like this.  (I'll be glad
> to eventually move to a CMUCL with package locks, so I can retire my
> hack to do this).

It isn't just the CL package, though, it is any external symbol in
any package that you might be using (CL is a good example because
you *always* use it).  I have a hard time memorizing the external
symbols of packages I haven't used or seen yet.

Package locks help, but they don't solve the problem.
From: Nils Goesche
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <lyvfri86k9.fsf@cartan.de>
·············@comcast.net writes:

> It isn't just the CL package, though, it is any external symbol in
> any package that you might be using (CL is a good example because
> you *always* use it).  I have a hard time memorizing the external
> symbols of packages I haven't used or seen yet.
> 
> Package locks help, but they don't solve the problem.

Yet another argument for not doing :use-package on everything.

Regards,
-- 
Nils G�sche
"Don't ask for whom the <CTRL-G> tolls."

PGP key ID 0x0655CFA0
From: Thomas F. Burdick
Subject: Re: Using keywords as :initargs?
Date: 
Message-ID: <xcvpthovce4.fsf@famine.OCF.Berkeley.EDU>
·············@comcast.net writes:

> ···@famine.OCF.Berkeley.EDU (Thomas F. Burdick) writes:
> 
> > Peter Seibel <·····@javamonkey.com> writes:
> >
> >> Joe Marshall <···@ccs.neu.edu> writes:
> >> 
> >> > Putting the initargs in the same package as the class may help, but
> >> > it won't solve the problem:
> >> > 
> >> >   (defclass button ()
> >> >     ((function :initarg 'function))) ;; The function performed by this button. 
> >> > 
> >> > ;;; in another package
> >> > 
> >> >   (defclass integral ()
> >> >     ((function :initarg 'function))) ;; The kernel function of this integral.
> >> > 
> >> > You not only have to make sure that you use a local symbol, you also
> >> > have to ensure that you never export the symbol.
> >> 
> >> Yup. That problem occured to me later.
> >
> > But this is just the same problem you always get with the package
> > system.  It's a bad idea to name a slot/function/type/anything
> > COMMON-LISP:FUNCTION.  No, I'm not Paul Dietz, so I don't have the
> > external symbols of COMMON-LISP memorized -- I just expect my
> > implementation to warn me if I do something like this.  (I'll be glad
> > to eventually move to a CMUCL with package locks, so I can retire my
> > hack to do this).
> 
> It isn't just the CL package, though, it is any external symbol in
> any package that you might be using (CL is a good example because
> you *always* use it).  I have a hard time memorizing the external
> symbols of packages I haven't used or seen yet.

So, use the things named by the external symbols of those packages,
but don't use-package them.  Only use-package packages that you
actually *do* know the external symbols of (or for which you're
willing to fake it, like for COMMON-LISP).

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'