[plt-scheme] Swindle question: multiple gf defs with the same name

From: Eli Barzilay (eli at barzilay.org)
Date: Sat Aug 7 18:12:25 EDT 2004

On Aug  7, Doug Orleans wrote:
> What class do you mean?  These methods are otherwise unrelated
> except for their name, so there's no class specializer in common.

Supposedly you're working on some data and there is some place where
you define that data (classes, structs or whatever).  If you use just
builtin classes, then I'd go for a module that defines the generics.

>  > (In CLOS there is no problem because there is no module system, so you
>  > can have (defmethod foo::bar ...) inside a file that defines another
>  > package.)
> Right, but you still have to know about the other package.  In my
> example the two modules are oblivious to each other.

So I don't know if you could do that in CLOS without having one
package require the other.

> They could both be made to require a common module that defined the
> gfs, but it would be tedious to make every single gf definition
> explicit in this common module, especially if they're usually
> macro-generated by some form that expands into multiple defmethods.

(defgeneric* foo (...))?

> I'm thinking the best answer is to make a new gf that somehow forwards
> to (the methods of) the other gfs.  This is pretty much what you have
> to do to resolve name clashes in general, either with multiple modules
> or multiple inheritance.  The problem is knowing which gf to forward
> to.  Perhaps it's enough to call one gf, catching "no such method"
> exceptions, which cause the next gf to be called.  Or maybe something
> more sophisticated could be done with the MOP that doesn't have the
> overhead of an exception handler.  I was just hoping this problem had
> already been solved...

There is a `no-next-method' generic that you can override, but I don't
know if what you're talking about makes sense.  If you simply make a
generic give up and send its arguments to another, then you won't see
some methods.  For example:

  module A: (defmethod (foo (x <integer>)) ...)
  module B: (defmethod (foo (x <integer>)) ...)
  module C: (require (prefix A: A) (prefix B: B))
            (define foo (combine-gfs A:foo B:foo))

will always ignore one of the <integer> methods.  But if you think
that this makes sense, you can write a `combine-gfs' that works
slightly better -- instead of making A:foo go to B:foo when giving up,
you could just make a new gf, then add all the generic-methods of
A:foo and B:foo to it.  (Of course you still need to choose which ones
get added last...)

          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!

Posted on the users mailing list.