[ANN] fun-map: put your code into this map, it turns value when you access it

199 views
Skip to first unread message

Robert Luo

unread,
May 8, 2018, 10:36:23 PM5/8/18
to Clojure
Github Link: https://github.com/robertluo/fun-map

It is a lazy map:

(def m (fun-map {:a 4 :b (delay (println "accessing :b") 10)}))

and can also be a future map:

(def m (fun-map {:a (future (do (Thread/sleep 1000) 10))
                 :b (future (do (Thread/sleep 1000) 20))}))

or mixed:

(def m (fun-map {:a (future (do (Thread/sleep 1000) 10))
                 :b (delay 20)}))

or cascading function calls:

(def m (fun-map {:xs (range 10)
                 :count-keys ^:wrap (fn [m] (count (keys m)))
                 :sum (fnk [xs] (apply + xs))
                 :cnt (fnk [xs] (count xs))
                 :avg (fnk [sum cnt] (/ sum cnt))}))

or even a light weight system can be halted in order:

(def system
  (life-cycle-map
    {:component/a
     (fnk []
      (reify java.io.Closeable
        (close [_]
          (println "halt :a"))))
     :component/b
     (fnk [:component/a]
       (reify java.io.Closeable
         (close [_]
           (println "halt :b"))))}))
(touch system) ;;start the system
(halt! system)

Jason Kapp

unread,
May 10, 2018, 2:14:20 PM5/10/18
to Clojure
This looks a lot like Prismatic's Plumbing library: https://github.com/plumatic/plumbing

Robert Luo

unread,
May 10, 2018, 6:46:31 PM5/10/18
to Clojure
Yes. Fun-map can be used like a `graph` in plumbing. It actually has a macro named `fnk` just like plumbing. Both of fun-map and plumbing can link functions toghether by the name of arguments, hence can be used as a dependency injection tool.

However, the implementation of fun-map is very different from plumbing.

- The graph in plumbing is a data structure defined by a map, but need be compiled to a function. While a fun-map is just a plain map, so no compilation there.
- Plumbing allow you compile your computation eagerly or lazily, in fact, it even use another lazy-map library. Fun-map is just map and you can put delay or future in you value for each map entry, so there is not any limit to choose.
- the compiling process can detect cyclical dependency between functions, while in a fun-map there is not such a mechanism yet.
- you can not put a separated value or function in a graph, the compilation process will remove them. In a fun-map you can keep any thing.

Because fun-map do no pre-computation, it just use clojure function call and map lookup itself, the implementation is very simple.

Jason Kapp

unread,
May 10, 2018, 11:57:43 PM5/10/18
to Clojure
Cool.
Reply all
Reply to author
Forward
0 new messages