This is the mail archive of the guile@sourceware.cygnus.com mailing list for the Guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Goops and the module system



>>>>> "Jost" == Jost Boekemeier <jostobfe@calvados.zrz.TU-Berlin.DE> writes:

<snip>

Jost> But let me ask another question.

>> [...] where you define various types of objects --- this is a set;
>> this is a graph; this is a group [...]

Jost> In which environment?  ---------------------

Presumably in the module/package you're using.  (or in mathematics,
the paper or book you're reading).  

Jost> The real question is: Is there is only one "world" in which one
Jost> can identify things like a set, a graph, a group, or may there
Jost> be other "worlds"?  

Define world? 

Jost> And what is a "world" anyway, is it a form (a type) or is it
Jost> simply a bunch of operations (behaviour)?

I have no clue, and having read your entire post, still don't.  

Jost> While CLOS, ADA, etc. ignore this question completely, the OO
Jost> paradigm groups operations into separate "worlds".  Such a world
Jost> is a data type, sometimes called a "container" or a
Jost> "collection".

Ok, where I come from (C++, mostly), a container or collection is an
object that can be used to hold other objects.  

I think by "world" you mean something along the lines of "module" or
"class library".  

Jost> I think this is important.  To describe a real world system we
Jost> must 1) identify the objects that populate the system and design
Jost> the appropriate classes.  After that we 2) identify the
Jost> behaviour of the system and create appropriate operations on the
Jost> classes we've designed.  And in step 3) we encapsulate these
Jost> operations and classes into a compound class and specify the
Jost> interface to the outside world.

How, beyond defining classes, and operations on classes (methods) does
C++ (which I know) or java (which at least I'm familiar with) provide
for step 3?  Are you saying that a class library should export only
one class?  Certainly the C++ language makes no such restriction (one
class per header file?).  

Jost> CLOS stops at step 2) and lets you only specify classes and
Jost> operations (generic functions).  It leaves everything else to
Jost> the package system which can be viewed as some kind of
Jost> "idiosyncratic module system" (citation from Kiczales [1]).


Jost> No external overrides ----------------------

Jost> To cite from Kiczales paper [1] again: "User programs must not
Jost> redefine any specified class, generic functions, or methods.
Jost> User defined methods on specified generic functions must be
Jost> specialized to a user-defined class.  User-defined classes and
Jost> generic functions must be named in a user defined package"

Jost> That means that within module P which exports class p you must
Jost> not specify a method specialized to a class q exported from
Jost> module Q.  What a restriction!

Well, specialized solely to class q from module Q.  I'd think that
within the context of Kiczales paper (on the design of extensible
class libraries), "user-defined" means "not part of the library".

Jost> Well, it is exactly the restriction which Java and other OO
Jost> languages enforce.  In pseudo code:

Jost> ---- java module P ------ 
Jost> class p { 
Jost>   void foo (Integer i, String comment) {...}  
Jost>   void foo (Integer i, MBString comment) {...}  
Jost> }

Jost> ---- java module Q ------- 
Jost> class q inherits p { 
Jost>   void foo (Integer i, String comment) {...}  
Jost>   void foo (Integer i, MBString comment) {...}  
Jost> }

Jost> In the above example we have a generic function called "foo"
Jost> which has 4 concrete methods which in turn have three (!)
Jost> specializers.  The specializers are: The scope ("self"), an
Jost> Integer and a String (or MBString).

However, it also prevents some specializations that are still allowed
even with Kiczales proscription.  i.e. the clos-ish code:

---- module P ----
(define-class <p> ())
(define-method foo ((p <p>) (i <integer>)) ...)
---- module Q ----
(define-class <q> ())
(define-method foo ((p <p>) (q <q>)) ...)

Has no java/C++ equivalent, without creating in module Q a class
derived from p that just adds the method foo (q).  Which is a stronger
restriction than Kiczales assertions that a user-defined generic
function must be specialized to a (i.e. at least one) user-defined
class.

Jost> The "self" scope avoids that Q's foo(Integer String)
Jost> destructively overrides P's.

True, but at the expense of requiring additional inheretance to
provide any additional methods.  The CLOS paridigm doesn't enforce
this restriction, and requires the additional effort of not doing
something with undefined behavior.

Jost> How should we do it?  --------------------

>> [...] Then we could define methods like (fetch <representation>
>> <string>) (fetch <representation> <port>)

Jost> Remember: No external overrides.  You must either create a
Jost> derived class <my-representation> and specialize fetch to
Jost> <my-representation>, <string> or you create your own class and
Jost> specialize fetch to it: <my-class>,<representation>,<string>.

You have misinterpreted Kiczales proscription on external overrides to
the stronger requirement enforced by all the foo.bar() languages where
inheretance is the only means of extension.  Adding methods does not
necesarially override an internal one...  

Jost> Summary: CLOS generic functions are not different than
Jost> operations in the standard OO paradigm, but they have stopped
Jost> somewhere on its way towards supporting the OO paradigm.

Summary: you have, due to your unwillingness or inability to
understand generic functions and their use, misinterpreted something
Kiczales said in an over-broad manner that "proves" that your concepts 
of how an OO language should work are correct.

Either a) they are different, or b) they are not.  if they "stopped
somewhere on it's way towards supporting the OO paradigm" they are
different.  Yes, they overlap a lot, and most things that can be done
one way can be done the other.  The CLOS generic function method does,
in some cases, require some greater dicipline on the part of the
programmer, not to break things, but there's no language anywhere
where the programmer can't break things :)

  -Eric
------- end of forwarded message -------

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]