As I posted a couple weeks ago, I've been finding it awkward that
Clojure doesn't have too many math functions that know how to "do the
right thing" with the various numeric types it uses.  The one that's
been bothering me the most is the lack of an expt function.  Calling
Math/pow automatically coerces everything to doubles, which isn't
necessarily the desired behavior.

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))

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Attachment: expt.clj
Description: Binary data

Reply via email to