Skip to content

Commit 0a234ee

Browse files
committed
fix: replace lazymap dependency for one in tree
1 parent e75142a commit 0a234ee

File tree

5 files changed

+252
-6
lines changed

5 files changed

+252
-6
lines changed

deps.edn

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
{:paths ["src"]
2-
:deps {prismatic/schema {:mvn/version "1.2.0"}
3-
de.kotka/lazymap {:mvn/version "3.1.0"}}}
2+
:deps {prismatic/schema {:mvn/version "1.2.0"}}}

project.clj

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
:url "http://www.eclipse.org/legal/epl-v10.html"
66
:distribution :repo}
77

8-
:dependencies [[prismatic/schema "1.2.0"]
9-
[de.kotka/lazymap "3.1.0" :exclusions [org.clojure/clojure]]]
8+
:dependencies [[prismatic/schema "1.2.0"]]
109

1110
:profiles {:dev {:dependencies [[org.clojure/clojure "1.10.3"]
1211
[org.clojure/clojurescript "1.10.891"]

src/plumbing/graph.cljc

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
For more details and examples of Graphs, see test/plumbing/graph_examples_test.cljx."
2323
(:refer-clojure :exclude [compile])
2424
(:require
25-
#?(:clj [lazymap.core :as lazymap])
25+
#?(:clj [plumbing.lazymap :as lazymap])
2626
[schema.core :as s]
2727
#?(:clj [schema.macros :as schema-macros])
2828
[plumbing.fnk.schema :as schema #?@(:cljs [:include-macros true])]

src/plumbing/lazymap.clj

+248
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
;-
2+
; Copyright 2008-2011 (c) Meikel Brandmeyer.
3+
; All rights reserved.
4+
;
5+
; Permission is hereby granted, free of charge, to any person obtaining a copy
6+
; of this software and associated documentation files (the "Software"), to deal
7+
; in the Software without restriction, including without limitation the rights
8+
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
; copies of the Software, and to permit persons to whom the Software is
10+
; furnished to do so, subject to the following conditions:
11+
;
12+
; The above copyright notice and this permission notice shall be included in
13+
; all copies or substantial portions of the Software.
14+
;
15+
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
; THE SOFTWARE.
22+
23+
;; Retreived from https://bitbucket.org/kotarak/lazymap/raw/5a2437e70a91/src/main/clojure/lazymap/core.clj
24+
;; by JW on 11/17/2011, and slightly modified to fix a bug in .entryAt and add a safety check.
25+
;; Also replaced 'force' with 'deref' so this can be used with futures (with marginal utility).
26+
;; (our pull request with these changes has been been ignored, so we've just included
27+
;; this fixed file in plumbing for the time being).
28+
29+
;; Known Issues: LazyMapEntries are not equal to persistent vectors like ordinary map entries.
30+
31+
32+
(ns plumbing.lazymap
33+
"Lazymap is to maps what lazy-seq is to lists. It allows to store values
34+
with evaluating them. This is only done in case the value is really accessed.
35+
Lazymap works with any map type (hash-map, sorted-map, struct-map) and may
36+
be used as a drop-in replacement everywhere where a normal map type may be
37+
used.
38+
Available macros:
39+
lazy-hash-map, lazy-sorted-map, lazy-struct-map, lazy-struct, lazy-assoc
40+
and their * counterpart functions."
41+
(:import
42+
clojure.lang.IObj
43+
clojure.lang.IFn
44+
clojure.lang.ILookup
45+
clojure.lang.IMapEntry
46+
clojure.lang.IPersistentMap
47+
clojure.lang.IPersistentVector
48+
clojure.lang.ASeq
49+
clojure.lang.ISeq
50+
clojure.lang.Seqable
51+
clojure.lang.SeqIterator))
52+
53+
(defprotocol ILazyMapEntry
54+
"ILazyMapEntry describes the behaviour of a lazy MapEntry. It provides
55+
an additional method (over IMapEntry), which returns the raw delay object
56+
and not the forced value."
57+
(get-key [lazy-map-entry] "Return the key of the map entry.")
58+
(get-raw-value [lazy-map-entry] "Return the underlying delay object."))
59+
60+
; Extend the IMapEntry interface to act also like ILazyMapEntry.
61+
; For a IMapEntry get-raw-value just returns the given value as
62+
; wrapped in a delay. Similar a vector of two elements might be
63+
; used in place of a IMapEntry.
64+
(extend-protocol ILazyMapEntry
65+
IMapEntry
66+
(get-key [#^IMapEntry this] (.getKey this))
67+
(get-raw-value [#^IMapEntry this] (let [v (.getValue this)] (delay v)))
68+
IPersistentVector
69+
(get-key [this]
70+
(when-not (= (count this) 2)
71+
(throw (IllegalArgumentException.
72+
"Vector used as IMapEntry must be a pair")))
73+
(this 0))
74+
(get-raw-value
75+
[this]
76+
(when-not (= (count this) 2)
77+
(throw (IllegalArgumentException.
78+
"Vector used as IMapEntry must be a pair")))
79+
(let [v (this 1)]
80+
(delay v))))
81+
82+
(defprotocol ILazyPersistentMap
83+
"ILazyPersistentMap extends IPersistentMap with a method to allow
84+
transportation of the underlying delay objects."
85+
(delay-assoc [lazy-map key delay] "Associates the given delay in the map."))
86+
87+
(deftype LazyMapEntry [k v]
88+
ILazyMapEntry
89+
(get-key [_] k)
90+
(get-raw-value [_] v)
91+
IMapEntry
92+
(key [_] k)
93+
(getKey [_] k)
94+
(val [_] (deref v))
95+
(getValue [_] (deref v))
96+
Object
97+
(toString [_] (str \[ (pr-str k) \space (pr-str (deref v)) \])))
98+
99+
(defmethod print-method LazyMapEntry
100+
[this #^java.io.Writer w]
101+
(.write w (str this)))
102+
103+
(defn create-lazy-map-seq
104+
([inner-seq]
105+
(create-lazy-map-seq inner-seq nil))
106+
([inner-seq metadata]
107+
(proxy [ASeq] [metadata]
108+
; ISeq
109+
(first []
110+
(let [first-val (first inner-seq)]
111+
(LazyMapEntry. (key first-val) (val first-val))))
112+
(next []
113+
(when-let [inner-rest (next inner-seq)]
114+
(create-lazy-map-seq inner-rest metadata)))
115+
(more [] (lazy-seq (next this))))))
116+
117+
(declare create-lazy-map)
118+
119+
(deftype LazyPersistentMap
120+
[base metadata]
121+
ILazyPersistentMap
122+
(delay-assoc [this k v] (create-lazy-map (assoc base k v) metadata))
123+
IPersistentMap
124+
(assoc [this k v] (create-lazy-map (assoc base k (delay v)) metadata))
125+
(assocEx
126+
[this k v]
127+
(when (contains? base k)
128+
(throw (Exception. (str "Key already present in map: " k))))
129+
(.assoc this k v))
130+
(without [this k] (create-lazy-map (dissoc base k) metadata))
131+
; Associative
132+
(containsKey [this k] (contains? base k))
133+
(entryAt [this k] (when-let [v (base k)] (LazyMapEntry. k v)))
134+
; IPersistentCollection
135+
(count [this] (count base))
136+
(cons
137+
[this o]
138+
(if (satisfies? ILazyMapEntry o)
139+
(delay-assoc this (get-key o) (get-raw-value o))
140+
(into this o)))
141+
(empty [this] (create-lazy-map (empty base) nil))
142+
ILookup
143+
(valAt [this k] (.valAt this k nil))
144+
(valAt
145+
[this k not-found]
146+
(if (contains? base k)
147+
(-> base (get k) deref)
148+
not-found))
149+
IFn
150+
(invoke [this k] (.valAt this k nil))
151+
(invoke [this k not-found] (.valAt this k not-found))
152+
(applyTo
153+
[this args]
154+
(let [[k v & rest-args :as args] (seq args)]
155+
(when (or (not args) rest-args)
156+
(throw (Exception. "lazy map must be called with one or two arguments")))
157+
(.valAt this k v)))
158+
Seqable
159+
(seq
160+
[this]
161+
(when-let [inner-seq (seq base)]
162+
(create-lazy-map-seq inner-seq)))
163+
IObj
164+
(withMeta [this new-metadata] (create-lazy-map base new-metadata))
165+
; IMeta
166+
(meta [this] metadata)
167+
Iterable
168+
(iterator [this] (-> this .seq SeqIterator.)))
169+
170+
(defn create-lazy-map
171+
([base]
172+
(create-lazy-map base nil))
173+
([base metadata]
174+
(LazyPersistentMap. base metadata)))
175+
176+
(defn- quote-values
177+
[kvs]
178+
(assert (even? (count kvs)))
179+
(mapcat (fn [[k v]] [k `(delay ~v)]) (partition 2 kvs)))
180+
181+
(defn lazy-assoc*
182+
"lazy-assoc* is like lazy-assoc but a function and takes values as delays
183+
instead of expanding into a delay of val."
184+
[m & kvs]
185+
(assert (even? (count kvs)))
186+
(reduce (fn [m [k v]] (delay-assoc m k v)) m (partition 2 kvs)))
187+
188+
(defmacro lazy-assoc
189+
"lazy-assoc associates new values to the given keys in the given lazy map.
190+
The values are not evaluated, before their first retrieval. They are
191+
evaluated at most once."
192+
[m & kvs]
193+
`(lazy-assoc* ~m ~@(quote-values kvs)))
194+
195+
(defn lazy-hash-map*
196+
"lazy-hash-map* is the same as lazy-hash-map except that its a function
197+
and it takes a seq of keys-delayed-value pairs."
198+
[& kvs]
199+
(create-lazy-map (apply hash-map kvs)))
200+
201+
(defmacro lazy-hash-map
202+
"lazy-hash-map creates a map. The values are not evaluated before their
203+
first retrieval. Each value is evaluated at most once. The underlying map
204+
is a hash map."
205+
[& kvs]
206+
`(lazy-hash-map* ~@(quote-values kvs)))
207+
208+
(defn lazy-sorted-map*
209+
"lazy-sorted-map* is the same as lazy-sorted-map except that its a
210+
function and it takes a seq of keys-delayed-value pairs."
211+
[& kvs]
212+
(create-lazy-map (apply sorted-map kvs)))
213+
214+
(defmacro lazy-sorted-map
215+
"lazy-sorted-map creates a map. The values are not evaluated before their
216+
first retrieval. Each value is evaluated at most once. The underlying map
217+
is a sorted map."
218+
[& kvs]
219+
`(lazy-sorted-map* ~@(quote-values kvs)))
220+
221+
(defn lazy-struct-map*
222+
"lazy-struct-map* is the same as lazy-struct-map except that its a
223+
function and it takes a seq of keys-delayed-value pairs together with the
224+
struct basis."
225+
[s & kvs]
226+
(create-lazy-map (apply struct-map s kvs)))
227+
228+
(defmacro lazy-struct-map
229+
"lazy-struct-map creates a map. The values are not evaluated before their
230+
first retrieval. Each value is evaluated at most once. The underlying map
231+
is a struct map according to the provided structure s."
232+
[s & kvs]
233+
`(lazy-struct-map* ~s ~@(quote-values kvs)))
234+
235+
(defn lazy-struct*
236+
"lazy-struct* is the same as lazy-struct except that its a function and
237+
it takes a seq of delayed value together with the struct basis."
238+
[s & vs]
239+
(create-lazy-map (apply struct s vs)))
240+
241+
(defmacro lazy-struct
242+
"lazy-struct creates a map. The values are not evaluated before their
243+
first retrieval. Each value is evaluated at most once. The underlying map
244+
is a struct map according to the provided structure s. As with Clojure's
245+
struct the values have to appear in the order of the keys in the structure."
246+
[s & vs]
247+
(let [vs (map (fn [v] `(delay ~v)) vs)]
248+
`(lazy-struct* ~s ~@vs)))

test/plumbing/lazymap_test.clj

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
(ns plumbing.lazymap-test
2-
(:use plumbing.core clojure.test lazymap.core))
2+
(:use plumbing.core clojure.test plumbing.lazymap))
33

44
(deftest lazy-map-entry-extend-test
55
(is (= :a (get-key [:a 2])))

0 commit comments

Comments
 (0)