core-async

2020-04-02T16:38:17.005700Z

Can anyone explain what would be the advantage of using take! recursively over a go-loop? Example:

;; avoid using go-loops with aot here
(take! err-ch (fn loop-fn [e]
                (error-fn e)
                (take! err-ch loop-fn)))
The comment on avoiding go-loops with aot is in the original source. Copied from https://github.com/replikativ/superv.async/blob/c9ec3ed4611e84889eb10eab5da753559f7a4703/src/superv/async.cljc#L87

2020-04-02T16:59:28.008800Z

take! has a callback as its second arg

2020-04-02T16:59:33.009Z

the callback invokes it again

2020-04-02T16:59:50.009400Z

so it's a sort of trampoline - every time the take succeeds, it invokes a new take

2020-04-02T17:00:44.010300Z

the advantage is that go blocks compile by doing a transform on their body, I wouldn't be surprised if that interacts poorly with aot with certain core.async versions

2020-04-02T17:01:06.010700Z

I don't know of the specific bug (and my alternative would be just never doing aot...)

kenny 2020-04-02T17:02:41.011Z

I'd like to do a pipe and apply a transducer to the values taken from from before putting them to to. pipeline seems to do exactly this. However, I've usually thought of the pipeline* functions in core.async as utilities for doing things in parallel. Is it typical to use pipeline with a parallelism of 1 for this sort of task?

rgm 2020-04-02T22:55:25.012900Z

Is there a good reference for how to reliably log to a repl window from a go-loop? I’m using timbre from a mount-managed go-loop and I almost certainly don’t have it hooked up right. I’ve resorted to resetting an atom from within the loop and have an add-watch set up outside the loop.

rgm 2020-04-02T22:58:24.013800Z

(the more general teach-me-to-fish-ish question: understanding what exactly is going on with stdout, etc. and the various places it might hide).

2020-04-02T22:58:54.014200Z

on the java level, stdout is attached by default to System/out

2020-04-02T22:59:14.014700Z

in clojure, the dynamic var *out* is derived by default from Sytem/out

2020-04-02T22:59:49.015500Z

but the value of *out* can be modifed, via dynamic binding or just plan redefinition / resetting

2020-04-02T23:00:22.016200Z

many loggers intentionally don't use out- try askin our logger to print to *out* instead of its current method?

2020-04-02T23:00:40.016800Z

but on the other hand, it might be more elegant to have a go loop that reads a channel and logs every entry it consumes (instead of the logger library handling this ordering via queue for you)

rgm 2020-04-02T23:01:20.017800Z

oh, thanks. Ok. I’ll try passing *out*. I’m still learning what’s what with core.async and I’m finding it challenging when I can’t see things happen in a log stream.

rgm 2020-04-02T23:03:13.019300Z

Is this the kind of thing I should be doing with (tap> ,,,)?

2020-04-02T23:07:10.019800Z

I haven't played with tap - but it would be one way to do this(?)

rgm 2020-04-02T23:08:13.020700Z

Ok, I’ll see if that helps too. Now to log *out* and see what it is in various places with wild abandon.

seancorfield 2020-04-02T23:21:38.022100Z

@rgm If you're doing this for debugging purposes, I'd reach for tap> first. Then either use Cognitect's REBL or use a second REPL connected into the first one and add a tap listener that just println's the tapped data.

seancorfield 2020-04-02T23:22:17.022700Z

(I've used that second approach quite often to get a simple console logging stream running outside my main REPL/editor setup)

rgm 2020-04-02T23:23:14.023500Z

by second repl do you mean in an editor, or say connecting a second nrepl via lein connect? (I’m in a lein project)

seancorfield 2020-04-02T23:24:04.024200Z

The latter. Just from another terminal window so you can add-tap to get println output in that second REPL.

seancorfield 2020-04-02T23:24:51.024900Z

(that way the tap values are printed just to the stdout of that second REPL)

seancorfield 2020-04-02T23:27:42.026100Z

Hmm, I just tried that and it doesn't actually work the way I expected with Leiningen... I'm used to doing it with a Socket REPL and it works there. I wonder what Leiningen is doing differently with stdout?

rgm 2020-04-02T23:28:11.027100Z

yeah, between lein and fireplace (vim user) it’s not really clear to me where it’s all being swallowed

seancorfield 2020-04-02T23:28:13.027300Z

(I haven't used Leiningen for anything for years at this point)

rgm 2020-04-02T23:28:19.027500Z

that second repl’s a neat trick though, thanks.

rgm 2020-04-02T23:28:59.028300Z

is the idea that tap> calls can just stay in place and they don’t matter if no taps are attached?

seancorfield 2020-04-02T23:37:56.029200Z

Yup. They'll just tap into the void if nothing is listening. They have a dropping channel buffer behind them I believe. Maybe 1024 entries?

rgm 2020-04-02T23:38:09.029400Z

oooo