Fork me on GitHub
#clojure-dev
<
2018-04-30
>
leonoel08:04:00

in this talk https://youtu.be/cPNkH-7PRTk?t=4663 RH made it pretty clear he didn't want dynamic bindings to propagate to child threads, anyone knows what made it change his mind ?

tbaldridge14:04:39

Maybe that it was done in a read-only manner? Something that's a little interesting in the implementation of Vars is that if a binding is propagated to a child thread, the child thread cannot call set! on that binding

tbaldridge14:04:49

(binding [foo 4]
         (set! foo 3)
         (future (set! foo 44)))

tbaldridge14:04:03

Results in "Can't set!: foo from non-binding thread"

tbaldridge14:04:00

Also conveyance of bindings is only done automatically for futures and agents. That video is pretty old, so I'm not sure how the timeline of all these features fits together.

tbaldridge14:04:20

That being said, I'm glad we have binding conveyance.

leonoel14:04:34

go block as well IIRC ?

leonoel14:04:06

assignment restriction in child threads mitigates the problem but you can still screw it up with mutable objects

tbaldridge14:04:21

true, that's the case with mutable objects in general though, nothing stops you from doing (atom (List.))

leonoel14:04:46

yes, but one of the benefits of thread local state is precisely to use (performant) unsynchronized state safely

leonoel14:04:26

what are the good use cases for dynamic vars according to you ?

tbaldridge14:04:37

I mostly use them for storing global-esque state instead of returning multiple values from a function.

tbaldridge14:04:05

When I want to pass something into a function, but that function may need to update that value.

leonoel14:04:40

what benefits do you get from implicit binding conveyance in this scenario ?

leonoel14:04:21

I understand how binding conveyance can be useful, but I can hardly understand how it can be a good default behavior

tbaldridge14:04:43

Oh, implicit binding conveyance is useful for things like print:

(with-out-str
  @(future (println "test")))

tbaldridge14:04:40

That's the original use case for this I think. Back when binding conveyance was introduced (2010) it was fairly common to pass db connections and IO streams around in dynamic bindings.

gfredericks01:05:33

those were the days

tbaldridge14:04:14

And without that, things would just randomly break when you put them inside pmap or any other function that used futures.

leonoel14:04:49

that makes sense