clojure - merge to set default values, but potentially expensive functions -
an idiomatic way set default values in clojure merge:
;; `merge` can used support setting of default values (merge {:foo "foo-default" :bar "bar-default"} {:foo "custom-value"}) ;;=> {:foo "custom-value" :bar "bar-default"}
in reality however, default values not simple constants function calls. obviously, i'd avoid calling function if it's not going used.
so far i'm doing like:
(defn ensure-uuid [msg] (if (:uuid msg) msg (assoc msg :uuid (random-uuid))))
and apply ensure-*
functions (-> msg ensure-uuid ensure-xyz)
.
what more idiomatic way this? i'm thinking like:
(merge-macro {:foo {:bar (expensive-func)} :xyz (other-fn)} my-map) (associf my-map [:foo :bar] (expensive-func) :xyz (other-fn))
you can use delay
combined force
.
you can merge defaults like
(merge {:foo "foo-default" :bar "bar-default" :uuid (delay (random-uuid))} {:foo "custom-value" :uuid "abc"})
and access values using
(force (:foo ...))
or
(force (:uuid ...))
random-uuid
called when need value (and first time).
you can wrap call force
in get-value
function, or that.
Comments
Post a Comment