Fork me on GitHub
#clojure
<
2020-07-03
>
hanDerPeder11:07:07

given two vectors of maps; [{:id 1 ….} …]what’s a good way to join the maps on id?

hanDerPeder11:07:28

currently I’m reducing both into a new map using id as key

vlaaad11:07:52

user=> (require '[clojure.set :as set])
nil
user=> (set/join #{{:id 1 :name "vlaaad"}} #{{:id 1 :age 29}} {:id :id})
#{{:id 1, :name "vlaaad", :age 29}}
@peder.refsnes ^

hanDerPeder11:07:52

great! thanks.. in hindsight I probably should have search the docs for join 🙂

sveri14:07:17

Hi, let's say I have a map {:foo :bar :baz {:buz :biz}} and want to destructure that l know that this works: {{:keys [buz]} :baz} But what if I want to destructure different levels at the same time. So I need the :foo from the first and the :buz from the second level. Is that possible?

sveri15:07:40

Ah, I think I got it: {:keys [foo] {:keys [buz]} :baz} should work.

p-himik15:07:06

Or {foo :foo, {buz :buz} :baz}.

👍 3
noisesmith16:07:38

also, you are allowed to use let to do separate destructure calls, which is usually more readable and clear, and doesn't have an extra performance cost

sveri13:07:00

Yea, I usually do that, but I wanted to experiment a bit as I never used nested destructuring before.

telekid15:07:39

Does anyone know of a library that allows you to express regexes that operate over clojure data structures? I’m basically looking for spec’s regex ops, but in a format that allows for lightweight anonymous expressions, e.g. ephemeral matchers that aren’t placed in a registry. My usecase is expressing something like the following:

(t/is (dr/match (dr/data-regex-of-some-kind :a dr/* :b) [:a :a :a :b]))

telekid16:07:13

oh, interesting - I hadn’t considered meander for this case. I’ve been looking for an excuse to play around with it for a little while now, too.

telekid16:07:23

thanks for the tip!

👍 3
Alex19:07:12

Hi all, what ways do clojure devs deal with async streaming? I'm coming from Kotlin mostly where coroutines/flows are used but I've also played around with Scala where Monix and fs2 compete for this use case. I watched a conference talk where the speaker seemed to imply its common to provide a callback style api to the user and then use core.async's channels behind the scenes, is that a good route to take?

emilaasa19:07:41

If you are familiar with Kotlins coroutines then core.async should fit right in.

👍 3
noisesmith19:07:36

a huge gotcha is that you should not do IO or CPU intensive work inside core.async go blocks

noisesmith19:07:09

core.async is a coordinator, and go blocks are not designed appropriately for execution

Alex20:07:22

Okay thanks, how do you manage that when using core.async? I'm used to libraries where you specify which thread pool you run a specific task on (io-bound, cpu-bound, etc).

potetm20:07:02

There is a macro thread

potetm20:07:31

Wrap all of your I/O calls like so:

(<! (thread (network-call args)))

noisesmith20:07:00

in some cases you just want to hold onto the channel that thread returns and use it elsewhere of course - but that's the 95% idiom for sure

Alex20:07:39

Okay that makes sense, thanks.

jumar04:07:05

You may want to specify a dedicated thread poll for this blocking ops to avoid spawning thousands of threads

noisesmith13:07:36

that's something core.async go blocks are actually good at, you can use them to implement backpressure, which regulatest the number of threads in flight

☝️ 3
potetm15:07:57

Thread-limiting at the i/o layer is usually about in-memory bulkheads. (You can’t reliably abandon a call on a thread you don’t own.) That’s good, but you usually want to consolidate that in a single object. It’s generally better to backpressure processes at higher layers if feasible.

jumar05:07:23

Note sure what you meant by "in-memory" bulkheads but threadpools are bulkheads. And when you interrupt a thread which is blocked on IO it will throw an InterruptedException (which misbehaving thread may ignore but otherwise it should be a good mechanism). I agree that backpressure at higher levels is a good thing but also think that a separate thread pool is preferrable to the potentially unbounded thread creation via a/thread

noisesmith05:07:35

what I'm advocating for is using core.async structure to provide backpressure, rather than doing it via the size of a thread pool. It's the kind of thing core.async is actually good at (eg. you can start N go-loops, reading from one channel, in order to limit parallelism of the work derived from that channel to N)

👍 6
potetm13:07:28

And I’m reiterating exactly what @U051SS2EU is saying 😉