Fork me on GitHub
#core-async
<
2016-02-02
>
bbrinck21:02:20

That seems like a bug to me (it works if you run the code without the go block), but perhaps I am mistaken?

ghadi21:02:17

bindings within go blocks don't work because of the way the current impl works. We should document that

ghadi21:02:41

bindings are grabbed at the initial invocation of the block and will persist throughout the whole block

ghadi21:02:45

bbrinck: ^

bbrinck22:02:21

@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.

bbrinck22:02:14

@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.

ghadi22:02:00

the cljs impl may be different. I wrote the binding code for CLJ, so take this with a grain of salt:

bbrinck22:02:10

Understood 😄

bbrinck22:02:46

To be fair, I haven't tested this on CLJ yet, so I'm not sure if it's the same or different.

ghadi22:02:05

"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

darwin22:02:06

I had to wrap my bindings into a function call last time I experienced this issue - that solved it for me

bbrinck22:02:03

@darwin, do you mean like this?

(binding [x (some-func-that-returns-b)]
        (is (= x "b")))

darwin22:02:40

no, calling a separate function, which has `(binding […]…)

darwin22:02:54

I understand that it is not always possible

ghadi22:02:58

or avoid binding within the scope of go

ghadi22:02:08

bind on the outside if it's possible

darwin22:02:36

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

darwin22:02:00

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

bbrinck22:02:17

@darwin: I think you're right, that's the best solution, ideally.

bbrinck22:02:13

@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 😄

bbrinck22:02:57

@darwin: Thanks for the example!

bbrinck22:02:12

> 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"

bbrinck22:02:09

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

darwin22:02:10

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

bbrinck22:02:19

Yeah that's true

darwin22:02:41

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

bbrinck22:02:21

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

darwin22:02:27

ah, I see, good point, so my proposal is wrong, it cannot be done this way

bbrinck22:02:46

@darwin It's a good thought though. In my case, I've got a workaround for now, so it's not a huge deal.

bbrinck22:02:35

But moving forward, I'll be looking for ways to avoid using binding within a go block if at all possible.

darwin22:02:12

I think we would need something like thread-local-storage for go blocks, to make it work simple_smile

darwin22:02:54

is there any identifier of a go block “thread”? maybe one could just keep a map with mapping from thread-id to some data

ghadi22:02:06

darwin: that was on my list...

ghadi22:02:18

the "cheap vars" for go blocks, "killable" go blocks

darwin22:02:52

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

darwin22:02:07

basically I would like to keep a map of all running blocks and their state/data

bbrinck22:02:46

@ghadi: But to your earlier point, if the somewhat surprising (at least to me) behavior of binding was documented somewhere, that'd be awesome!

darwin22:02:23

people don’t read documentation simple_smile it must be the first google search result on SO or similar place simple_smile