This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # announcements (1)
- # aws-lambda (3)
- # babashka (6)
- # beginners (91)
- # bristol-clojurians (5)
- # calva (25)
- # chlorine-clover (8)
- # cider (6)
- # clj-kondo (13)
- # cljdoc (10)
- # cljsrn (1)
- # clojure (80)
- # clojure-berlin (6)
- # clojure-europe (29)
- # clojure-nl (4)
- # clojure-spec (18)
- # clojure-uk (51)
- # clojurescript (41)
- # conjure (55)
- # crux (10)
- # cursive (3)
- # datomic (58)
- # emacs (9)
- # events (1)
- # figwheel-main (2)
- # fulcro (29)
- # graphql (12)
- # helix (4)
- # jobs (4)
- # klipse (8)
- # london-clojurians (1)
- # malli (5)
- # off-topic (13)
- # portal (9)
- # re-frame (30)
- # shadow-cljs (44)
- # spacemacs (7)
- # specter (3)
- # sql (11)
- # tools-deps (71)
- # windows (1)
Is it normal to define multimethods like this
(defmulti my-fn #(mapv type %)) to achieve a sort-of function overloading in Clojure?
Following on from a discussion in #clojure-uk, I'm trying to wrap my head around the information presented here
Since Var roots are global for the entire application, once the body of the future gets around to deref-ing the var (after the 1 sec pause) the root value has already been reset back to 0, causing a race condition.
I just don't understand however, what is meant
the root value has already been reset back to 0, causing a race condition.
What is throwing me is this
the root value has already been reset back - it suggests to me that something behind the scenes is changing the value of the var back to the value of
What if the future executed more quickly, before the
with-redefs completes? That's your race condition.
The with-redefs in this example doesn't seem to be doing anything much, it's wrapping a future.
The same code with different results.
user=> (defn foo  0) #'user/foo user=> (with-redefs [foo (fn  42)] (future (println (foo))) (dorun (range 1))) nil 0 user=> (with-redefs [foo (fn  42)] (future (println (foo))) (dorun (range 1))) 42 nil user=>
with-redefs completes, the value is reset back to what it was before
I must have a faster machine 🙂 I have to bump the range up to nearly 1000 to have differing results
It would make sense to me, if the line was instead of
the root value has already been reset back to 0, causing a race condition. it was
the root value has already been reset back to 42, causing a race condition.
the race is that you have code expecting the value to be 42 and code that will change the value back to 0. the order of those events is not deterministic and therefore you have a race
sometimes the future will execute in totality first, sometimes the resetting back to 0 will happen first, sometimes the future will execute some portion with 42, then some portion with 0. its a race
the root value is
reset back to 0 after
with-redefs completes. It is not
reset back to 42.
with-redefs temporarily sets it to (return, in my case)
42 -- and then resets it back to (return)
Riiigh, so is it a typo then on that line? Should it be
reset back to 42, causing a race condition. not
reset back to 0, causing a race condition.
I assumed, based on the quote, it was doing what I showed. But, yeah, the article should say "reset back to 42".
(I mistakenly assumed the article was correct and you were just confused about why there was a race condition 🙂 )
> What is throwing me is this the root value has already been reset back - it suggests to me that something behind the scenes is changing the value of the var back to the value of 42.
with-redefs is gross (but it is also still very useful if you know you won't have any race conditions)
Now I get it, the with-redefs sets the answer to be 0, but it modifies the root binding, only for the duration of that block. When the block exits, the value is put back to 42, in the meantime, the future inside that block will complete at some point and where you the programmer was thinking that the value of the answer would be
0, it's now
42 because it's been reset back
Well, it may or may not have been reset back. Hence you may get zero or you may get forty-two.
Yes, and I appreciate it - it helped to futher solidify my understanding and help figure out that the article was a little misleading 🙂
Just to prove it can happen with a simple Var, set to
42 initially and
Took me about half a dozen repetitions to see the value flip.
user=> (def answer 42) #'user/answer ... user=> (with-redefs [answer 0] (future (println answer)) (dorun (range 1))) nil 42 user=> (with-redefs [answer 0] (future (println answer)) (dorun (range 1))) 0 nil user=>
Would it be impolite to reach out to Tim to ask him to review the material and look to update the post?
Others may stumble across it (or be linked to it, from a discussion in another channel) and end up being confused too 🙂
Thank you everyone. I've reached out to Tim with the hope he might consider the change to the blog post 🙂
I didn't actually read all that backchat, but if you could summarize what needs to be updated, I can probably do so