subtype polymorphism using multimethod

88 views
Skip to first unread message

Feng

unread,
Apr 14, 2008, 1:28:09 AM4/14/08
to Clojure
Hi,

I'm seeking some suggestions on how to use multimethod with java
interface/class types.

Let's say we have following java types:

interface IFoo
interface IBar
class FooA implements IFoo
class FooB implements IFoo
class Bar implements IBar
class FooBar implements IFoo, IBar

and following Clojure methods:

(defmethod meth [IFoo IBar] [f b] ...)
(defmethod meth [FooA Bar] [f b] ...)
(defmethod meth [FooB Bar] [f b] ...)
(defmethod meth [FooBar FooBar] [f b] ...)

I'm currently reading this paper http://research.sun.com/projects/plrg/Publications/2006-0501.pdf,
which discusses lots of problems around multimethod. How are they
relevant to Clojure multimethod? Is it possible (and desirable) to
implement a dispatch function that satisfy the properties in the paper
(except static checking part)?

regards,
Feng

Rich Hickey

unread,
Apr 15, 2008, 6:25:06 PM4/15/08
to Clojure


On Apr 14, 1:28 am, Feng <hou...@gmail.com> wrote:
> Hi,
>
> I'm seeking some suggestions on how to use multimethod with java
> interface/class types.
>
> Let's say we have following java types:
>
> interface IFoo
> interface IBar
> class FooA implements IFoo
> class FooB implements IFoo
> class Bar implements IBar
> class FooBar implements IFoo, IBar
>
> and following Clojure methods:
>
> (defmethod meth [IFoo IBar] [f b] ...)
> (defmethod meth [FooA Bar] [f b] ...)
> (defmethod meth [FooB Bar] [f b] ...)
> (defmethod meth [FooBar FooBar] [f b] ...)
>
> I'm currently reading this paperhttp://research.sun.com/projects/plrg/Publications/2006-0501.pdf,
> which discusses lots of problems around multimethod. How are they
> relevant to Clojure multimethod? Is it possible (and desirable) to
> implement a dispatch function that satisfy the properties in the paper
> (except static checking part)?
>

I left a question for you in response to the last question you asked -
could you please wrap that up before starting another thread?

In short response to this, all of these type systems have the problem
of forcing all multiple derivations through a single getClass/
instanceof channel. The IFoo IBar types above are content-free, but in
the real world different bases often exist in separate taxonomies, in
which the above structure wouldn't occur, or would represent a flaw in
the logic. I think OO systems need to start representing taxonomies
separately rather than multiplexing class/type. It's a limited system
that creates the problems the paper tries to address. why keep
pursuing it?

Clojure multimethods have the ability to dispatch on separate
taxonomies. But they don't solve Java's problems.

Rich

Feng

unread,
Apr 15, 2008, 10:46:28 PM4/15/08
to Clojure


On Apr 15, 6:25 pm, Rich Hickey <richhic...@gmail.com> wrote:
> On Apr 14, 1:28 am, Feng <hou...@gmail.com> wrote:
>
>
>
> > Hi,
>
> > I'm seeking some suggestions on how to use multimethod with java
> > interface/class types.
>
> > Let's say we have following java types:
>
> > interface IFoo
> > interface IBar
> > class FooA implements IFoo
> > class FooB implements IFoo
> > class Bar implements IBar
> > class FooBar implements IFoo, IBar
>
> > and following Clojure methods:
>
> > (defmethod meth [IFoo IBar] [f b] ...)
> > (defmethod meth [FooA Bar] [f b] ...)
> > (defmethod meth [FooB Bar] [f b] ...)
> > (defmethod meth [FooBar FooBar] [f b] ...)
>
> > I'm currently reading this paperhttp://research.sun.com/projects/plrg/Publications/2006-0501.pdf,
> > which discusses lots of problems around multimethod. How are they
> > relevant to Clojure multimethod? Is it possible (and desirable) to
> > implement a dispatch function that satisfy the properties in the paper
> > (except static checking part)?
>
> I left a question for you in response to the last question you asked -
> could you please wrap that up before starting another thread?
>

Just replied. Please feel free to consider it closed, although I
thought of a different mulitmethod composition semantic. I actually
like current multimethod semantics as well, more explicit, less magic.

> In short response to this, all of these type systems have the problem
> of forcing all multiple derivations through a single getClass/
> instanceof channel. The IFoo IBar types above are content-free, but in
> the real world different bases often exist in separate taxonomies, in
> which the above structure wouldn't occur, or would represent a flaw in
> the logic. I think OO systems need to start representing taxonomies
> separately rather than multiplexing class/type. It's a limited system
> that creates the problems the paper tries to address. why keep
> pursuing it?
>

First, I must admit my failure of coming up a useful example on
multidispatch of subtype relations. However, I still believe that a
well-defined multidispatch protocol based on subtype relations (not
subclass implementation inheritance) is very powerful way to model
certain problem space. Java interface subtype and runtime reflection,
in combine with Clojure multimethod (MultiFn still needs some
reflective features), provide good substrate to build such taxonomy. I
don't disagree that multi taxonomies and leaving out a native type/
class system in Clojure are great design decisions. It's just that
subtype polymorphism is very useful technique, from CLOS to Dylan to
Fortress all build their multidispatch on top of it, and make
improvement in each step. This at least proves it's useful, and
difficult to get right (all these subtype liniearization, asymmetric
vs symmetric dispatch, modular method composition design choose still
make my brain hurt). If we leave all these to users, what we may end
up with is that everyone will build their own, for exact same
taxonomy, but none of them are compatible and composible. I believe
that a well-designed ,constrained multidispatch protocol ensures good
composibility, which can be more powerful than "system allows
unlimited behavior" kind of design. You have demonstrated some
positive results in Clojure (e.g. *immutable* vs multiable,
constrained ref vs naked ref etc). We can see negative effects (e.g.
monkeypatch chaos) happening on ruby/javascript side as well.

> Clojure multimethods have the ability to dispatch on separate
> taxonomies.
>

Agreed.

> But they don't solve Java's problems.

can't or don't intent to? Clojure multimethod for functional
extensibility plus java interface subtyping for data extensibility are
such a perfect fit to each other. Why not take advantage them?

>
> Rich

I didn't mean to disturb you by these threads. Sorry again if they
made so (which means I'm perfect fine if you don't feel the need to
response).

Kindly regards,
Feng

Rich Hickey

unread,
Apr 16, 2008, 8:23:50 AM4/16/08
to Clojure
I think it is essential to come up with a motivating example. The fact
that the paper fails to provide one is telling as well. Once you
separate out classes/types as declarers of sets of methods, most of
the subtypes are used for implementation inheritance.

> Java interface subtype and runtime reflection,
> in combine with Clojure multimethod (MultiFn still needs some
> reflective features), provide good substrate to build such taxonomy. I
> don't disagree that multi taxonomies and leaving out a native type/
> class system in Clojure are great design decisions. It's just that
> subtype polymorphism is very useful technique, from CLOS to Dylan to
> Fortress all build their multidispatch on top of it, and make
> improvement in each step.

I found the 'excludes' declaration quite troubling and wonder how that
scales - how does one explicitly exclude everything that it is not? In
my opinion, this begs for named taxonomies. If Vector and Matrix
belonged to the same taxonomy, and you could have only one entry per
taxonomy, then exclusion would be automatic and extensible. Funnel
type systems are bad and need to be replaced.

> This at least proves it's useful, and
> difficult to get right (all these subtype liniearization, asymmetric
> vs symmetric dispatch, modular method composition design choose still
> make my brain hurt). If we leave all these to users, what we may end
> up with is that everyone will build their own, for exact same
> taxonomy, but none of them are compatible and composible. I believe
> that a well-designed ,constrained multidispatch protocol ensures good
> composibility, which can be more powerful than "system allows
> unlimited behavior" kind of design. You have demonstrated some
> positive results in Clojure (e.g. *immutable* vs multiable,
> constrained ref vs naked ref etc). We can see negative effects (e.g.
> monkeypatch chaos) happening on ruby/javascript side as well.
>
> > Clojure multimethods have the ability to dispatch on separate
> > taxonomies.
>
> Agreed.
>
> > But they don't solve Java's problems.
>
> can't or don't intent to? Clojure multimethod for functional
> extensibility plus java interface subtyping for data extensibility are
> such a perfect fit to each other. Why not take advantage them?
>

Java is still a funnel system, e.g. all characteristics funnel through
an object's class/type. Therefore, constituent interfaces are not
selectable by taxonomy/value, and thus there are limits to the
interoperability with Clojure's equality-based dispatch.

> I didn't mean to disturb you by these threads. Sorry again if they
> made so (which means I'm perfect fine if you don't feel the need to
> response).
>

Not at all. I'm a language geek and am interested in all of these
things. I developed object systems and a predicate dispatch system
while designing Clojure. The predicate dispatch might still make it
in, and handled is-a relationships not necessarily tied to types, as
well as some definition-time logical-implication-based overload
resolution and ambiguity detection. It requires a mini-prolog rules
engine that has not yet made it into Clojure, but likely will even if
I don't do predicate dispatch.

Rich

Feng

unread,
Apr 16, 2008, 6:12:40 PM4/16/08
to Clojure
I don't believe Clojure should take a single taxonomy either, be it
the paper I referred to (bias to a static type/module system for
resolving call ambiguity), nor the ones in CLOS family (linearization
of type hierarchy, dispatch parameter type from left to right). I'm
wondering if a set of dispatch functions (c3-multidispatch, m3-
multidispatch etc) can be developed as a library. Then everyone can
just use them without building their own. This brings two issues I'm
thinking about current Clojure multimethod design (admitted very
flexible, powerful at bare metal level).

1. Is it valuable to build such library on top of java type system
(one most widely used and understood taxonomy, for better or worse)?
What's the best way to implement them (dispatch functions use a
reflective api to test MultiFn dispatch table entries against a set of
dispatch rules and find most specific method)?

2. With all these variations of dispatch strategy within the same
taxonomy (let alone broken ones that I'm trying to develop ;-),
methods that use these dispatchers (with very subtle differences)
couldn't compose at all, in a modular and declarative way.
It's very interesting and exciting. I'll be patiently waiting for it.

> Rich

Thank you again for spending time on this,
Feng
Reply all
Reply to author
Forward
0 new messages