On Feb 5, 6:36 am, Laurent PETIT <laurent.pe...@gmail.com> wrote:


> Doesn't that sound  like multifunctions whose dispatching is tied to the
> type ('model') of a 'thing' ?

Yes, but see below.

> Once again, does'nt this correspond to the introduction of the interface
> concept in java ?

No. I think the article I linked to clarifies the idea pretty well,
but to respond more directly to your question: Java interfaces are a
particular way to support protocols at the language level, and I like
them, as far as they go. But in order to implement an interface, you
must define a class. You don't need to define a class in order to
implement a protocol in my scheme (and indeed, in my scheme there are
no such things as classes):

(make-thing {:models [::thing]
                   :protocols [::thing ::idea]
                   :inits {:name "test-thing1" :number 1}})

The above snippet creates a thing whose model is [::thing] and whose
protocol is [::thing ::idea]. That means that this thing has all the
data fields defined by the model ::thing, and it responds correctly to
protocol functions (that is multifunctions) defined by the
protocols ::thing and ::idea.

Notice that no class is defined. You simply make a thing and say what
models and protocols it implements. You can also update the models and
protocols at runtime (more properly: you can create a copy of a thing
with different models and protocols).

This code does illustrate a fly in the ointment that is the reason I
wish for predicate dispatch: suppose that ::thing and ::idea are
unrelated protocols. Under the covers, my code creates a relationship
between this thing and each of those protocols such that if you call
some multimethod "frob" on the thing, Clojure will dispatch to the
appropriate method. The fly in the ointment is: what happens if both
protocols specialize frob? Then Clojure will complain that it can't
tell which method to call. In order to resolve that problem, we must
use prefer-method to declare that one protocol or the other is
preferred.

But what if I want to make another thing:

(make-thing {:models [::thing]
                   :protocols [::idea ::thing]
                   :inits {:name "test-thing2" :number 2}})

...where the order of the protocols expresses my wish to prefer ::idea
over ::thing? At present, I can't do this; once prefer-method has said
that dispatch prefers ::thing over ::idea, I cannot then create a
thing for which dispatch prefers ::idea over ::thing (without also
changing the preference for all other things whose protocols include
both ::thing and ::idea). With predicate dispatch, I could build a
solution to this problem; I haven't yet thought of a way to solve it
in the existing Clojure.

Apart from this wart, the scheme currently works as intended: you can
create objects with arbitrary models and protocols, where the set of
fields is determined by all the models, and the set behavior under
multifunctions is determined by the set of protocols.

Alert readers will notice that it's possible to create contradictory
sets of models and protocols, and a complete implementation should
implement policies for detecting and correcting that failing; dealing
with those issues is on my to-do list.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to