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



Hi Jim,

Jim Blandy <jimb@red-bean.com> writes:
> Here you're specifying the types of both operands.  This is like
> specializing a generic function on two of its arguments, which Smalltalk
> and Java can't do.


Hmm, a couple of silly questions come to my mind, for example why do
you think that Java doesn't support multiple argument dispatch or why
should a method driven approach be more natural than a type driven
approach -- Platon (identify forms; a car is only a shadow of the idea
car) vs. Aristoteles (see how things behave and group them
accordantly).


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 [...]


In which environment?
---------------------

The real question is: Is there is only one "world" in which one can
identify things like a set, a graph, a group, or may there be other
"worlds"?  And what is a "world" anyway, is it a form (a type) or is
it simply a bunch of operations (behaviour)?

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

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

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


No external overrides
----------------------

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

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

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

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

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

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

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



How should we do it?
--------------------

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

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

When you view a module as a class, everything else follows:
(fetch <my-module> <representation> <string>)
(fetch <my-module> <representation> <port>)
Where the my-module argument can also be implicit.


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


> In the example above, it doesn't really make sense to say that the
> particular `fetch' function we end up calling is a method of the
> <representation> class, or the <string> class --- it's both.

Exactly.  The `fetch' function belongs to the "container", the
"world", the "collection", the "context" or whatever you call it, in
which the objects <representation> and <string> currently live:
<my-module>.



Jost

[1] http://www.parc.xerox.com/spl/groups/eca/pubs/papers/Kiczales-OOPSLA92/for-web.pdf

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