Skip to content

Create Clojure maps whose values are only calculated when accessed, either from data or from java objects.

License

Notifications You must be signed in to change notification settings

Malabarba/lazy-map-clojure

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

lazy-map https://secure.travis-ci.org/Malabarba/lazy-map-clojure.png?branch=master https://img.shields.io/badge/dryness-68-97CA00.svg https://coveralls.io/repos/Malabarba/lazy-map-clojure/badge.svg?branch=master&service=github

Create maps whose values are only calculated when accessed, either from data or from java objects. Supports both Clojure and Clojurescript!

https://clojars.org/malabarba/lazy-map/latest-version.svg

Documentation

This macro is analogous to lazy-seq. It takes a map (instead of a seq), but the value expressions you write aren’t actually evaluated until they are accessed.

user> (def my-map
        (lazy-map
         {:cause (do (println "Getting Cause")
                     :major-failure)
          :name (do (println "Getting Name")
                    "Some Name")}))
#'user/my-map

user> (:name my-map)
Getting Name
"Some Name"

user> (:name my-map)
"Some Name"

user> (:cause my-map)
Getting Cause
:major-failure

user> (:cause my-map)
:major-failure

You can also assoc new keys into a LazyMap like a regular Clojure map. If you assoc a delay it will act as a lazy value, and if you assoc anything else it acts as a regular value.

user> (def new-map (-> (assoc my-map :surname "Malabarba")
                 (assoc :delayed-surname
                        (delay (println "Resolved")
                               "Late Malabarba"))))
#'user/new-map
user> (:surname my-map)
"Malabarba"
user> (:delayed-surname my-map)
Resolved
"Late Malabarba"

The to-lazy-map protocol

This protocol allows you to convert any java class into a lazy map, where each entry correponds to a method call. Since everything is lazy, you can rest assured the methods won’t actually be called until you use them.

user> (use 'lazy-map.iop)
nil
user> (extend-lazy-map String)
nil

user> (to-lazy-map "My Own Map!")
{:to-char-array #object[clojure.lang.Delay 0x5c3c775a {:status :pending, :val nil}],
 :empty?        #object[clojure.lang.Delay 0x774f63f2 {:status :pending, :val nil}],
 :to-string     #object[clojure.lang.Delay 0x4a62ed8c {:status :pending, :val nil}],
 :intern        #object[clojure.lang.Delay 0x4ddc7018 {:status :pending, :val nil}],
 :chars         #object[clojure.lang.Delay 0x72e5585e {:status :pending, :val nil}],
 :class         #object[clojure.lang.Delay 0x7e39e503 {:status :pending, :val nil}],
 :length        #object[clojure.lang.Delay 0x236a69c5 {:status :pending, :val nil}],
 :trim          #object[clojure.lang.Delay 0xd988100 {:status :pending, :val nil}],
 :bytes         #object[clojure.lang.Delay 0x55671f45 {:status :pending, :val nil}],
 :code-points   #object[clojure.lang.Delay 0x64c7f917 {:status :pending, :val nil}],
 :to-lower-case #object[clojure.lang.Delay 0x1493800b {:status :pending, :val nil}],
 :hash-code     #object[clojure.lang.Delay 0x5d4a8318 {:status :pending, :val nil}],
 :object        #object[clojure.lang.Delay 0x30ba32c3 {:status :pending, :val nil}],
 :to-upper-case #object[clojure.lang.Delay 0x6b6e6a82 {:status :pending, :val nil}]}

user> (:to-upper-case *1)
"MY OWN MAP!"

Note how there’s an entry for each method. Obviously, only methods that takes no arguments (0-arity) are included.

There’s also an extra :object entry holding the string itself.

License

Copyright © 2015 Artur Malabarba

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

About

Create Clojure maps whose values are only calculated when accessed, either from data or from java objects.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published