Commits

Meikel Brandmeyer  committed c918c02

Moved LazyMap to reify

  • Participants
  • Parent commits ea41695
  • Branches new

Comments (0)

Files changed (3)

             <sysproperty key="clojure.compile.path" value="${classes.dir}"/>
             <arg value="de.kotka.lazymap.LazyMapEntry"/>
             <arg value="de.kotka.lazymap.LazyMapSeq"/>
-            <arg value="de.kotka.lazymap.LazyMap"/>
             <arg value="de.kotka.lazymap"/>
         </java>
     </target>

File src/de/kotka/lazymap.clj

   lazy-hash-map, lazy-sorted-map, lazy-struct-map, lazy-struct, lazy-assoc
   and their * counterpart functions."
   (:import
-     (de.kotka.lazymap LazyMap)))
+     clojure.lang.IObj
+     clojure.lang.IFn
+     clojure.lang.IMapEntry
+     clojure.lang.IPersistentVector
+     clojure.lang.SeqIterator
+     de.kotka.lazymap.LazyMapEntry
+     de.kotka.lazymap.LazyMapSeq))
+
+(gen-interface
+  :name    de.kotka.lazymap.ILazyMap
+  :extends [clojure.lang.IPersistentMap]
+  :methods [[lazyAssoc [Object Object] de.kotka.lazymap.ILazyMap]])
+
+(import 'de.kotka.lazymap.ILazyMap)
+
+(defn create-lazy-map
+  ([base]
+   (create-lazy-map base nil))
+  ([base metadata]
+   (reify this [ILazyMap IFn IObj]
+     ; ILazyMap
+     (.lazyAssoc
+       [k v]
+       (create-lazy-map (assoc base k v) metadata))
+     ; IPersistentMap
+     (.assoc
+       [k v]
+       (create-lazy-map (assoc base k (delay v)) metadata))
+     (.assocEx
+       [k v]
+       (when (.containsKey base k)
+         (throw (Exception. (str "Key already present in map: " k))))
+       (.assoc this k v))
+     (.without
+       [k]
+       (create-lazy-map (dissoc base k) metadata))
+     ; Associative
+     (.containsKey
+       [k]
+       (contains? base k))
+     (.entryAt
+       [k]
+       (LazyMapEntry. k (base k)))
+     ; IPersistentCollection
+     (.count
+       []
+       (count base))
+     (.cons
+       [o]
+       (condp instance? o
+         LazyMapEntry      (let [#^LazyMapEntry o o]
+                             (let [k (.getKey o)
+                                   v (.getRawValue o)]
+                               (.lazyAssoc this k v)))
+         IMapEntry         (let [#^IMapEntry o o]
+                             (let [k (.getKey o)
+                                   v (.getValue o)]
+                               (.assoc this k (delay v))))
+         IPersistentVector (if (= (count o) 2)
+                             (let [k (o 0)
+                                   v (o 1)]
+                               (.assoc this k (delay v)))
+                             (throw (IllegalArgumentException.
+                                      "Vector arg to map conj must be a pair")))
+         (reduce #(.cons #^ILazyMap %1 %2) this o)))
+     (.empty
+       []
+       (create-lazy-map (empty base) nil))
+     ; ILookup
+     (.valAt
+       [k]
+       (.valAt this k nil))
+     (.valAt
+       [k not-found]
+       (if (contains? base k)
+         (-> base (get k) force)
+         not-found))
+     ; IFn
+     (.invoke
+       [k]
+       (.valAt this k nil))
+     (.invoke
+       [k not-found]
+       (.valAt this k not-found))
+     (.applyTo
+       [args]
+       (let [[k v & rest-args :as args] (seq args)]
+         (when (or (not args) rest-args)
+           (throw (Exception. "lazy map must be called with one or two arguments")))
+         (.valAt this k v)))
+     ; Seqable
+     (.seq
+       []
+       (when-let [inner-seq (seq base)]
+         (LazyMapSeq. inner-seq)))
+     ; IObj
+     (.withMeta
+       [new-metadata]
+       (create-lazy-map base new-metadata))
+     ; IMeta
+     (.meta
+       []
+       metadata)
+     ; Iterable
+     (.iterator
+       []
+       (-> this .seq SeqIterator.)))))
 
 (defn- quote-values
   [kvs]
   "lazy-hash-map* is the same as lazy-hash-map except that its a function
   and it takes a seq of keys-delayed-value pairs."
   [& kvs]
-  (LazyMap. (apply hash-map kvs)))
+  (create-lazy-map (apply hash-map kvs)))
 
 (defmacro lazy-hash-map
   "lazy-hash-map creates a map. The values are not evaluated before their
   "lazy-sorted-map* is the same as lazy-sorted-map except that its a
   function and it takes a seq of keys-delayed-value pairs."
   [& kvs]
-  (LazyMap. (apply sorted-map kvs)))
+  (create-lazy-map (apply sorted-map kvs)))
 
 (defmacro lazy-sorted-map
   "lazy-sorted-map creates a map. The values are not evaluated before their
   function and it takes a seq of keys-delayed-value pairs together with the
   struct basis."
   [s & kvs]
-  (LazyMap. (apply struct-map s kvs)))
+  (create-lazy-map (apply struct-map s kvs)))
 
 (defmacro lazy-struct-map
   "lazy-struct-map creates a map. The values are not evaluated before their
   "lazy-struct* is the same as lazy-struct except that its a function and
   it takes a seq of delayed value together with the struct basis."
   [s & vs]
-  (LazyMap. (apply struct s vs)))
+  (create-lazy-map (apply struct s vs)))
 
 (defmacro lazy-struct
   "lazy-struct creates a map. The values are not evaluated before their

File src/de/kotka/lazymap/LazyMap.clj

-;-
-; Copyright 2008,2009 (c) Meikel Brandmeyer.
-; All rights reserved.
-;
-; Permission is hereby granted, free of charge, to any person obtaining a copy
-; of this software and associated documentation files (the "Software"), to deal
-; in the Software without restriction, including without limitation the rights
-; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-; copies of the Software, and to permit persons to whom the Software is
-; furnished to do so, subject to the following conditions:
-;
-; The above copyright notice and this permission notice shall be included in
-; all copies or substantial portions of the Software.
-;
-; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-; THE SOFTWARE.
-
-(clojure.core/ns de.kotka.lazymap.LazyMap
-  (:gen-class
-     :init         init
-     :state        theMap
-     :extends      clojure.lang.APersistentMap
-     :methods      [[lazyAssoc [Object Object] clojure.lang.IPersistentMap]]
-     :constructors {[clojure.lang.IPersistentMap] []
-                    [clojure.lang.IPersistentMap clojure.lang.IPersistentMap]
-                    [clojure.lang.IPersistentMap]})
-  (:import
-     (clojure.lang SeqIterator IMapEntry IPersistentVector IObj)))
-
-(defn- -init
-  ([theMap]
-   [[] theMap])
-  ([theMap metaData]
-   [[metaData] theMap]))
-
-(defn- -lazyAssoc
-  [#^de.kotka.lazymap.LazyMap this k v]
-  (de.kotka.lazymap.LazyMap. (-> this .theMap (assoc k v))))
-
-; IObj
-(defn- -withMeta
-  [#^de.kotka.lazymap.LazyMap this meta-data]
-  (de.kotka.lazymap.LazyMap. (.theMap this) meta-data))
-
-; IPersistentMap
-(defn- -assoc
-  [#^de.kotka.lazymap.LazyMap this k v]
-  (de.kotka.lazymap.LazyMap. (-> this .theMap (assoc k (delay v)))))
-
-(defn- -assocEx
-  [#^de.kotka.lazymap.LazyMap this k v]
-  (when (.containsKey this k)
-    (throw (Exception. (str "Key alread present: " k))))
-  (.assoc this k v))
-
-(defn- -without
-  [#^de.kotka.lazymap.LazyMap this k]
-  (-> this .theMap (dissoc k) de.kotka.lazymap.LazyMap.))
-
-; Associative
-(defn- -containsKey
-  [#^de.kotka.lazymap.LazyMap this k]
-  (-> this .theMap (contains? k)))
-
-(defn- -entryAt
-  [#^de.kotka.lazymap.LazyMap this k]
-  (when (.containsKey this k)
-    (de.kotka.lazymap.LazyMapEntry. k (-> this .theMap (get k)))))
-
-(defn- -valAt
-  ([#^de.kotka.lazymap.LazyMap this k]
-   (.valAt this k nil))
-  ([#^de.kotka.lazymap.LazyMap this k nf]
-   (if (-> this .theMap (contains? k))
-     (-> this .theMap (get k) force)
-     nf)))
-
-; Iterable
-(defn- -iterator
-  [#^de.kotka.lazymap.LazyMap this]
-  (-> this .seq SeqIterator.))
-
-; IPersistentCollection
-(defn- -count
-  [#^de.kotka.lazymap.LazyMap this]
-  (-> this .theMap count))
-
-(defn- -seq
-  [#^de.kotka.lazymap.LazyMap this]
-  (when-let [inner-seq (-> this .theMap seq)]
-    (de.kotka.lazymap.LazyMapSeq. inner-seq)))
-
-(defn- -cons
-  [#^de.kotka.lazymap.LazyMap this o]
-  (condp instance? o
-    de.kotka.lazymap.LazyMapEntry
-                      (let [#^de.kotka.lazymap.LazyMapEntry o o]
-                        (let [k (.getKey o)
-                              v (.getRawValue o)]
-                          (.lazyAssoc this k v)))
-    IMapEntry         (let [#^IMapEntry o o]
-                        (let [k (.getKey o)
-                              v (.getValue o)]
-                          (.assoc this k (delay v))))
-    IPersistentVector (if (= (count o) 2)
-                        (let [k (o 0)
-                              v (o 1)]
-                          (.assoc this k (delay v)))
-                        (throw (IllegalArgumentException.
-                                    "Vector arg to map conj must be a pair")))
-    (reduce #(.cons #^de.kotka.lazymap.LazyMap %1 %2) this o)))
-
-(defn- -empty
-  [#^de.kotka.lazymap.LazyMap this]
-  (-> this .theMap empty de.kotka.lazymap.LazyMap.))