Fork me on GitHub
#core-async
<
2015-08-15
>
rauh15:08:34

Changing the transducer of a channel whiles it's running (without creating a new channel): https://gist.github.com/rauhs/01d98084d9d2b9c9fd81

meow20:08:43

@rauh: aren't you clever! simple_smile

ghadi20:08:35

there is no safe way to achieve changing a transducer on the fly

rauh20:08:09

If it has state, then it will destroy the state and make the transducer possibly useless. Though, why wouldn't it be safe?

ghadi20:08:03

stateful transducers is one problem

ghadi20:08:32

there's no ordering semantics on when the swap!/reset! happens with respect to any other values flowing through the channel

ghadi20:08:59

you'll have to control that knob from the producing end of the channel

ghadi20:08:26

But fundamentlly transducers are applied once

ghadi20:08:01

the returned "process/reducing function" can be applied as many times as need be, but the process transformation happens only once

ghadi20:08:34

to distill the problem look at transduce

ghadi20:08:15

It will apply the transducer within the call to transduce. Transducer applications are once only

rauh20:08:20

Yes it definitely has very limited use-cases. Though in my case I'm only using it for some CLJS stuff where I transform the events on my channel according to some given rules. And these rules can change over time

rauh20:08:18

@ghadi: Yes, but the "only once application" is circumvented by just re-doing it manually on every value that's coming in. It's instantiated on every value (inefficient but for my use case ok)

ghadi21:08:16

when do the rules change? and can you be guaranteed in an async setting to change the rules before or after the value goes in the channel?

rauh21:08:02

I actually don't know. The user provides the transducer. Though I allow the freedom to change it during the runtime of my library. If it does change, I'm currently tearing down my channel and set it up again. But with this I can just remove some of that complexity

ghadi21:08:18

you're trading complexity for brokenness

ghadi21:08:36

never a good trade 😃

rauh21:08:57

Well, when I tear down the channel and set it up again I also brake all the state, so nothing is more broken than it already was simple_smile

ghadi21:08:42

No that's fine, because when you close a channel, it should allow a transducer's arity-1 function (the completing function) to run properly and clean up

rauh21:08:48

But i agree, not the finest thing to do. Basically I restrict the user to map/filter and other simpler transducers, which is fine. And the library is only a development tool. NEver makes it into production

ghadi21:08:06

Ok, I didn't mean to rain on the parade 😃

rauh21:08:17

That's a good point, I should call the arity 1 function myself.

ghadi21:08:17

perhaps, but there's still no safe or clearly defined time to make the swap in the general case (beyond map filter)

ghadi21:08:02

If the code can guarantee Tear Down -> Drain -> Construct New, then it is fine

ghadi21:08:10

in that order

rauh21:08:11

Well I'll intercept the swap with an add-watch and complete the old value which can push all its stuff out to the channel

rauh21:08:29

I wonder if it'd make sense to differentiate (in clojure) between stateful and stateless transducers. hmm