This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-02-02
Channels
- # admin-announcements (33)
- # announcements (2)
- # beginners (75)
- # boot (340)
- # braid-chat (6)
- # cider (30)
- # cljsrn (44)
- # clojars (19)
- # clojure (169)
- # clojure-austin (12)
- # clojure-czech (1)
- # clojure-japan (6)
- # clojure-miami (1)
- # clojure-poland (7)
- # clojure-russia (83)
- # clojurebridge (4)
- # clojurescript (166)
- # community-development (55)
- # component (2)
- # core-async (39)
- # core-matrix (3)
- # cursive (32)
- # data-science (3)
- # datavis (3)
- # datomic (58)
- # dirac (28)
- # emacs (4)
- # events (7)
- # hoplon (254)
- # immutant (29)
- # jobs (2)
- # jobs-discuss (4)
- # ldnclj (35)
- # lein-figwheel (3)
- # mount (202)
- # off-topic (9)
- # om (123)
- # onyx (22)
- # parinfer (112)
- # proton (11)
- # re-frame (6)
- # reagent (43)
- # ring (3)
- # spacemacs (2)
That seems like a bug to me (it works if you run the code without the go
block), but perhaps I am mistaken?
bindings within go blocks don't work because of the way the current impl works. We should document that
bindings are grabbed at the initial invocation of the block and will persist throughout the whole block
@ghadi: Thanks for the info! I think my confusion is that the binding does change (the first two assertions pass, so it goes from "a" to "b") but it just doesn't go back.
@ghadi: So can you expand a little bit about what you mean by "persist throughout the whole block"? It seems like they are altered within the binding, if you see what I mean.
the cljs impl may be different. I wrote the binding code for CLJ, so take this with a grain of salt:
To be fair, I haven't tested this on CLJ yet, so I'm not sure if it's the same or different.
"persist for the whole block" meaning -- whatever binding was grabbed as the block starts -- if the block ever resumes after a <! or >!, the binding will be reset to those initial bindings
I had to wrap my bindings into a function call last time I experienced this issue - that solved it for me
@darwin, do you mean like this?
(binding [x (some-func-that-returns-b)]
(is (= x "b")))
but since this headache I started to use go blocks defensively, I try to move as much code into function calls, try to not make go body complex
for example one case was here: https://github.com/darwin/plastic/blob/master/src/common/plastic/frame.cljs#L113 originally body of apply-event was inlined in the go-loop which didn’t work
@ghadi: OK, good to know that binding within a go block is not expected to always work. That's good to know - I'l look at a potential refactor instead of waiting for a fix 😄
> I think you're right, that's the best solution, ideally. I meant that in response to " I try to move as much code into function calls, try to not make go body complex"
It's a bit tricky right now due to trying to integrate async testing, test.check, and the test-env dynamic var ... but I'll think more on it
I think it is generally good practice to try to make go blocks as lean as possible, you minimize code rewriting and it helps when you have to read call stacks when debugging
if you really need binding in the middle of your go block code, and you cannot move it out, I think that you can save original value, set! new value and then return backup, this is a bit dangerous, but should work if done correctly, also make sure you handle exceptional cases if the code in between could throw
Yeah, I did use set!
although in my particular case, a whole bunch of go
blocks were kicked off "simultaneously" that all ran that code, so they all starting altering the var with set!
in conflict with each other
@darwin It's a good thought though. In my case, I've got a workaround for now, so it's not a huge deal.
But moving forward, I'll be looking for ways to avoid using binding
within a go block if at all possible.
I think we would need something like thread-local-storage for go blocks, to make it work
is there any identifier of a go block “thread”? maybe one could just keep a map with mapping from thread-id to some data
I would like to add some “runtime” info in debug mode, so I could implement this (cljs only): https://github.com/binaryage/dirac/issues/3