clojure-europe

For people in Europe... or elsewhere... UGT https://indieweb.org/Universal_Greeting_Time
plexus 2021-03-15T04:51:30.046300Z

Moin moin

agigao 2021-03-15T06:26:07.046900Z

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

mccraigmccraig 2021-03-15T06:26:27.047100Z

morening

djm 2021-03-15T06:41:49.047300Z

👋

orestis 2021-03-15T06:59:38.047500Z

Morning

ordnungswidrig 2021-03-15T07:04:57.047900Z

Good morning. And ❄️

synthomat 2021-03-15T07:09:02.048100Z

good morning!

dharrigan 2021-03-15T07:10:20.048300Z

Good Morning!

agigao 2021-03-15T07:13:52.049200Z

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

dharrigan 2021-03-15T07:38:38.049600Z

Would a nice little recursive function work here?

agigao 2021-03-15T07:42:32.050100Z

Yup, I think so

ordnungswidrig 2021-03-15T07:49:06.050600Z

treewalk 🙂

ordnungswidrig 2021-03-15T07:49:29.051100Z

postwalk and collect into a seq

☝️ 1
ordnungswidrig 2021-03-15T07:50:42.052400Z

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

simongray 2021-03-15T08:09:03.052600Z

good morning

slipset 2021-03-15T08:21:50.055100Z

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

ordnungswidrig 2021-03-15T08:22:10.055900Z

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

slipset 2021-03-15T08:22:11.056Z

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

agigao 2021-03-15T08:22:31.056300Z

@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 🥺

ordnungswidrig 2021-03-15T08:23:02.056900Z

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

agigao 2021-03-15T08:23:41.057400Z

Oh 😇

ordnungswidrig 2021-03-15T08:23:42.057500Z

Maybe tree-seq also works

slipset 2021-03-15T08:25:09.058300Z

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

slipset 2021-03-15T08:26:06.059Z

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

slipset 2021-03-15T08:27:34.059800Z

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

slipset 2021-03-15T08:28:05.060500Z

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.

slipset 2021-03-15T08:29:44.062100Z

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.

ordnungswidrig 2021-03-15T08:32:28.062700Z

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

slipset 2021-03-15T08:34:13.063500Z

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.

slipset 2021-03-15T08:35:32.064800Z

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.

2021-03-15T08:42:40.067400Z

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

❤️ 1
simongray 2021-03-15T08:44:17.068400Z

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.

slipset 2021-03-15T08:45:45.069400Z

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

plexus 2021-03-15T08:47:20.071800Z

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

slipset 2021-03-15T08:48:21.072900Z

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.

simongray 2021-03-15T08:49:33.074200Z

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

slipset 2021-03-15T08:49:52.074600Z

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

slipset 2021-03-15T08:50:15.074800Z

https://en.wikipedia.org/wiki/Expression_problem

simongray 2021-03-15T08:52:49.075800Z

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

slipset 2021-03-15T08:54:02.076200Z

Somewhat related https://insideclojure.org/2015/04/27/poly-perf/

simongray 2021-03-15T08:56:10.077600Z

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.

slipset 2021-03-15T08:56:10.077700Z

Nested if/else sounds like cond btw

simongray 2021-03-15T08:56:55.078Z

sure, I could do cond too

simongray 2021-03-15T08:57:03.078200Z

probably should…

simongray 2021-03-15T08:57:42.078800Z

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

slipset 2021-03-15T08:57:55.079100Z

🙂

simongray 2021-03-15T08:57:59.079300Z

core.match kinda merges the two

slipset 2021-03-15T08:58:39.080Z

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…

jasonbell 2021-03-15T08:58:59.080200Z

Morning

borkdude 2021-03-15T09:00:01.080400Z

@slipset Meander?

slipset 2021-03-15T09:00:07.080600Z

exactly

borkdude 2021-03-15T09:00:30.081Z

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

borkdude 2021-03-15T09:00:51.082Z

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

borkdude 2021-03-15T09:03:52.082200Z

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

borkdude 2021-03-15T09:08:42.082700Z

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

plexus 2021-03-15T09:09:02.082900Z

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

slipset 2021-03-15T09:09:39.083300Z

Could be.

slipset 2021-03-15T09:09:51.083600Z

Haven’t used/looked into transit.

thomas 2021-03-15T09:10:21.083800Z

morning

slipset 2021-03-15T09:11:11.084100Z

Where does transit depend on Jackson?

slipset 2021-03-15T09:11:41.084300Z

transit-java?

slipset 2021-03-15T09:12:00.084500Z

Jupp

borkdude 2021-03-15T09:46:52.085400Z

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

borkdude 2021-03-15T09:47:23.086Z

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).

2021-03-15T09:58:44.086400Z

morning

👋 1
2021-03-15T09:58:52.086700Z

:morning:

jkxyz 2021-03-15T09:59:13.087Z

Morning!

simongray 2021-03-15T10:20:24.087400Z

@jasonbell https://github.com/lilactown/autonormal

jasonbell 2021-03-15T10:22:55.088200Z

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

borkdude 2021-03-15T10:23:26.088800Z

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

simongray 2021-03-15T10:24:33.089900Z

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

jasonbell 2021-03-15T10:24:36.090100Z

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

😬 1
😁 2
borkdude 2021-03-15T10:25:22.090600Z

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

borkdude 2021-03-15T10:25:36.091100Z

More with consistency / corruption

mccraigmccraig 2021-03-15T10:26:48.092100Z

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

simongray 2021-03-15T10:28:20.092300Z

@mccraigmccraig https://walkable.gitlab.io/

mccraigmccraig 2021-03-15T10:30:19.092800Z

ooo, lovely!

jasonbell 2021-03-15T10:30:40.093Z

nice!

2021-03-15T11:13:42.094Z

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

jasonbell 2021-03-15T11:14:01.094200Z

🙂

borkdude 2021-03-15T11:15:49.095Z

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

2021-03-15T11:15:55.095200Z

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

2021-03-15T11:16:06.095500Z

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

borkdude 2021-03-15T11:16:35.095800Z

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

jasonbell 2021-03-15T11:17:00.096300Z

Single processes for me. Fairly slow moving.

2021-03-15T11:17:06.096500Z

and what needs to be shown when you are reading

2021-03-15T11:17:16.096800Z

and then we get into jepsen territory 😄

borkdude 2021-03-15T11:18:42.097200Z

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

borkdude 2021-03-15T11:18:55.097600Z

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

ordnungswidrig 2021-03-15T11:25:47.097800Z

Pattern matching is fine when there is a pattern.

ordnungswidrig 2021-03-15T11:25:51.098Z

🙂

ordnungswidrig 2021-03-15T11:26:03.098200Z

And often it’s preferrable over nested conditionals

ordnungswidrig 2021-03-15T11:26:59.098400Z

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 🙂

ordnungswidrig 2021-03-15T11:28:34.098800Z

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

borkdude 2021-03-15T11:29:16.099300Z

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

ordnungswidrig 2021-03-15T11:29:53.100100Z

so with 4000 connections this means 4000 os processes?

borkdude 2021-03-15T11:29:54.100200Z

Maybe same for Python + GIL + C extensions

borkdude 2021-03-15T11:30:10.100400Z

yes

borkdude 2021-03-15T11:30:41.101100Z

This is a good reason to use a connection pool

ordnungswidrig 2021-03-15T11:30:59.101600Z

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

borkdude 2021-03-15T11:31:05.101800Z

I'm not sure if mysql does this differently

agigao 2021-03-15T12:41:03.104300Z

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:

agigao 2021-03-15T12:41:41.104900Z

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

borkdude 2021-03-15T12:42:35.105500Z

@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

borkdude 2021-03-15T12:43:16.106Z

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

agigao 2021-03-15T12:45:14.107700Z

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)))

borkdude 2021-03-15T12:45:42.108100Z

it depends on what f1 and f2 do

agigao 2021-03-15T12:47:00.108900Z

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

borkdude 2021-03-15T12:47:26.109100Z

map is lazy

borkdude 2021-03-15T12:49:33.109400Z

maybe try mapv

agigao 2021-03-15T12:54:43.110Z

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

borkdude 2021-03-15T12:55:08.110300Z

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

agigao 2021-03-15T12:57:46.111Z

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

2021-03-15T15:59:52.111400Z

a delightful afternoon of classpath hell

2021-03-15T16:00:19.111700Z

.cpcache doesn't seem to help much

borkdude 2021-03-15T16:01:43.112100Z

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

borkdude 2021-03-15T16:02:10.112200Z

Anyone got a Raspbery Pi 64bit?

dharrigan 2021-03-15T16:02:48.112400Z

I have one

dharrigan 2021-03-15T16:02:51.112600Z

spinning it up now

2021-03-15T16:03:54.112900Z

whatever comes with Clojure CLI version 1.10.2.796

borkdude 2021-03-15T16:04:37.113700Z

@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

ordnungswidrig 2021-03-15T16:46:51.114700Z

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

🧮 1
ordnungswidrig 2021-03-16T17:41:15.067200Z

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

simongray 2021-03-15T17:06:46.114900Z

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