Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to code a variadic defmulti/defmethod in clojure

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?

like image 698
phreed Avatar asked Sep 30 '14 21:09

phreed


1 Answers

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"
like image 72
Alex Avatar answered Nov 05 '22 16:11

Alex