5

I have a defmulti/defmethod group that take pairs of arguments like so...

(defmulti foo "some explanation" (fn [arg1 arg2] (mapv class [arg1 arg2])))
(defmethod foo [N P] (->L 1 2 3))
(defmethod foo [L P] (->N 5))
(defmethod foo [P N] (->L 6 7 8))
 ...

Which are called in the way you might expect.

(foo (->N 9) (->P 9))

What I would like is to call 'foo' with more than 2 arguments. I know how to do this with functions and I suppose I could use some wrapper function that split the args into pairs and then combined the result (or just use 'reduce') but that seems wrong.

My question then is... What is the idiomatic way to define a variadic multi-function in clojure?

phreed
  • 1,759
  • 1
  • 15
  • 30
  • 1
    Same way you make regular functions variatic - give the dispatch function and `defmethod` bodies a variatic signature. – Alex Sep 30 '14 at 21:25
  • Thanks, I just found this... http://stackoverflow.com/questions/10313657/is-it-possible-to-overload-clojure-multi-methods-on-arity – phreed Sep 30 '14 at 21:41

1 Answers1

6

There's nothing wrong with giving the defmulti dispatch function and defmethod bodies variadic signatures, and this is perfectly idiomatic:

(defmulti bar (fn [x & y] (class x)))
(defmethod bar String [x & y] (str "string: " (count y)))
(defmethod bar Number [x & y] (str "number: " (count y)))

(bar "x" 1 2 3) ;=> "string: 3"
(bar 1 2 3) ;=> "number: 2"
Alex
  • 13,811
  • 1
  • 37
  • 50
  • I used your answer to construct a sample in clojuredocs. http://clojuredocs.org/clojure.core/defmulti#example_542c2058e4b05f4d257a2966 – phreed Oct 02 '14 at 15:49