Skip to content

Instantly share code, notes, and snippets.

@roman01la
Created August 30, 2021 08:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save roman01la/053281b92a1ba04feddf1c24f5741fa1 to your computer and use it in GitHub Desktop.
Save roman01la/053281b92a1ba04feddf1c24f5741fa1 to your computer and use it in GitHub Desktop.

This example illustrates an intersting side effect of Clojure's lazy sequences when used in re-frame subscriptions. The behaviour described below takes place only on initial subscribe call

(reg-sub :test/x-2
  (constantly [])
  (fn [_ _]
    (prn "evaluating body of " :test/x-2)
    (map #(do (prn "evaluating lazy seq returned from " :test/x-2) (inc %)) (range 3))))

(reg-sub :test/x-1
  :<- [:test/x-2]
  (fn [x2 _]
    (prn "evaluating body of " :test/x-1)
    (map #(do (prn "evaluating lazy seq returned from " :test/x-1) (inc %)) x2)))

(defn component []
  (let [x @(subscribe [:test/x-1])]
    (prn "printing the value in Reagent componen now")
    (prn x)))

Printing order

"evaluating body of " :test/x-2
"evaluating body of " :test/x-1
"printing the value in Reagent componen now"
"evaluating lazy seq returned from " :test/x-2
"evaluating lazy seq returned from " :test/x-1
(2 3 4)

What happens here?

Evaluation of a lazy seq, returned from a subscription, is being deferred until a point where the resulting value is realized/evaluated

What are the consequences?

Even though lazy seq caches its compued value, so it's not evaluated again and again, deferred evaluation makes debugging harder, since the code defined in subscription body is evaluated in component tree.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment