From: Rodney
Subject: Newbie-> How to prevent symbol clash- CLOS
Date: 
Message-ID: <m%mLc.76694$bp1.60182@twister.nyroc.rr.com>
Loading the following code from a CLOS tutorial into CLISP:
-----------------------------------------------------------------
[1]> (defclass Submarine ()
  ((Depth :accessor Depth :initform 100)
   (Speed :accessor Speed :initform 5))
   (:documentation "The basic submarine class") )
-----------------------------------------------------------------

Yields:

** - Continuable Error
INTERN("(SETF COMMON-LISP:SPEED)"): #<PACKAGE COMMON-LISP> is locked
If you continue (by typing 'continue'): Ignore the lock and proceed
Break 1 [2]>

So with my limited understanding, it looks as if there is already
a symbol 'Speed' and lisp is warning me that it will overwritten
or 'shadowed'  by the accessor 'Speed'.


In my naive little world, I would have expected the
 symbol 'Speed' to belong to the class Submarine and
invisible unless being used to access the slot
Speed.  If that is not so, how can you ever hope
to use meaningful names without having to
worrying about what names are already in use?

Rodney Malone

From: Peter Herth
Subject: Re: Newbie-> How to prevent symbol clash- CLOS
Date: 
Message-ID: <cdl6o3$bt8$1@newsreader2.netcologne.de>
Rodney wrote:

> So with my limited understanding, it looks as if there is already
> a symbol 'Speed' and lisp is warning me that it will overwritten
> or 'shadowed'  by the accessor 'Speed'.

correct
 
> In my naive little world, I would have expected the
>  symbol 'Speed' to belong to the class Submarine and
> invisible unless being used to access the slot
> Speed.  If that is not so, how can you ever hope
> to use meaningful names without having to
> worrying about what names are already in use?

Yes, coming from languages like Java or Python, I have been bitten by 
the same thing. While in Java every class has its "own" member function
names, in CL we have symbols and symbols do not belong to single classes,
but to packages. So if the accessor does not need to be public, you
can create your own package, and define the class there. But as soon
you try to export the symbol speed from your package, you have got 
the same problem again. 
The only way around this problem I have come up so far, is to mimic 
the way defstruct works (probably this was the reason defstruct works
that way :) and prepend the accessor function names with the name 
of the base class, here submarine-speed or, if submarine is a subclass
of ship, something like ship-speed. That is a little bit awkward, but
if one considers that the accessor functions are generic functions,
it becomes clear, that we have to distinguinsh in mind between those
functions that are only functions on one class (those should be named
after that class) and some are thought to be truly generic, that means
applicable to a whole range of classes and thus no longer belonging
to a single class (a fact that is emphasized by the constraint that
all methods to a generic function need to have a congruent parameter 
list).
But one complaint perhaps could have been made: that the creators
of the Common Lisp standard were perhaps a little bit liberal in 
their use of very common symbol names, especially for uses that
are really not that often used for programs. For example, functions
like "list" and "append" you are probably going to use more often 
than long to define yourself, but as you noted "speed" and my 
favourite one "room", these are ones that should have gotten another
name. 

Peter

-- 
pet project: http://dawn.netcologne.de
homepage:    http://www.peter-herth.de
lisp stuff:  http://www.peter-herth.de/lisp.html
get Ltk here: http://www.peter-herth.de/ltk/
From: Christophe Rhodes
Subject: Re: Newbie-> How to prevent symbol clash- CLOS
Date: 
Message-ID: <sq8yddoj9c.fsf@cam.ac.uk>
Peter Herth <·····@netcologne.de> writes:

> But one complaint perhaps could have been made: that the creators
> of the Common Lisp standard were perhaps a little bit liberal in 
> their use of very common symbol names, especially for uses that
> are really not that often used for programs. For example, functions
> like "list" and "append" you are probably going to use more often 
> than long to define yourself, but as you noted "speed" and my 
> favourite one "room", these are ones that should have gotten another
> name. 

I recently had occasion to write the following:

  (in-package :gsharp-numbering)
  (deftype number () 'cl:number)
  (setf (find-class 'number) (find-class 'cl:number))

  (in-package :gsharp-buffer)
  (defun rest (list)
    (cl:rest list))
  (define-compiler-macro rest (list)
    `(cl:rest ,list))
  (define-setf-expander rest (list &environment env)
    (get-setf-expansion `(cl:rest ,list) env))

where these packages internally defined NUMBER as a function and REST
as a class.  Unfortunately, this trick doesn't work for SPEED: since
it is an opaque symbol known to DECLARE OPTIMIZE, one cannot simply
shadow it and define a translation layer.  On the other hand, since it
is only ever used in optimization declarations, which should in
general be a relatively rare event, I'd shadow SPEED, and remember to
use (declare (optimize (cl:speed 3))) where necessary.  As for ROOM:
I'd expect calls to ROOM to be even rarer than OPTIMIZE SPEED
declarations, so a simple shadowing should be fine.

Christophe
-- 
http://www-jcsu.jesus.cam.ac.uk/~csr21/       +44 1223 510 299/+44 7729 383 757
(set-pprint-dispatch 'number (lambda (s o) (declare (special b)) (format s b)))
(defvar b "~&Just another Lisp hacker~%")    (pprint #36rJesusCollegeCambridge)
From: Laurence Kramer
Subject: Re: Newbie-> How to prevent symbol clash- CLOS
Date: 
Message-ID: <cdm5uj$7t9$1@wolfberry.srv.cs.cmu.edu>
Peter Herth wrote:

> Rodney wrote:
> 
> 
>>So with my limited understanding, it looks as if there is already
>>a symbol 'Speed' and lisp is warning me that it will overwritten
>>or 'shadowed'  by the accessor 'Speed'.
> 
> 
> correct
>  
> 
>>In my naive little world, I would have expected the
>> symbol 'Speed' to belong to the class Submarine and
>>invisible unless being used to access the slot
>>Speed.  If that is not so, how can you ever hope
>>to use meaningful names without having to
>>worrying about what names are already in use?
> 
> 
> Yes, coming from languages like Java or Python, I have been bitten by 
> the same thing. While in Java every class has its "own" member function
> names, in CL we have symbols and symbols do not belong to single classes,
> but to packages. So if the accessor does not need to be public, you
> can create your own package, and define the class there. But as soon
> you try to export the symbol speed from your package, you have got 
> the same problem again. 
> The only way around this problem I have come up so far, is to mimic 
> the way defstruct works (probably this was the reason defstruct works
> that way :) and prepend the accessor function names with the name 
> of the base class, here submarine-speed or, if submarine is a subclass
> of ship, something like ship-speed. That is a little bit awkward

Others have pointed out different solutions to this problem, so
I'll adress the convention (like the default behavior of defstruct)
of prepending a class name to the accessor.  I don't like it, for
several reasons.

1. It just makes your code less readable (awkward, as you pointed out).
Instead of having s-expressions that read (speed ship), where ship
is a variable pointing to a ship instance, you'll find
things like (ship-speed ship), which when read as English is redundant.
[BTW, this was the convention in a large system that I contribute to,
and I hate it.]  It becomes even more ungainly when applied to long
accessor names such as mission-requested-resource-type as opposed
to the simpler requested-resource-type.

1a. A corollary problem of this naming convention is that if you
go by the convention that the slot name and accessor name are the
same, you don't have to think about what the accessor name is in
any given situation (when writing code).  Plus, if you're not
aware of the complete hierarchy for a class, you'll have to browse
it first, to find (or recall) what the accessor name actually is.

2. Often you'd like to use an accessor applied to different classes
that do not share a common ancestor, or only a very remote ancestor,
and you certainly wouldn't want to name the accessor thing-speed or
t-speed.

My first impulse confronted with your problem would be to look for
an English synonym for "speed" such as "velocity," and name the
slot/accessor velocity.

Larry
From: Rodney
Subject: Re: Newbie-> How to prevent symbol clash- CLOS
Date: 
Message-ID: <4bALc.77191$bp1.10091@twister.nyroc.rr.com>
"Peter Herth" <·····@netcologne.de> wrote in message
·················@newsreader2.netcologne.de...
> Rodney wrote:
>
> > So with my limited understanding, it looks as if there is already
> > a symbol 'Speed' and lisp is warning me that it will overwritten
> > or 'shadowed'  by the accessor 'Speed'.
>
> correct
>
> > In my naive little world, I would have expected the
> >  symbol 'Speed' to belong to the class Submarine and
> > invisible unless being used to access the slot
> > Speed.  If that is not so, how can you ever hope
> > to use meaningful names without having to
> > worrying about what names are already in use?
>
> Yes, coming from languages like Java or Python, I have been bitten by
> the same thing. While in Java every class has its "own" member function
> names, in CL we have symbols and symbols do not belong to single classes,
> but to packages. So if the accessor does not need to be public, you
> can create your own package, and define the class there. But as soon
> you try to export the symbol speed from your package, you have got
> the same problem again.
> The only way around this problem I have come up so far, is to mimic
> the way defstruct works (probably this was the reason defstruct works
> that way :) and prepend the accessor function names with the name
> of the base class, here submarine-speed or, if submarine is a subclass
> of ship, something like ship-speed. That is a little bit awkward, but
> if one considers that the accessor functions are generic functions,
> it becomes clear, that we have to distinguinsh in mind between those
> functions that are only functions on one class (those should be named
> after that class) and some are thought to be truly generic, that means
> applicable to a whole range of classes and thus no longer belonging
> to a single class (a fact that is emphasized by the constraint that
> all methods to a generic function need to have a congruent parameter
> list).
> But one complaint perhaps could have been made: that the creators
> of the Common Lisp standard were perhaps a little bit liberal in
> their use of very common symbol names, especially for uses that
> are really not that often used for programs. For example, functions
> like "list" and "append" you are probably going to use more often
> than long to define yourself, but as you noted "speed" and my
> favourite one "room", these are ones that should have gotten another
> name.

Yes, thank you Peter.  That helps clear up a few points that were bothering
me.  And since it was very first CLOS example I tried, I felt I needed to
get
past the issue before I wrote too much code.

Rodney Malone
From: Pascal Costanza
Subject: Re: Newbie-> How to prevent symbol clash- CLOS
Date: 
Message-ID: <cdlbhe$meh$1@newsreader2.netcologne.de>
Rodney wrote:
> Loading the following code from a CLOS tutorial into CLISP:
> -----------------------------------------------------------------
> [1]> (defclass Submarine ()
>   ((Depth :accessor Depth :initform 100)
>    (Speed :accessor Speed :initform 5))
>    (:documentation "The basic submarine class") )
> -----------------------------------------------------------------
[...]

> In my naive little world, I would have expected the
>  symbol 'Speed' to belong to the class Submarine and
> invisible unless being used to access the slot
> Speed.  If that is not so, how can you ever hope
> to use meaningful names without having to
> worrying about what names are already in use?

See Christophe's posting. You can say the following before your own 
class declaration:

(shadow 'speed 'room)

But you should make sure that you are in your own package, so you should 
probably better say this:

(defpackage watercrafts
   (:shadow 'speed 'room)
   (:export 'submarine 'depth 'speed))

(in-package 'watercrafts)

...and then your own class definition.

See also http://www.tfeb.org/lisp/hax.html#CONDUITS


Note: Don't feel put off by these minor obstacles. IMHO, symbols and 
Common Lisp's package system are among the best things since sliced 
bread because they allow you to resolve naming conflicts under almost 
any circumstance. As with all versatile tools, it makes some of the 
simple things more complicated but makes some of the complicated things 
solvable in the first place. For example, in Common Lisp you cannot get 
any name clashes because of multiple inheritance, unlike other languages 
with multiple inheritance, because of the way Common Lisp handles 
symbols as names.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Peter Herth
Subject: Re: Newbie-> How to prevent symbol clash- CLOS
Date: 
Message-ID: <cdlcfi$o96$1@newsreader2.netcologne.de>
Pascal Costanza wrote:

> Note: Don't feel put off by these minor obstacles. IMHO, symbols and
> Common Lisp's package system are among the best things since sliced
> bread because they allow you to resolve naming conflicts under almost
> any circumstance. As with all versatile tools, it makes some of the
> simple things more complicated but makes some of the complicated things
> solvable in the first place. For example, in Common Lisp you cannot get
> any name clashes because of multiple inheritance, unlike other languages
> with multiple inheritance, because of the way Common Lisp handles
> symbols as names.

The more I dig into the Common Lisp package system, indeed, the more I like.
But, as today most people who start learning CL have already some exposure
to languages like Java, it takes some time to grasp, because it different
to the world they knew before. What makes this especially nasty is, that
in my experience you first get bitten by a cultural difference before you
get the chance to enjoy the advantages of the different system. I think 
this is one of the main reasons why languages that think different than
the mainstream often have a bad reputation. So what I still miss is an
introduction to CLOS for the Java-minded beginner :).

As for the example of nameclashes with accessor functions of differen
classes: while it is very nice that you have not fear name clashes
when defining methods for a Java class, you can create quite a 
confusion if you have equal method names in different classes but
really different functionality assigned to them. So the limitation
to only one generic function of a name within a package can be 
considered as a wise restriction...

Peter

-- 
pet project: http://dawn.netcologne.de
homepage:    http://www.peter-herth.de
lisp stuff:  http://www.peter-herth.de/lisp.html
get Ltk here: http://www.peter-herth.de/ltk/
From: Rahul Jain
Subject: Re: Newbie-> How to prevent symbol clash- CLOS
Date: 
Message-ID: <87llhcrg4n.fsf@nyct.net>
Peter Herth <·····@netcologne.de> writes:

> So what I still miss is an introduction to CLOS for the Java-minded
> beginner :).

AMOP has one for C++ programmers, which should be close enough.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Larry Clapp
Subject: Re: Newbie-> How to prevent symbol clash- CLOS
Date: 
Message-ID: <slrncfu8qr.52q.larry@theclapp.ddts.net>
In article <············@newsreader2.netcologne.de>, Peter Herth wrote:
> So what I still miss is an introduction to CLOS for the Java-minded
> beginner :).

Some of the exercises at
http://theclapp.blog-city.com/index.cfm?m=1&y=2003 might help.

-- Larry

p.s.  Or they might not.  :)  They helped me.
From: Rodney
Subject: Re: Newbie-> How to prevent symbol clash- CLOS
Date: 
Message-ID: <4bALc.77192$bp1.37642@twister.nyroc.rr.com>
"Pascal Costanza" <········@web.de> wrote in message
·················@newsreader2.netcologne.de...
>
> Rodney wrote:
> > Loading the following code from a CLOS tutorial into CLISP:
> > -----------------------------------------------------------------
> > [1]> (defclass Submarine ()
> >   ((Depth :accessor Depth :initform 100)
> >    (Speed :accessor Speed :initform 5))
> >    (:documentation "The basic submarine class") )
> > -----------------------------------------------------------------
> [...]
>
> > In my naive little world, I would have expected the
> >  symbol 'Speed' to belong to the class Submarine and
> > invisible unless being used to access the slot
> > Speed.  If that is not so, how can you ever hope
> > to use meaningful names without having to
> > worrying about what names are already in use?
>
> See Christophe's posting. You can say the following before your own
> class declaration:
>
> (shadow 'speed 'room)
>
> But you should make sure that you are in your own package, so you should
> probably better say this:
>
> (defpackage watercrafts
>    (:shadow 'speed 'room)
>    (:export 'submarine 'depth 'speed))
>
> (in-package 'watercrafts)
>
> ...and then your own class definition.
>
> See also http://www.tfeb.org/lisp/hax.html#CONDUITS
>
>
> Note: Don't feel put off by these minor obstacles. IMHO, symbols and
> Common Lisp's package system are among the best things since sliced
> bread because they allow you to resolve naming conflicts under almost
> any circumstance. As with all versatile tools, it makes some of the
> simple things more complicated but makes some of the complicated things
> solvable in the first place. For example, in Common Lisp you cannot get
> any name clashes because of multiple inheritance, unlike other languages
> with multiple inheritance, because of the way Common Lisp handles
> symbols as names.
>

Not at all Pascal.  As Peter, Christophe, and you have shown, one of the
charms of Common Lisp is you can always work around anything that
doesn't quite work the way you think it should. Forth is similar
in  this regard, but Common Lisp has a bigger toy chest to play with.

I loved the clean syntax of Eiffel and it's ability to handle
inheritance and renaming of attributes and methods, including
multiple-inheritance. However, I often felt I was in handcuffs
when trying to do anything that had to change it's behavior
dynamically at run time.  And no macros.  Not even compile
time #ifdefs.  Very tough to write for multiple targets without
some external tool.

Common Lisp for me is a perfect mix.  I can create a framework with
just the right amount of order to satisfy my left brain, and yet
be able to come up with new and creative  ways to do things whenever
my right brain gets the best of me.

Unfortunately, because of the sheer size, I'm not always able to find
examples and explainations without asking.  I very much appreciate
this news group and the wealth of information that is presented here
and the friendliness of all the participants.

I've looked at the link to Conduits above.  Thank you.  It is especially
nice to see snippets of code to see how others have solved problems.
I feel this is one of the best ways to learn a language.

Thanks again to all who responded.

Cheers,
Rodney Malone