One of the benefits of Clojure(Script)'s multimethods over traditional OO 
polymorphism is that you can dispatch on multiple values. For example, we can 
dispatch on the types of all the arguments, instead of just the first one:

(defmulti example (fn [x y] [(type x) (type y)]))

My question is about the use of :default in such situations.

Let's switch to a more clojure-ish example, with plain maps for data:

(def a-circle { :type :circle, :radius 10 })
(def a-rectangle { :type rectangle, :width 2, :height 3 })

(defmulti combine (fn [x y] [(:type x) (:type y)]))

Now I can define combine for any combination of shapes:

  (defmethod combine [::circle ::circle] ...)
  (defmethod combine [::circle ::rectangle] ...)

If I happen to have different types of circles, say ::red-circle, and 
::blue-circle, I can do

  (derive ::red-circle ::circle)
  (derive ::blue-circle ::circle)

Now combine can be specialised for these types of circles, but, if not, will 
fall back to the more general ::circle methods

This works because (from the docs):

    isa? works with vectors by calling isa? on their corresponding elements:

    (derive ::rect ::shape)
    (derive ::square ::rect)

    (isa? [::square ::rect] [::shape ::shape])
    -> true

Now the problem with :default 

I can define a single default combine method:

  (defmethod combine :default ...)

which will be called when none of the other methods match.

What I CAN"T do, as far as I can tell, is define a method for combining a 
::circle with any shape, i.e. this doesn't work

  (defmethod combine [::circle :default] ...)

because support for :default is not part of clojure's hierarchy mechanism, but 
part of defmulti/defmethod, and it doesn't have the special treatment of 
vectors.

I realise I could call (derive t ::shape) for each t from all the shape types 
in my program, but in my real code this is not at all convenient, and would 
introduce a dependency between two modules which I would like to avoid.

Am I overlooking a way to work around this? 

Someone proposed a fix back in 2009:

  https://groups.google.com/forum/#!topic/clojure/vFGTMEwasuM

but I wasn't able to trace where that went, or find any rationale for not 
merging the patch.

Thanks very much,

Tom

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.

Reply via email to