Fork me on GitHub
#clojure-europe
<
2021-03-15
>
agigao06:03:07

დილა მშიდობის!

ordnungswidrig07:03:57

Good morning. And ❄️

synthomat07:03:02

good morning!

dharrigan07:03:20

Good Morning!

agigao07:03:52

Any pointers on this Monday morning regarding extracting all values for a specific key in a very nested map/vectors of maps?

dharrigan07:03:38

Would a nice little recursive function work here?

agigao07:03:32

Yup, I think so

ordnungswidrig07:03:29

postwalk and collect into a seq

☝️ 3
ordnungswidrig07:03:42

(let [xs (atom 0)] ((postwalk (fn [x] (when-let [v (:some-key x)] (swap! xs v]))) my-ds) (untested)

simongray08:03:03

good morning

slipset08:03:50

@ordnungswidrig you could use a transient or a volatile there as well right?

ordnungswidrig08:03:10

Sure, but I love to optimize only until the very end

slipset08:03:11

(given that your xs doesn’t leave the call stack)

agigao08:03:31

@ordnungswidrig in case of k-v pairs, postwalk goes through key first and value in the next, so not quite sure how to get value using key in this case 🥺

ordnungswidrig08:03:02

@chokheli on the way “up” it will once receive the map as a whole 🙂

ordnungswidrig08:03:42

Maybe tree-seq also works

slipset08:03:09

tree-seq is cool, if not only because of a blog post that I only vaguely remember because of the illustrations.

slipset08:03:06

And the only way I find that blog is by searching for images related to clojure and tree-seq…

slipset08:03:34

@ordnungswidrig have you ever made a studies of typical json payloads for liberator?

slipset08:03:05

Reason I’m asking is that I’m working on speeding up data.json and it would be interesting to have an idea of “real world” json payloads.

slipset08:03:44

With some typical payloads from work (shallow maps around 1k), I read json faster now with data.json than with both cheshire and jsonista, but as payloads grow in size and complexity, cheshire and jsonista are faster.

ordnungswidrig08:03:28

I didn’t. But most projects I know register cheshire to generate actual json reponse 🙂

slipset08:03:13

Yeah, we do that at work too (I think) but I want to see how close I can get with a somewhat pure Clojure json lib so that I don’t have to use Jackson.

slipset08:03:32

There is a startup cost to Jackson that is not insignificant, and then there is the dependency management with all libs having their own version of Jackson which is incompatible with every other version of Jackson.

jmayaalv08:03:40

having suffered the pain of having to resolve classpath clashes with jackson versions this sounds amazing.

❤️ 3
simongray08:03:17

Anyone recall why Rich Hickey (PBUH) doesn’t like pattern matching? I have a bunch of nested ifs I want to flatten and core.match seems like the right tool for the job.

ordnungswidrig11:03:47

Pattern matching is fine when there is a pattern.

ordnungswidrig11:03:03

And often it’s preferrable over nested conditionals

ordnungswidrig11:03:59

I had a clever use of pattern matching recently. And after some real world tests and checks and adding some resilience it all fall together into clever use of (first xs) (rest xs) and some defaulting and nil punning 🙂

slipset08:03:45

@simongray I don’t think he minds pattern matching as such, but it’s a somewhat closed system.

plexus08:03:20

I recently ran into an issues where Cheshire threw an exception on JSON responses coming from the metabase API. Worked fine with data.json.

borkdude09:03:52

Have you created an issue at cheshire? I'm curious what the issue was

plexus09:03:02

no, didn't have time to dig into it. Just switched to data.json which we were already using elsewhere

slipset08:03:21

So, imagine some type A which is the union(?) type of B, C, and D, so you’d have code like:

case a
 B "it's a b"
 C "it's a c"
 D "it's a d"
Now, if you introduce another subtype, eg A is the union of B, C, D, and E, then you correctly need to update your case. But it seems like these case statements tend to be all over your code, instead of neatly managed within a protocol or some such.

simongray08:03:33

I see. So if you have a neatly delimited set of possible options, you’re ok?

slipset08:03:52

And, I guess, unlike protocols and multimethods, consumers of your code are not free to extend A themselves, aka the expression problem

simongray08:03:49

in this case, I think core.match and nested ifs would be about equally extensible 😛

simongray08:03:10

I have precisely 2*2*2=8 cases I need to handle and these cases are already occurring inside a couple of nested ifs, so I thought it was becoming a bit unreadable.

slipset08:03:10

Nested if/else sounds like cond btw

simongray08:03:55

sure, I could do cond too

simongray08:03:03

probably should…

simongray08:03:42

just annoyed me how I would have to make a let in that case and create another indentation level

simongray08:03:59

core.match kinda merges the two

slipset08:03:39

There is another lib, though, don’t remember quite the name, but it was sponsored by clojurists together which was doing somthing like core.match…

borkdude09:03:30

There is also https://github.com/xapix-io/matchete which is a lot simpler, works with babashka and is data/function vs macro driven

borkdude09:03:51

Perf is probably not as good as meander as it doesn't try to optimize as heavily

borkdude09:03:42

About jackson: isn't the same true when including transit? This also depends on Jackson

slipset09:03:51

Haven’t used/looked into transit.

slipset09:03:11

Where does transit depend on Jackson?

slipset09:03:41

transit-java?

borkdude09:03:52

It seems jackson has a pretty sane way of dealing with breaking functionality: https://github.com/FasterXML/jackson/wiki/Jackson-Releases#general So I wonder what the problems with it are? I've never experienced those myself, but I hear some people mention it here and there

borkdude09:03:23

I worry about this from the perspective of babashka, which has both transit and cheshire that depend both on jackson (choices I made early on, they seemed legit choices from a community / track record perspective).

otfrom09:03:44

morning

👋 3
jasonbell10:03:55

@simongray Because bootstrapping comes out of my pocket and RDS is overpriced 🙂

borkdude10:03:26

Almost every project where I started with persisting EDN files ended up using postgres in the end

simongray10:03:33

@jasonbell it was a joke based on the github repo I referenced 😉

jasonbell10:03:36

Yeah but I’m the CEO/CTO/CFO/COO/CMO #“C[A-Z]O”

😁 6
😬 3
borkdude10:03:22

Ending up with postgres didn't have anything to do with management

borkdude10:03:36

More with consistency / corruption

mccraigmccraig10:03:48

if there was an EQL->SQL query generator then you could have a smooth migration path @jasonbell

otfrom11:03:42

everybody who says that databases avoid consistency and corruption hasn't done as many migration or DR jobs as I have 😉

borkdude11:03:49

just storing edn files on disk doesn't always improves the situation though ;)

otfrom11:03:55

nothing more fun than figuring out what proportion of the records have been trashed by a bad migration and then figuruing out how to fix them

otfrom11:03:06

@borkdude true, depends on what you are storing in the edn files

borkdude11:03:35

and how many processes/threads are reading from/writing to those

jasonbell11:03:00

Single processes for me. Fairly slow moving.

otfrom11:03:06

and what needs to be shown when you are reading

otfrom11:03:16

and then we get into jepsen territory 😄

borkdude11:03:42

I recently learned that a postgres connection always maps to one OS process (not thread!)

borkdude11:03:55

so everything you do in a postgres extension is thread-safe by nature

ordnungswidrig11:03:34

that is a nice design. I hope it scales well 🙂

borkdude11:03:16

I think it's more because of ancient design and they can't change anything about this model anymore because so many people depend on it

ordnungswidrig11:03:53

so with 4000 connections this means 4000 os processes?

borkdude11:03:54

Maybe same for Python + GIL + C extensions

borkdude11:03:41

This is a good reason to use a connection pool

ordnungswidrig11:03:59

not sure about modern os (read linux) but I think the context-switch impact is relevant

borkdude11:03:05

I'm not sure if mysql does this differently

agigao12:03:03

I’m kinda lost, code runs from repl and produces the output files, but from main clojure -M:run-m doesn’t executes that last function :man-shrugging:

agigao12:03:41

P.S. @ordnungswidrig thank you, postwalk did the job 🥷

borkdude12:03:35

@chokheli Did you try putting lots of println everywhere? It's my equivalent of "have you tried turning it off and on again" for clojure

borkdude12:03:16

@chokheli It could be a laziness issue. E.g. when you evaluate a lazy seq in the REPL, the printing forces it

agigao12:03:14

Not many, just a few. Regarding laziness - I’m using juxt at the end of the previous function and I think I’m “evaluating it” it, perhaps not.

(defn f [coll]
((juxt f1 f2) coll)))

borkdude12:03:42

it depends on what f1 and f2 do

agigao12:03:00

f1 at the end runs map over some collection and f2 returns a vector

borkdude12:03:26

map is lazy

borkdude12:03:33

maybe try mapv

agigao12:03:43

nope, mapv didn’t change anything 👀 still not evaluating

borkdude12:03:08

but it does reach function f? Have you put a println there?

agigao12:03:46

Oh, it works now, mapv after juxt did the job! Thank you!

otfrom15:03:52

a delightful afternoon of classpath hell

otfrom16:03:19

.cpcache doesn't seem to help much

borkdude16:03:43

@otfrom what version of tools.deps art thou using?

borkdude16:03:10

Anyone got a Raspbery Pi 64bit?

dharrigan16:03:51

spinning it up now

otfrom16:03:54

whatever comes with Clojure CLI version 1.10.2.796

borkdude16:03:37

@otfrom There were some problems with gitlibs in the preview releases, but I think you have a "normal" one. I often have to kill .cpcache and/or .gitlibs if something is up with a gitlib or local/root. It's a bit of a pain sometimes

ordnungswidrig16:03:51

Also for people interested in clojure on microprocessors, @mfikes just release esprit 1.0.0. https://github.com/mfikes/esprit

🧮 3
simongray17:03:46

I'm interested yet have zero uses for it :thinking_face:

ordnungswidrig17:03:15

If you have the solution the problem will come to you 😜