(def m (fun-map {:a (future (+ 5 3))}))
(:a m) ;=> 8
If you put a clojure.lang.IDeRef
instance like a deferred value (created by defer
) or future into the map, deref
will be automatically called when you access it. This way, the map can be thought of as a lazy map.
(def m (fun-map {:a (future (+ 5 3))}))
(:a m) ;=> 8
You can specify :keep-ref to disable this default feature, and use fnk to force it to be lazy for individual values.
|
Your values can now depend on the map itself, most commonly on other values.
(def m
(fun-map {:numbers (range 10)
:cnt (fnk [numbers] (count numbers))
:sum (fnk [numbers] (apply + numbers))
:average (fnk [cnt sum] (/ sum cnt))}))
This feature is similar to Plumatic Plumbing’s graph, it even has the same name fnk
macro! The difference is that fun-map is a normal map, you could update the values (and the fnk
function) at any time. You could use a plain map if you want to test some complex computations.
A fun-map can track the realization order of its values by specifying a :trace-fn
option, combine this and the dependency injection nature, leads to a simple lifecycle management feature.
life-cycle-map
is a fun-map that can orderly close your lifecycle components.
(def system
(life-cycle-map
{:component/a
(fnk []
(closeable 100 #(println "halt :a"))) (1)
:component/b
(fnk [:component/a]
(closeable (inc a) #(println "halt :b")))}))
(touch system) (2)
(halt! system) (3)
1 | closeable function turns a value to a closeable value, the specified close function will be called when the whole system is being close . |
2 | touch travels the system, and makes potential lazy values realized, in a real application, you may not want to do it. |
3 | halt! is a function that closes a closeable value. |
Waterfall library uses life-cycle-map
to do dependency injection and lifecycle management, turns Kafka usage into map accessing.
The complete API documents are on cljdocs.
Some of the most frequently used APIs are:
fun-map
fnk
(macro)
fw
(macro)
(defn book-of
[connection author]
(-> (fun-map {:datomic/db (fnk [:datomic/connection] (d/db connection)) (1)
:books (fnk [:datomic/db author]
(d/q '[:find ?e
:in $ ?name
:where [?e :book/author ?name]]
db author))
:book-count (fnk [books] (count books))})
(assoc :datomic/connection connection :author author))) (2)
(book-system (d/connect "datomic:mem://books") "Harry Potter")
1 | fnk accepts namespaced keywords. |
2 | by assoc key-value pairs to a fun-map, you turn Datomic API into a map. |
Fun-map using kaocha as the test runner.
use clj -M:test --watch
to automatically run tests whenever code changes.
Copyright © 2018, 2019, 2022 Robertluo
Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close