From: Robert Monfera
Subject: Re: What are some ways of packaging a class and its methods?
Date: 
Message-ID: <38B00B16.4285BD1E@fisec.com>
Steve Long wrote:

> You could create a macro called defklass [...]

If anything, I'd prefer a MOP-based solution if there was a true need
for the concept of hiding, because you would not have to reinvent things
like class finalizations and a million other things.  Of course, macros
would still be needed as an API for humans.

If methods belong to classes, then say good-bye to multimethods, method
combinations, dispatching on symbols and built-in classes, to name a
few.  Naturally, if someone doesn't know these concepts, he won't miss
them :-)

Hiding could be implemented such a way that you preserve multiple
dispatch, but in this case the unit of protection would need to be a
bigger chunk than a class (say, a module).  But the whole point of
Metaobject Protocol (another concept for the OP to study) is to open up
the object system.

I highly doubt that people at an early stage of learning CLOS need
hiding, and by the time they think they'll need it, they will change
their minds, otherwise we'd be surrounded by hiding libraries.  (Maybe
we are, but they hide so well?)

Robert

From: David J. Cooper
Subject: Re: What are some ways of packaging a class and its methods?
Date: 
Message-ID: <38B019F8.D08D652E@genworks.com>
Robert Monfera wrote:
> 
> If methods belong to classes, then say good-bye to multimethods, method
> combinations, dispatching on symbols and built-in classes, to name a
> few.  Naturally, if someone doesn't know these concepts, he won't miss
> them :-)
> 

Look at it this way: just because a method ``belongs'' to a certain class,
does not mean it cannot take additional arguments of arbitrary other types.
The class it ``belongs to'' just happens to transliterate into its first
argument. What I am basically saying is that CLOS can subsume some of the
simplicity and advantages of Flavor or Smalltalk style messaging quite happily.
And this does not have to be seen as limiting, really.

This idea that the Generic Function OO model subsumes the message-passing OO
model is the main point of section 11.10 of Graham's _ANSI_Common_Lisp_.


 -dave


-- 
David J. Cooper Jr, Chief Engineer	Genworks International
·······@genworks.com			5777 West Maple, Suite 130
(248) 932-2512 (Genworks HQ/voicemail)	West Bloomfield, MI 48322-2268
(248) 407-0633 (pager)			http://www.genworks.com
From: Robert Monfera
Subject: Re: What are some ways of packaging a class and its methods?
Date: 
Message-ID: <38B0217C.6E46A13A@fisec.com>
"David J. Cooper" wrote:

[in arbitrary order]

> This idea that the Generic Function OO model subsumes the
> message-passing OO model is the main point of section 11.10 of
> Graham's _ANSI_Common_Lisp_.

I agree with this.  The ability to dispatch on one argument only is an
arbitrary limitation, something similar to the limitation of being able
to return only one value from a function.  It is trivial to use CLOS
roughly at the Smalltalk/C++/Java level of polymorphism and inheritance
model if that's somebody's intention - just don't dispatch on anything
other than the first argument.

> Look at it this way: just because a method ``belongs'' to a certain
> class, does not mean it cannot take additional arguments of arbitrary
> other types.
> The class it ``belongs to'' just happens to transliterate into its
> first argument.

[I assume you meant to preserve the possibility of dispatching on other
arguments, otherwise I see nothing you disagree with what I've said]

This is technically true, although from the viewpoint of consequences,
it almost does not matter which argument (first, second) we consider the
base case.  Even though the first argument has a bigger say in
dispatching than the second, it would be artificial to assign the GF or
even the method to a specific class, because it does not make a
difference from the viewpoint of encapsulation if there may be methods
dispatching on other arguments.

The main point of single-argument dispatch is that it enables
Smalltalk-style _encapsulation_ and C++-type _hiding_ (besides assumed
simplicity), and forcing these styles on the GF model is not possible
without giving up multi-arg dispatch and a host of other things.  In
other words, what would be the use of CLOS-style methods or GFs
belonging to one class, if we don't even benefit from the perceived
values of encapsulation and hiding?

(I don't imply that encapsulation and hiding are impossible with the GF
model, but it would definitely require a style incompatible with the
common class-based encapsulation and hiding.)

Robert
From: Masoud Pirnazar
Subject: Re: What are some ways of packaging a class and its methods?
Date: 
Message-ID: <38B1CFDB.75125B2D@poboxes.com>
Ok, let's make the question simpler and more specific.  I have

e (defclass c-cons2 ...)
e (defmethod do-something-1-with-cons2 (c cons2) (other parms) ...)
e (defmethod do-something-2 ...)
e (defun do-non-method-thing-3 (...) ...)
L (defun do-local-thing (...) ...)
L (defun do-local-thing-2 (...) ...)

The lines marked e are for use by the general package user.  The lines
marked L are used by the e functions, but would ordinarily not be called by
the outside world. I want to package this functionality into a package
"PKG-CONS2" so someone can :use "PKG-CONS2" and have access the the class
c-cons2 and the functions and methods it exports.   Can this be done, and if
so, how would I do it? (a sample module or some lisp annotations around the
above code would explain how to do it well).

For example, when you export c-cons2, does it export all the class
information?  Or would you resort to defining c-cons2 outside of PKG-CONS2?

Robert Monfera wrote:

> Steve Long wrote:
>
> > You could create a macro called defklass [...]
>
> If anything, I'd prefer a MOP-based solution if there was a true need
> for the concept of hiding, because you would not have to reinvent things
> like class finalizations and a million other things.  Of course, macros
> would still be needed as an API for humans.
>
> If methods belong to classes, then say good-bye to multimethods, method
> combinations, dispatching on symbols and built-in classes, to name a
> few.  Naturally, if someone doesn't know these concepts, he won't miss
> them :-)
>
> Hiding could be implemented such a way that you preserve multiple
> dispatch, but in this case the unit of protection would need to be a
> bigger chunk than a class (say, a module).  But the whole point of
> Metaobject Protocol (another concept for the OP to study) is to open up
> the object system.
>
> I highly doubt that people at an early stage of learning CLOS need
> hiding, and by the time they think they'll need it, they will change
> their minds, otherwise we'd be surrounded by hiding libraries.  (Maybe
> we are, but they hide so well?)
>
> Robert
From: Pierre R. Mai
Subject: Re: What are some ways of packaging a class and its methods?
Date: 
Message-ID: <87itzh5gh9.fsf@orion.dent.isdn.cs.tu-berlin.de>
Masoud Pirnazar <··········@poboxes.com> writes:

> Ok, let's make the question simpler and more specific.  I have
> 
> e (defclass c-cons2 ...)
> e (defmethod do-something-1-with-cons2 (c cons2) (other parms) ...)
> e (defmethod do-something-2 ...)
> e (defun do-non-method-thing-3 (...) ...)
> L (defun do-local-thing (...) ...)
> L (defun do-local-thing-2 (...) ...)

Again, you should use packages at a higher granularity than classes.
Compare CL's packages more to Java's packages than to it's classes.
I.e. something like the AWT would be bundled in 1-4 packages, not in
hundreds of packages.

That said let me give you an example what I'd write if hard pressed to 
do something like this:

(defpackage "MAGIC-CONS"
  (:nicknames "MCONS")
  (:use "CL")
  (:export "MCONS" "MCONS-ITEM" "MCONS-LEFT" "MCONS-RIGHT"
           "MAGIC-LEFT" "MAGIC-RIGHT"))

(in-package "MAGIC-CONS")

(defclass mcons ()
  ((item :initarg :item :accessor mcons-item)
   (left :initarg :left :initform nil :accessor mcons-left)
   (right :initarg :right :initform nil :accessor mcons-right)))

(defun mcons (item left right)
  "Create a magic cons out of item and left and right magic-trees."
  (make-instance 'mcons :item item :left left :right right))

;;; Note that the following is overly verbose, and advanced users
;;; would use the automatically generated accessors as implementations 
;;; for magic-left and magic-right directly.  But let's keep things
;;; simple for the moment.

(defgeneric magic-left (cons)
  (:documentation 
   "Return the left subtree of a cons or mcons.  Is setf-able."))

(defgeneric (setf magic-left) (newval cons)
  (:documentation 
   "Set the left subtree of a cons or mcons."))

(defgeneric magic-right (cons)
  (:documentation 
   "Return the right subtree of a cons or mcons.  Is setf-able."))

(defgeneric (setf magic-right) (newval cons)
  (:documentation 
   "Set the right subtree of a cons or mcons."))

(defmethod magic-left ((cons cons))
  (car cons))

(defmethod magic-left ((cons mcons))
  (mcons-left cons))

(defmethod (setf magic-left) (newval (cons cons))
  (setf (car cons) newval))

(defmethod (setf magic-left) (newval (cons mcons))
  (setf (mcons-left cons) newval))

(defmethod magic-right ((cons cons))
  (cdr cons))

(defmethod magic-right ((cons mcons))
  (mcons-right cons))

(defmethod (setf magic-right) (newval (cons cons))
  (setf (cdr cons) newval))

(defmethod (setf magic-right) (newval (cons mcons))
  (setf (mcons-right cons) newval))

> The lines marked e are for use by the general package user.  The lines
> marked L are used by the e functions, but would ordinarily not be called by
> the outside world. I want to package this functionality into a package
> "PKG-CONS2" so someone can :use "PKG-CONS2" and have access the the class
> c-cons2 and the functions and methods it exports.   Can this be done, and if
> so, how would I do it? (a sample module or some lisp annotations around the
> above code would explain how to do it well).

For your above code, all the names of the (generic) functions and
classes that you want to export should be exported.  Since defclass
forms allow you to define accessors, if you want to allow access to
those (which you'll frequently want to do), the names of those should
be exported to.  Since you didn't give the body of the defclass form,
I'll assume there isn't anything you consider worthwile to export in
it, so the defpackage form might look like:

(defpackage "C-CONS2"
  (:use "CL")
  (:export "C-CONS2" "DO-SOMETHING-1-WITH-CONS2" "DO-SOMETHING-2"
           "DO-NON-METHOD-THING-3"))

> For example, when you export c-cons2, does it export all the class
> information?  Or would you resort to defining c-cons2 outside of PKG-CONS2?

Note that the package system works at the level of symbols
(i.e. names) only.  It has no knowledge of whether C-CONS2 names a
class, a variable, a function, a setf-function (or all of the above).
You will have to understand this to make effective use of the package
system.  Also try to heed the advice of using packages at a
granularity level far above single classes.  If we take MaiSQL for
example, then you will find that it consists of X packages only:

- MAISQL-SYS, which exports all of the database-backend intependend
  functionality for use by implementors of database-backends,

- MAISQL, which re-exports the subset of MAISQL-SYS which is intended
  for the user and not only for backend-implementors, and

- MAISQL-USER, which is to MAISQL what COMMON-LISP-USER is to
  COMMON-LISP.

Furthermore, each database-backend has it's own package (currently
MAISQL-MYSQL and MAISQL-POSTGRESQL, more to come),  which uses
MAISQL-SYS.  This is done mostly to hide the FFI bindings.

At the moment the user functionality of MaiSQL only consists of two
classes, but when classes for SQL syntax constructs, etc. will be
added, they will be in the MAISQL packages as well.

Regs, Pierre.

-- 
Pierre Mai <····@acm.org>         PGP and GPG keys at your nearest Keyserver
  "One smaller motivation which, in part, stems from altruism is Microsoft-
   bashing." [Microsoft memo, see http://www.opensource.org/halloween1.html]
From: Tim Bradshaw
Subject: Re: What are some ways of packaging a class and its methods?
Date: 
Message-ID: <ey31z66ca5x.fsf@cley.com>
* Masoud Pirnazar wrote:

> For example, when you export c-cons2, does it export all the class
> information?  Or would you resort to defining c-cons2 outside of PKG-CONS2?

No.  Exporting works entirely at the level of symbols -- names really.
So if you export the symbol C-CONS2 all you export is that name, so
now it's easier to say (make-instance 'c-cons2 ...).  If C-CONS2 has
been defined to have keyword arguments to initialise slots (or do
whatever), then those will be available too, of course.

--tim