On Tue Mar 15 09:21 2011, Alan wrote:
> On Mar 14, 8:15 pm, Daniel Solano Gomez <cloj...@sattvik.com> wrote:
> > I believe there are two approaches to doing this in Clojure:
> >
> > 1. Multimethods:http://clojure.org/multimethods
> > 2. Protocols:http://clojure.org/Protocols
> >
> > Of the two, as of Clojure 1.2, protocols are the preferred way of doing
> > things.  
> 
> What? Who says they're preferred? Prefer the one that is simplest,
> unless you really need performance, in which case use protocols.

Well, preferred may be a strong word, but such seems to be the
implication from some the documentation on clojure.org.  From the page
on protocols, one of the motivations is to ‘support the 90% case of
multimethods (single dispatch on type) while providing higher-level
abstraction/organization’.  In particular, there is the note that ‘most
uses of StructMaps would now be better served by records’, and records
are designed to work particularly well with protocols.

I don't think that protocols introduce a significantly different level
of complexity than multimethods.  If you are dispatching on type anyway,
they give you performance with your polymorphism.  If you want some
other type of dispatch, multimethods give you the ultimate flexibility
in your polymorphism.


> I might be inclined to do this as a multimethod dispatching on the
> number of points in the shape. Maybe I represent my shape as a vector:
> [[p1, p2, ...] more-data]. Then I can write:
> 
> (defmulti draw (fn [pts & more] (count pts))
> 
> (defmethod draw 1 [[center] radius] (do stuff with these))
> (defmethod draw 2 [[p1 p2]] (draw a line))
> (defmethod draw 3 [[p1 p2 p3] filled?] (draw a triangle)) ...
> (defmethod draw :default [points] (connect up all the points))
> 
> In fact a lot of the methods won't need to even be written,
> because :default can handle them by just drawing lines from point to
> point.

This is an excellent example of how multimethods, combined with a
simple and straightforward data type, can accomplish something that
protocols can not.

In the end, the it all depends on what fits best with what you are
doing.  One approach is to simply avoid using multimethods or
polymorphism as you start developing.  Instead, you can use a custom
dispatch using if or cond in your polymorphic methods.  Once you find
your code being littered with such things, you can think about what
works best in your situation.


Sincerely,

Daniel Solano Gómez

Attachment: pgpRS6Sfae2hQ.pgp
Description: PGP signature

Reply via email to