diff options
author | Konrad Hinsen <konrad.hinsen@laposte.net> | 2009-03-12 17:47:30 +0000 |
---|---|---|
committer | Konrad Hinsen <konrad.hinsen@laposte.net> | 2009-03-12 17:47:30 +0000 |
commit | 08cfc276dfc60d9a45b4dff7581597dd23682bfb (patch) | |
tree | 64d3823dbe05f0744e0ff025301cc4046362dc6b /src | |
parent | ea60eb05432f24f7244eb36a7f952236a04ebbb1 (diff) |
New module clojure.contrib.generic.arithmetic (experimental)
Diffstat (limited to 'src')
-rw-r--r-- | src/clojure/contrib/gen_html_docs.clj | 1 | ||||
-rw-r--r-- | src/clojure/contrib/generic/arithmetic.clj | 159 | ||||
-rw-r--r-- | src/clojure/contrib/load_all.clj | 1 |
3 files changed, 161 insertions, 0 deletions
diff --git a/src/clojure/contrib/gen_html_docs.clj b/src/clojure/contrib/gen_html_docs.clj index df9f9580..7cf62d9e 100644 --- a/src/clojure/contrib/gen_html_docs.clj +++ b/src/clojure/contrib/gen_html_docs.clj @@ -482,6 +482,7 @@ emits the generated HTML to the path named by path." 'clojure.contrib.error-kit 'clojure.contrib.except 'clojure.contrib.fcase + 'clojure.contrib.generic.arithmetic 'clojure.contrib.import-static 'clojure.contrib.javadoc 'clojure.contrib.javalog diff --git a/src/clojure/contrib/generic/arithmetic.clj b/src/clojure/contrib/generic/arithmetic.clj new file mode 100644 index 00000000..558ec37b --- /dev/null +++ b/src/clojure/contrib/generic/arithmetic.clj @@ -0,0 +1,159 @@ +;; Generic interfaces for arithmetic operations + +;; by Konrad Hinsen +;; last updated March 12, 2009 + +;; Copyright (c) Konrad Hinsen, 2009. All rights reserved. The use +;; and distribution terms for this software are covered by the Eclipse +;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) +;; which can be found in the file epl-v10.html at the root of this +;; distribution. By using this software in any fashion, you are +;; agreeing to be bound by the terms of this license. You must not +;; remove this notice, or any other, from this software. + +(ns clojure.contrib.generic.arithmetic + "Generic arithmetic interface + + NOTE: This library is VERY experimental. It WILL change significantly + with future release. + + This library defines generic versions of + - * / as multimethods + that can be defined for any type. The minimal required implementations + for a type are binary + and * plus unary - and /. Everything else + is derived from these automatically. Explicit binary definitions + for - and / can be given for efficiency reasons." + (:refer-clojure :exclude [+ - * /])) + +; +; A dispatch function that separates nulary, unary, binary, and +; higher arity calls and also selects on type for unary and binary +; calls. +; +(defn- nary-dispatch + ([] ::nulary) + ([x] [::unary (type x)]) + ([x y] + (let [tx (type x) + ty (type y)] + (cond (isa? tx ty) [::binary ty] + (isa? ty tx) [::binary tx] + ; Should there be clause checking if tx and ty have + ; a common ancestor? This would cover cases like + ; java.lang.Integer and java.lang.Double, which have the + ; common ancestor java.lang.Number. + :else [::binary tx ty]))) + ([x y & more] ::n-ary)) + +; +; We can't use [::binary :default], so we need to define a root type +; of the type hierarcy. The derivation for Object covers all classes, +; but all non-class types will need an explicit derive clause. +; Ultimately, a macro might take care of this. +; +(derive Object ::any) + +; +; Addition +; +; The minimal implementation is for [::binary my-type]. It is possible +; in principle to implement [::unary my-type] as well, though this +; doesn't make any sense. +; +(defmulti + nary-dispatch) + +(defmethod + ::nulary + [] + ::zero) + +(defmethod + [::unary ::any] + [x] x) + +(defmethod + ::n-ary + [x y & more] + (if more + (recur (+ x y) (first more) (next more)) + (+ x y))) + +; +; Subtraction +; +; The minimal implementation is for [::unary my-type]. A default binary +; implementation is provided as (+ x (- y)), but it is possible to +; implement [::unary my-type] explicitly for efficiency reasons. +; +(defmulti - nary-dispatch) + +(defmethod - ::nulary + [] + (throw (java.lang.IllegalArgumentException. + "Wrong number of arguments passed"))) + +(defmethod - [::binary ::any] + [x y] (+ x (- y))) + +(defmethod - ::n-ary + [x y & more] + (if more + (recur (- x y) (first more) (next more)) + (- x y))) + +; +; Multiplication +; +; The minimal implementation is for [::binary my-type]. It is possible +; in principle to implement [::unary my-type] as well, though this +; doesn't make any sense. +; +(defmulti * nary-dispatch) + +(defmethod * ::nulary + [] + ::one) + +(defmethod * [::unary ::any] + [x] x) + +(defmethod * ::n-ary + [x y & more] + (if more + (recur (* x y) (first more) (next more)) + (* x y))) + +; +; Division +; +; The minimal implementation is for [::unary my-type]. A default binary +; implementation is provided as (* x (/ y)), but it is possible to +; implement [::unary my-type] explicitly for efficiency reasons. +; +(defmulti / nary-dispatch) + +(defmethod / ::nulary + [] + (throw (java.lang.IllegalArgumentException. + "Wrong number of arguments passed"))) + +(defmethod / [::binary ::any] + [x y] (* x (/ y))) + +(defmethod / ::n-ary + [x y & more] + (if more + (recur (/ x y) (first more) (next more)) + (/ x y))) + +; +; Minimal implementations for java.lang.Number +; +(defmethod + [::binary java.lang.Number] + [x y] (clojure.core/+ x y)) + +(defmethod - [::unary java.lang.Number] + [x] (clojure.core/- x)) + +(defmethod * [::binary java.lang.Number] + [x y] (clojure.core/* x y)) + +(defmethod / [::unary java.lang.Number] + [x] (clojure.core// x)) + diff --git a/src/clojure/contrib/load_all.clj b/src/clojure/contrib/load_all.clj index 94bc8e91..f2b77bac 100644 --- a/src/clojure/contrib/load_all.clj +++ b/src/clojure/contrib/load_all.clj @@ -42,6 +42,7 @@ duck-streams error-kit except fcase +generic.arithmetic import-static javadoc.browse javadoc |