aboutsummaryrefslogtreecommitdiff
path: root/modules/generic/src
diff options
context:
space:
mode:
authorStuart Sierra <mail@stuartsierra.com>2010-08-07 16:41:53 -0400
committerStuart Sierra <mail@stuartsierra.com>2010-08-07 16:41:53 -0400
commita6a92b9b3d2bfd9a56e1e5e9cfba706d1aeeaae5 (patch)
treef1f3da9887dc2dc557df3282b0bcbd4d701ec593 /modules/generic/src
parente7930c85290f77815cdb00a60604feedfa2d0194 (diff)
Split all namespaces into sub-modules.
* Examples and tests have not been copied over. * Clojure test/compile phases are commented out in parent POM. * May require installing parent POM before full build.
Diffstat (limited to 'modules/generic/src')
-rw-r--r--modules/generic/src/main/clojure/clojure/contrib/generic.clj54
-rw-r--r--modules/generic/src/main/clojure/clojure/contrib/generic/arithmetic.clj201
-rw-r--r--modules/generic/src/main/clojure/clojure/contrib/generic/collection.clj116
-rw-r--r--modules/generic/src/main/clojure/clojure/contrib/generic/comparison.clj214
-rw-r--r--modules/generic/src/main/clojure/clojure/contrib/generic/functor.clj40
-rw-r--r--modules/generic/src/main/clojure/clojure/contrib/generic/math_functions.clj114
6 files changed, 739 insertions, 0 deletions
diff --git a/modules/generic/src/main/clojure/clojure/contrib/generic.clj b/modules/generic/src/main/clojure/clojure/contrib/generic.clj
new file mode 100644
index 00000000..44cc6db7
--- /dev/null
+++ b/modules/generic/src/main/clojure/clojure/contrib/generic.clj
@@ -0,0 +1,54 @@
+;; Support code for generic interfaces
+
+;; by Konrad Hinsen
+;; last updated May 4, 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
+ ^{:author "Konrad Hinsen"
+ :skip-wiki true
+ :doc "Generic interfaces
+ This library provides generic interfaces in the form of
+ multimethods that can be implemented for any type.
+ The interfaces partly duplicate existing non-generic
+ functions in clojure.core (arithmetic, comparison,
+ collections) and partly provide additional functions that
+ can be defined for a wide variety of types (functors, math
+ functions). More functions will be added in the future."}
+ clojure.contrib.generic
+ (:use [clojure.contrib.types :only (defadt)]))
+
+;
+; 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] (type x))
+ ([x y]
+ [(type x) (type y)])
+ ([x y & more] ::nary))
+
+;
+; 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.
+;
+(def root-type ::any)
+(derive Object root-type)
+
+;
+; Symbols referring to ::nulary and ::n-ary
+;
+(def nulary-type ::nulary)
+(def nary-type ::nary)
+
diff --git a/modules/generic/src/main/clojure/clojure/contrib/generic/arithmetic.clj b/modules/generic/src/main/clojure/clojure/contrib/generic/arithmetic.clj
new file mode 100644
index 00000000..04f2c318
--- /dev/null
+++ b/modules/generic/src/main/clojure/clojure/contrib/generic/arithmetic.clj
@@ -0,0 +1,201 @@
+;; Generic interfaces for arithmetic operations
+
+;; by Konrad Hinsen
+;; last updated May 5, 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
+ ^{:author "Konrad Hinsen"
+ :doc "Generic arithmetic interface
+ 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 provided for
+ efficiency reasons."}
+ clojure.contrib.generic.arithmetic
+ (:use [clojure.contrib.generic
+ :only (root-type nulary-type nary-type nary-dispatch)]
+ [clojure.contrib.types :only (defadt)])
+ (:refer-clojure :exclude [+ - * /]))
+
+;
+; Universal zero and one values
+;
+(defadt ::zero zero)
+(defadt ::one one)
+
+(derive ::zero root-type)
+(derive ::one root-type)
+
+;
+; 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 +
+ "Return the sum of all arguments. The minimal implementation for type
+ ::my-type is the binary form with dispatch value [::my-type ::my-type]."
+ {:arglists '([x] [x y] [x y & more])}
+ nary-dispatch)
+
+(defmethod + nulary-type
+ []
+ zero)
+
+(defmethod + root-type
+ [x] x)
+
+(defmethod + [root-type ::zero]
+ [x y] x)
+
+(defmethod + [::zero root-type]
+ [x y] y)
+
+(defmethod + nary-type
+ [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 -
+ "Return the difference of the first argument and the sum of all other
+ arguments. The minimal implementation for type ::my-type is the binary
+ form with dispatch value [::my-type ::my-type]."
+ {:arglists '([x] [x y] [x y & more])}
+ nary-dispatch)
+
+(defmethod - nulary-type
+ []
+ (throw (java.lang.IllegalArgumentException.
+ "Wrong number of arguments passed")))
+
+(defmethod - [root-type ::zero]
+ [x y] x)
+
+(defmethod - [::zero root-type]
+ [x y] (- y))
+
+(defmethod - [root-type root-type]
+ [x y] (+ x (- y)))
+
+(defmethod - nary-type
+ [x y & more]
+ (if more
+ (recur (- x y) (first more) (next more))
+ (- x y)))
+
+;
+; Multiplication
+;
+; The minimal implementation is for binary [my-type my-type]. It is possible
+; in principle to implement unary my-type as well, though this
+; doesn't make any sense.
+;
+(defmulti *
+ "Return the product of all arguments. The minimal implementation for type
+ ::my-type is the binary form with dispatch value [::my-type ::my-type]."
+ {:arglists '([x] [x y] [x y & more])}
+ nary-dispatch)
+
+(defmethod * nulary-type
+ []
+ one)
+
+(defmethod * root-type
+ [x] x)
+
+(defmethod * [root-type ::one]
+ [x y] x)
+
+(defmethod * [::one root-type]
+ [x y] y)
+
+(defmethod * nary-type
+ [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 binary [my-type my-type] explicitly for efficiency reasons.
+;
+(defmulti /
+ "Return the quotient of the first argument and the product of all other
+ arguments. The minimal implementation for type ::my-type is the binary
+ form with dispatch value [::my-type ::my-type]."
+ {:arglists '([x] [x y] [x y & more])}
+ nary-dispatch)
+
+(defmethod / nulary-type
+ []
+ (throw (java.lang.IllegalArgumentException.
+ "Wrong number of arguments passed")))
+
+(defmethod / [root-type ::one]
+ [x y] x)
+
+(defmethod / [::one root-type]
+ [x y] (/ y))
+
+(defmethod / [root-type root-type]
+ [x y] (* x (/ y)))
+
+(defmethod / nary-type
+ [x y & more]
+ (if more
+ (recur (/ x y) (first more) (next more))
+ (/ x y)))
+
+;
+; Macros to permit access to the / multimethod via namespace qualification
+;
+(defmacro defmethod*
+ "Define a method implementation for the multimethod name in namespace ns.
+ Required for implementing the division function from another namespace."
+ [ns name & args]
+ (let [qsym (symbol (str ns) (str name))]
+ `(defmethod ~qsym ~@args)))
+
+(defmacro qsym
+ "Create the qualified symbol corresponding to sym in namespace ns.
+ Required to access the division function from another namespace,
+ e.g. as (qsym clojure.contrib.generic.arithmetic /)."
+ [ns sym]
+ (symbol (str ns) (str sym)))
+
+;
+; Minimal implementations for java.lang.Number
+;
+(defmethod + [java.lang.Number java.lang.Number]
+ [x y] (clojure.core/+ x y))
+
+(defmethod - java.lang.Number
+ [x] (clojure.core/- x))
+
+(defmethod * [java.lang.Number java.lang.Number]
+ [x y] (clojure.core/* x y))
+
+(defmethod / java.lang.Number
+ [x] (clojure.core// x))
+
diff --git a/modules/generic/src/main/clojure/clojure/contrib/generic/collection.clj b/modules/generic/src/main/clojure/clojure/contrib/generic/collection.clj
new file mode 100644
index 00000000..cdca97fb
--- /dev/null
+++ b/modules/generic/src/main/clojure/clojure/contrib/generic/collection.clj
@@ -0,0 +1,116 @@
+;; Generic interfaces for collection-related functions
+
+;; by Konrad Hinsen
+;; last updated May 5, 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
+ ^{:author "Konrad Hinsen"
+ :doc "Generic arithmetic interface
+ This library defines generic versions of common
+ collection-related functions as multimethods that can be
+ defined for any type."}
+ clojure.contrib.generic.collection
+ (:refer-clojure :exclude [assoc conj dissoc empty get into seq]))
+
+;
+; assoc
+;
+(defmulti assoc
+ "Returns a new collection in which the values corresponding to the
+ given keys are updated by the given values. Each type of collection
+ can have specific restrictions on the possible keys."
+ {:arglists '([coll & key-val-pairs])}
+ (fn [coll & items] (type coll)))
+
+(defmethod assoc :default
+ [map & key-val-pairs]
+ (apply clojure.core/assoc map key-val-pairs))
+
+; assoc-in
+
+;
+; conj
+;
+(defmulti conj
+ "Returns a new collection resulting from adding all xs to coll."
+ {:arglists '([coll & xs])}
+ (fn [coll & xs] (type coll)))
+
+(defmethod conj :default
+ [coll & xs]
+ (apply clojure.core/conj coll xs))
+
+;
+; diassoc
+;
+(defmulti dissoc
+ "Returns a new collection in which the entries corresponding to the
+ given keys are removed. Each type of collection can have specific
+ restrictions on the possible keys."
+ {:arglists '([coll & keys])}
+ (fn [coll & keys] (type coll)))
+
+(defmethod dissoc :default
+ [map & keys]
+ (apply clojure.core/dissoc map keys))
+
+;
+; empty
+;
+(defmulti empty
+ "Returns an empty collection of the same kind as the argument"
+ {:arglists '([coll])}
+ type)
+
+(defmethod empty :default
+ [coll]
+ (clojure.core/empty coll))
+
+;
+; get
+;
+(defmulti get
+ "Returns the element of coll referred to by key. Each type of collection
+ can have specific restrictions on the possible keys."
+ {:arglists '([coll key] [coll key not-found])}
+ (fn [coll & args] (type coll)))
+
+(defmethod get :default
+ ([coll key]
+ (clojure.core/get coll key))
+ ([coll key not-found]
+ (clojure.core/get coll key not-found)))
+
+;
+; into
+;
+(defmulti into
+ "Returns a new coll consisting of to-coll with all of the items of
+ from-coll conjoined."
+ {:arglists '([to from])}
+ (fn [to from] (type to)))
+
+(declare seq)
+(defmethod into :default
+ [to from]
+ (reduce conj to (seq from)))
+
+;
+; seq
+;
+(defmulti seq
+ "Returns a seq on the object s."
+ {:arglists '([s])}
+ type)
+
+(defmethod seq :default
+ [s]
+ (clojure.core/seq s))
diff --git a/modules/generic/src/main/clojure/clojure/contrib/generic/comparison.clj b/modules/generic/src/main/clojure/clojure/contrib/generic/comparison.clj
new file mode 100644
index 00000000..e41b0792
--- /dev/null
+++ b/modules/generic/src/main/clojure/clojure/contrib/generic/comparison.clj
@@ -0,0 +1,214 @@
+;; Generic interfaces for comparison operations
+
+;; by Konrad Hinsen
+;; last updated May 25, 2010
+
+;; Copyright (c) Konrad Hinsen, 2009-2010. 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
+ ^{:author "Konrad Hinsen"
+ :doc "Generic comparison interface
+ This library defines generic versions of = < > <= >= zero?
+ as multimethods that can be defined for any type. Of the
+ greater/less-than relations, types must minimally implement >."}
+ clojure.contrib.generic.comparison
+ (:refer-clojure :exclude [= < > <= >= zero? pos? neg? min max])
+ (:use [clojure.contrib.generic
+ :only (root-type nulary-type nary-type nary-dispatch)]))
+
+;
+; zero? pos? neg?
+;
+(defmulti zero?
+ "Return true of x is zero."
+ {:arglists '([x])}
+ type)
+
+(defmulti pos?
+ "Return true of x is positive."
+ {:arglists '([x])}
+ type)
+
+(defmulti neg?
+ "Return true of x is negative."
+ {:arglists '([x])}
+ type)
+
+;
+; Equality
+;
+(defmulti =
+ "Return true if all arguments are equal. The minimal implementation for type
+ ::my-type is the binary form with dispatch value [::my-type ::my-type]."
+ {:arglists '([x] [x y] [x y & more])}
+ nary-dispatch)
+
+(defmethod = root-type
+ [x] true)
+
+(defmethod = nary-type
+ [x y & more]
+ (if (= x y)
+ (if (next more)
+ (recur y (first more) (next more))
+ (= y (first more)))
+ false))
+
+;
+; Greater-than
+;
+(defmulti >
+ "Return true if each argument is larger than the following ones.
+ The minimal implementation for type ::my-type is the binary form
+ with dispatch value [::my-type ::my-type]."
+ {:arglists '([x] [x y] [x y & more])}
+ nary-dispatch)
+
+(defmethod > root-type
+ [x] true)
+
+(defmethod > nary-type
+ [x y & more]
+ (if (> x y)
+ (if (next more)
+ (recur y (first more) (next more))
+ (> y (first more)))
+ false))
+
+;
+; Less-than defaults to greater-than with arguments inversed
+;
+(defmulti <
+ "Return true if each argument is smaller than the following ones.
+ The minimal implementation for type ::my-type is the binary form
+ with dispatch value [::my-type ::my-type]. A default implementation
+ is provided in terms of >."
+ {:arglists '([x] [x y] [x y & more])}
+ nary-dispatch)
+
+(defmethod < root-type
+ [x] true)
+
+(defmethod < [root-type root-type]
+ [x y]
+ (> y x))
+
+(defmethod < nary-type
+ [x y & more]
+ (if (< x y)
+ (if (next more)
+ (recur y (first more) (next more))
+ (< y (first more)))
+ false))
+
+;
+; Greater-or-equal defaults to (complement <)
+;
+(defmulti >=
+ "Return true if each argument is larger than or equal to the following
+ ones. The minimal implementation for type ::my-type is the binary form
+ with dispatch value [::my-type ::my-type]. A default implementation
+ is provided in terms of <."
+ {:arglists '([x] [x y] [x y & more])}
+ nary-dispatch)
+
+(defmethod >= root-type
+ [x] true)
+
+(defmethod >= [root-type root-type]
+ [x y]
+ (not (< x y)))
+
+(defmethod >= nary-type
+ [x y & more]
+ (if (>= x y)
+ (if (next more)
+ (recur y (first more) (next more))
+ (>= y (first more)))
+ false))
+
+;
+; Less-than defaults to (complement >)
+;
+(defmulti <=
+ "Return true if each arguments is smaller than or equal to the following
+ ones. The minimal implementation for type ::my-type is the binary form
+ with dispatch value [::my-type ::my-type]. A default implementation
+ is provided in terms of >."
+ {:arglists '([x] [x y] [x y & more])}
+ nary-dispatch)
+
+(defmethod <= root-type
+ [x] true)
+
+(defmethod <= [root-type root-type]
+ [x y]
+ (not (> x y)))
+
+(defmethod <= nary-type
+ [x y & more]
+ (if (<= x y)
+ (if (next more)
+ (recur y (first more) (next more))
+ (<= y (first more)))
+ false))
+
+;
+; Implementations for Clojure's built-in types
+;
+(defmethod zero? java.lang.Number
+ [x]
+ (clojure.core/zero? x))
+
+(defmethod pos? java.lang.Number
+ [x]
+ (clojure.core/pos? x))
+
+(defmethod neg? java.lang.Number
+ [x]
+ (clojure.core/neg? x))
+
+(defmethod = [Object Object]
+ [x y]
+ (clojure.core/= x y))
+
+(defmethod > [java.lang.Number java.lang.Number]
+ [x y]
+ (clojure.core/> x y))
+
+(defmethod < [java.lang.Number java.lang.Number]
+ [x y]
+ (clojure.core/< x y))
+
+(defmethod >= [java.lang.Number java.lang.Number]
+ [x y]
+ (clojure.core/>= x y))
+
+(defmethod <= [java.lang.Number java.lang.Number]
+ [x y]
+ (clojure.core/<= x y))
+
+;
+; Functions defined in terms of the comparison operators
+;
+(defn max
+ "Returns the greatest of its arguments. Like clojure.core/max except that
+ is uses generic comparison functions implementable for any data type."
+ ([x] x)
+ ([x y] (if (> x y) x y))
+ ([x y & more]
+ (reduce max (max x y) more)))
+
+(defn min
+ "Returns the least of its arguments. Like clojure.core/min except that
+ is uses generic comparison functions implementable for any data type."
+ ([x] x)
+ ([x y] (if (< x y) x y))
+ ([x y & more]
+ (reduce min (min x y) more)))
diff --git a/modules/generic/src/main/clojure/clojure/contrib/generic/functor.clj b/modules/generic/src/main/clojure/clojure/contrib/generic/functor.clj
new file mode 100644
index 00000000..4728eaab
--- /dev/null
+++ b/modules/generic/src/main/clojure/clojure/contrib/generic/functor.clj
@@ -0,0 +1,40 @@
+;; Generic interface for functors
+
+;; by Konrad Hinsen
+;; last updated May 3, 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
+ ^{:author "Konrad Hinsen"
+ :doc "Generic functor interface (fmap)"}
+ clojure.contrib.generic.functor)
+
+
+(defmulti fmap
+ "Applies function f to each item in the data structure s and returns
+ a structure of the same kind."
+ {:arglists '([f s])}
+ (fn [f s] (type s)))
+
+(defmethod fmap clojure.lang.IPersistentList
+ [f v]
+ (into (empty v) (map f v)))
+
+(defmethod fmap clojure.lang.IPersistentVector
+ [f v]
+ (into (empty v) (map f v)))
+
+(defmethod fmap clojure.lang.IPersistentMap
+ [f m]
+ (into (empty m) (for [[k v] m] [k (f v)])))
+
+(defmethod fmap clojure.lang.IPersistentSet
+ [f s]
+ (into (empty s) (map f s)))
diff --git a/modules/generic/src/main/clojure/clojure/contrib/generic/math_functions.clj b/modules/generic/src/main/clojure/clojure/contrib/generic/math_functions.clj
new file mode 100644
index 00000000..c0918840
--- /dev/null
+++ b/modules/generic/src/main/clojure/clojure/contrib/generic/math_functions.clj
@@ -0,0 +1,114 @@
+;; Generic interfaces for mathematical functions
+
+;; by Konrad Hinsen
+;; last updated May 5, 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
+ ^{:author "Konrad Hinsen"
+ :doc "Generic math function interface
+ This library defines generic versions of common mathematical
+ functions such as sqrt or sin as multimethods that can be
+ defined for any type."}
+ clojure.contrib.generic.math-functions
+ (:use [clojure.contrib.def :only (defmacro-)])
+ (:require [clojure.contrib.generic.arithmetic :as ga]
+ [clojure.contrib.generic.comparison :as gc]))
+
+(defmacro- defmathfn-1
+ [name]
+ (let [java-symbol (symbol "java.lang.Math" (str name))]
+ `(do
+ (defmulti ~name
+ ~(str "Return the " name " of x.")
+ {:arglists '([~'x])}
+ type)
+ (defmethod ~name java.lang.Number
+ [~'x]
+ (~java-symbol ~'x)))))
+
+(defn- two-types [x y] [(type x) (type y)])
+
+(defmacro- defmathfn-2
+ [name]
+ (let [java-symbol (symbol "java.lang.Math" (str name))]
+ `(do
+ (defmulti ~name
+ ~(str "Return the " name " of x and y.")
+ {:arglists '([~'x ~'y])}
+ two-types)
+ (defmethod ~name [java.lang.Number java.lang.Number]
+ [~'x ~'y]
+ (~java-symbol ~'x ~'y)))))
+
+; List of math functions taken from
+; http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Math.html
+(defmathfn-1 abs)
+(defmathfn-1 acos)
+(defmathfn-1 asin)
+(defmathfn-1 atan)
+(defmathfn-2 atan2)
+(defmathfn-1 ceil)
+(defmathfn-1 cos)
+(defmathfn-1 exp)
+(defmathfn-1 floor)
+(defmathfn-1 log)
+(defmathfn-2 pow)
+(defmathfn-1 rint)
+(defmathfn-1 round)
+(defmathfn-1 sin)
+(defmathfn-1 sqrt)
+(defmathfn-1 tan)
+
+;
+; Sign
+;
+(defmulti sgn
+ "Return the sign of x (-1, 0, or 1)."
+ {:arglists '([x])}
+ type)
+
+(defmethod sgn :default
+ [x]
+ (cond (gc/zero? x) 0
+ (gc/> x 0) 1
+ :else -1))
+
+;
+; Conjugation
+;
+(defmulti conjugate
+ "Return the conjugate of x."
+ {:arglists '([x])}
+ type)
+
+(defmethod conjugate :default
+ [x] x)
+
+;
+; Square
+;
+(defmulti sqr
+ "Return the square of x."
+ {:arglists '([x])}
+ type)
+
+(defmethod sqr :default
+ [x]
+ (ga/* x x))
+
+;
+; Approximate equality for use with floating point types
+;
+(defn approx=
+ "Return true if the absolute value of the difference between x and y
+ is less than eps."
+ [x y eps]
+ (gc/< (abs (ga/- x y)) eps))