Subject: Re: classes and structs
From: rpw3@rpw3.org (Rob Warnock)
Date: Sun, 25 May 2003 04:43:17 -0500
Newsgroups: comp.lang.lisp
Message-ID: <cs2cnXMS276oDU2jXTWc-w@speakeasy.net>
Joe Marshall  <jrm@ccs.neu.edu> wrote:
+---------------
| Rick <rgiuly@yahoo.com> writes:
| > "Steven E. Harris" wrote:
| > > Joe Marshall <jrm@ccs.neu.edu> writes:
| > > > Bonus question:  Why is this not a good idea?
| > > > (Hint:  the accessors are generic functions.)
| > > Because the chosen naming conflates the specific class defined here
| > > with generic function names that could be applicable to a broad set of
| > > classes (that don't need to be related through inheritance)?
| > 
| > If you use general generic method names, some other unrelated class may
| > one day need a generic function of the same name with a different number
| > of arguments. Which wouldn't be allowed. I think.
| 
| It wouldn't.  (Assuming you didn't partition things into separate packages.)
| 
| In either case, it is useful to think about what names the selectors
| ought to have and to choose them explicitly.
+---------------

Indeed. In fact, I just ran into that situation just the other day, when
without thinking too carefully about it I typed something like this:

	(defclass pool ()
	  ((type  :initarg :type  :accessor type  :initform :generic)
	   (count :initarg :count :accessor count :initform 0)
	   (list  :initarg :list  :accessor list  :initform nil)
	   ;...
	   ))

*OOPS!*  At least CMUCL was kind enough to give me a clear error:

	...[other chatter]...
	COUNT already names an ordinary function or a macro.
	If you want to replace it with a generic function, you should remove
	the existing definition beforehand.

	Restarts:
	  0: [CONTINUE] Discard the existing definition of COUNT.
	  1: [ABORT   ] Return to Top-Level.
	...

And of course, LIST would have gotten me if COUNT hadn't!  ;-}
Now the code reads like so:

	(defclass pool ()
	  ((type  :initarg :type  :accessor pool-type  :initform :generic)
	   (count :initarg :count :accessor pool-count :initform 0)
	   (list  :initarg :list  :accessor pool-list  :initform nil)
	   ;...
	   ))

And, yes, when I subclassed it with a "connection-pool", I had to
continue the "pool-" prefix convention to avoid the same problem
with a slot named "listen".

And what about a a slot named "phase" in a "connection" class?
Or in a "fats" class, slots named "cis" and "trans"? [Aside: For
those interested in nutrition, in this case the problem *isn't*
with the "trans" fats...  ;-}  ;-} ]

In fact, given the *large* number of useful, short, but all-too-common
names which are functions in the COMMON-LISP package, I'm starting to
wonder if it would be a reasonable idea to adopt a convention of picking
a short, non-conflicting conc-name for each major class hierarchy one
defines, and sticking with it throughout for *all* of the slots of
that particular hierarchy. That is, in the "connection-pool" or other
subclasses, using "pool-XXX" as accessors (but *not* "connection-pool-XXX").

Comments?


-Rob

-----
Rob Warnock, PP-ASEL-IA		<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607