So I took this as an opportunity to learn how Clojure's multimethods
work, and coded up a sample expt implementation, which I've attached
and pasted below. I'd like to hear some comments on whether I'm
utilizing multimethods correctly, and whether functions like this
would be beneficial for inclusion in the clojure contribs. If people
find this useful, there are a few other math functions which would
benefit from this sort of conversion as well.
(derive java.lang.Integer ::exact)
(derive java.lang.Integer ::integer)
(derive java.math.BigInteger ::exact)
(derive java.math.BigInteger ::integer)
(derive java.lang.Long ::exact)
(derive java.lang.Long ::integer)
(derive java.math.BigDecimal ::exact)
(derive clojure.lang.Ratio ::exact)
(derive java.lang.Double ::inexact)
(defmulti expt (fn [x y] [(class x) (class y)]))
(defn- expt-int [base pow]
(loop [n pow, y 1, z base]
(let [t (bit-and n 1), n (bit-shift-right n 1)]
(cond
(zero? t) (recur n y (* z z))
(zero? n) (* z y)
:else (recur n (* z y) (* z z))))))
(defmethod expt [::exact ::integer] [base pow]
(cond
(pos? pow) (expt-int base pow)
(zero? pow) 1
:else (/ 1 (expt-int base (- pow)))))
(defmethod expt :default [base pow] (Math/pow base pow))
> and pasted below. I'd like to hear some comments on whether I'm
> utilizing multimethods correctly,
I can't say, being new to multimethods as well, but...
> and whether functions like this
> would be beneficial for inclusion in the clojure contribs. If people
> find this useful, there are a few other math functions which would
> benefit from this sort of conversion as well.
... I think that this kind of routine is very useful and I'd
appreciate having it in clojure-contrib.
Konrad.