Fork me on GitHub

Is there a general best practice relating to passing a mult to functions which then "create" their own channels to do what they need, or leaving it to an outer assembly layer to create the chans that are needed first and pass them to the function? Are there any factors that help guide this decision? I keep going back and forth on it

Alex Miller (Clojure team)15:12:30

there's a chapter about this in Clojure Applied if you want to read that


Actually that's what got me thinking more about it 🙂 There you generally suggest the latter, assembling from the outside of the function right?

Alex Miller (Clojure team)15:12:19

in general, I think externalizing channels is a good idea (unless you rely on properties of those channels like buffer policy or transducer)

đź‘Ť 3

[great book by the way probably my fav clojure book!]

Alex Miller (Clojure team)15:12:19

what's missing that you would want in a 2nd edition?


I think I might have had thoughts on this when I last did a thorough reading maybe a year ago but I can't remember now. I'll skim it again tonight and let you know if anything jumps out. It's probably just the obvious stuff though like spec, and I'd be interested to know if anything would change relating to the usage of records vs maps


In general I like how it really goes into "composing a system", basically the whole section 2. But not sure a whole lot has changed on that over the years

Alex Miller (Clojure team)15:12:00

thx, let me know if you think of something

Alex Miller (Clojure team)15:12:07

I have my own list of course :)

đź‘Ť 3

It seems like an assembly layer is nice and certainly cleaner, but greatly increases development time and ongoing maintenance complexity. OTOH having functions orchestrate their own channels internally as black boxes presents a cleaner interface from the function to the outside world, but might become brittle later in certain combinations with other things. Any thoughts? (I haven’t read the book yet, just spitballing…)


Something to keep in mind is core.async is all side-effects, so architectural discussions of state and side effects are applicable


in general, the community around clojure is much more accepting of side effects that are not visible (mutating transients while creating them and returning immutable values), vs creating a mutable arraylist and returning it.


Another thing to keep in mind is core.async uses global resources (the thread pool, and for anything non-trivial timers) so multiple core.async "blackboxes" will be entangled there


And another thing, core.async isn't the best at timely resource management (it can hang onto references to things longer then might expect), so "externalizing" (creating it at the top most visible level) that stuff can help keep track, analogous to a C program managing memory by just allocating all it needs up front

❤️ 3

good tips, thanks!