clojure-europe

For people in Europe... or elsewhere... UGT https://indieweb.org/Universal_Greeting_Time
2020-10-06T05:57:42.207100Z

Morning

ordnungswidrig 2020-10-06T07:05:46.207500Z

has broken.

agile_geek 2020-10-06T07:16:18.208100Z

Bore da :welsh_flag:

2020-10-06T07:19:45.208600Z

I'm loving cgrand's xforms

borkdude 2020-10-06T07:22:50.209Z

morning!

jasonbell 2020-10-06T07:38:40.209600Z

Morning

orestis 2020-10-06T08:38:49.210600Z

I’m loving data-driven UIs. I need to spec my UI-driving data more though!

2020-10-06T08:38:55.210800Z

morning!

thomas 2020-10-06T08:54:12.211100Z

moin moin

2020-10-06T09:24:35.211300Z

@orestis what are you using?

orestis 2020-10-06T09:56:24.212100Z

@otfrom I’m using hx for the view layer, and my own reseda library for the state. https://github.com/lilactown/hx https://github.com/orestis/reseda

dharrigan 2020-10-06T10:00:24.213600Z

If anyone is interested, for those following the major.minor.commits approach to tagging repos, I've put together a very simple script to help do that. I use it on my clojure stuff all the time (with a slight variation, I prefix my versions with a rel/)....

πŸ‘ 3
dharrigan 2020-10-06T10:00:37.213800Z

<https://gist.github.com/dharrigan/3e083f8d0fd0fc5646b6871d011a1e02>

dharrigan 2020-10-06T10:00:40.214Z

Enjoy!

borkdude 2020-10-06T15:04:54.214900Z

@otfrom https://twitter.com/borkdude/status/863792981198995456 (including nice comment by Ray!)

ordnungswidrig 2020-10-06T15:05:19.215300Z

I do like monoids.

ordnungswidrig 2020-10-06T15:05:29.215500Z

But I’ve also studied math.

slipset 2020-10-06T15:48:34.216Z

I think not. A monoid is an associative operator with an identity element. (merge-with +) is at most an associative operator.

slipset 2020-10-06T15:49:07.216300Z

Monoids are cool.

slipset 2020-10-06T15:50:34.216600Z

https://clojuredocs.org/clojure.core.reducers/monoid is a fascinating fn

2020-10-06T15:51:23.216700Z

drat. so close

slipset 2020-10-06T15:54:00.217200Z

@borkdude one could argue that maps form a monoid under merge with nil as the identity since

user&gt; (merge nil)
;; =&gt; nil
user&gt; (merge)
;; =&gt; nil
user&gt; (merge {})
;; =&gt; {}
user&gt; (merge {} nil)
;; =&gt; {}
user&gt; (merge nil {})
;; =&gt; {}
user&gt; 

slipset 2020-10-06T15:57:10.218300Z

It seems like merge has two identity values, nil and {}

borkdude 2020-10-06T15:57:18.218600Z

Monoids are just a very simple thing with a fancy name which makes people think they're smart when using it :)

slipset 2020-10-06T15:57:57.219100Z

conj is also monoidic I believe

borkdude 2020-10-06T15:58:37.219800Z

monoids are a datastructure + an operation + an identity element, not one or the other without any given context

πŸ™‚ 1
slipset 2020-10-06T16:00:35.222400Z

Event though (conj) => [], so it somewhat presents an identity value, it doesn't seem to form a monoid with [] as an identity value.

slipset 2020-10-06T16:00:55.223Z

And, it's not really a binary operator of the same type

slipset 2020-10-06T16:01:37.223500Z

into on the other hand, with [] as the identity seem to form a monoid.

slipset 2020-10-06T16:02:22.224Z

(which makes sense since (reduce into [] colls) )

slipset 2020-10-06T16:07:10.225300Z

Another (not really) interesting thing:

user&gt; (clojure.repl/doc merge)
-------------------------
clojure.core/merge
([&amp; maps])
  Returns a map that consists of the rest of the maps conj-ed onto
  the first.  If a key occurs in more than one map, the mapping from
  the latter (left-to-right) will be the mapping in the result.
;; =&gt; nil
user&gt; (merge nil)
;; =&gt; nil
user&gt; (map? nil)
;; =&gt; false
user&gt; 

slipset 2020-10-06T16:07:48.225600Z

So nil is a map, but still it's not.

borkdude 2020-10-06T16:08:55.226400Z

Things are monoids in clojure, except when Rich chose not to in an instanceof check

slipset 2020-10-06T16:09:16.226700Z

Now, that's a tweet πŸ™‚

borkdude 2020-10-06T16:09:39.226900Z

Feel free to tweet ;)

slipset 2020-10-06T16:10:01.227200Z

I'm not sure I grok the true meaning of it yet.

2020-10-06T16:10:21.227600Z

🀯

borkdude 2020-10-06T16:11:02.228400Z

What I'm getting at is that some things are pretty ad hoc in Clojure based on their class. Take contains? for example. Did you know that thing worked on String?

slipset 2020-10-06T16:11:31.228900Z

What I find interesting with the typed fp folks is that they have their types and their "laws"

slipset 2020-10-06T16:12:03.229600Z

The "laws" are the things that the type-system can't help them with. It's where they have to retort to unit-tests

borkdude 2020-10-06T16:12:08.229800Z

user=&gt; (contains? "foo" 1)
true

slipset 2020-10-06T16:12:33.230300Z

Right, because strings are sequential? or some such

borkdude 2020-10-06T16:12:39.230500Z

nope, it's just hardcoded

slipset 2020-10-06T16:14:01.231600Z

Kind'a makes sense since Clojure is written pre-protocols and you can't extend interfaces to existing java-classes.

borkdude 2020-10-06T16:14:26.232Z

I think in hindsight they would not do the string seq / indexed thing again

borkdude 2020-10-06T16:14:40.232200Z

could be wrong, but it feels like a mistake

slipset 2020-10-06T16:14:46.232400Z

I kind'a like it.

slipset 2020-10-06T16:15:02.233Z

means you can use all the sequential fns on strings like interpose, interleave etc?

borkdude 2020-10-06T16:15:37.233800Z

I've been told by Alex: please don't use seq on a string, but str/foobar (e.g. str/blank?). It's just not an good idea to marshall a thing into some other object and then call some function on that which looks up if it's a string again, etc. All that waste of time

borkdude 2020-10-06T16:16:01.234100Z

not really no, interpose doesn't return a string

slipset 2020-10-06T16:16:39.235100Z

No, it doesn't return a string, but you kan get it back by (I've forgotten how)

2020-10-06T16:17:07.235700Z

apply str?

borkdude 2020-10-06T16:17:12.235900Z

yes, with horrible apply str + concat

2020-10-06T16:17:42.236200Z

(apply str (interpose \| "foo"))
"f|o|o"

slipset 2020-10-06T16:18:02.236700Z

exactly

slipset 2020-10-06T16:18:44.237400Z

Probably not something you'd do if you favour performance over golfing πŸ™‚

borkdude 2020-10-06T16:19:36.237800Z

user=&gt; (clojure.string/join "|" "foo")
"f|o|o"
(this calls seq on the string still)

slipset 2020-10-06T16:21:57.238100Z

user&gt; (apply str (interleave "aaa" "bbb"))
;; =&gt; "ababab"
user&gt; 

borkdude 2020-10-06T16:22:33.238400Z

that's nice for 4clojure, but not something you typically do with strings

slipset 2020-10-06T16:22:48.238900Z

exactly. Neat but not useful

slipset 2020-10-06T16:23:03.239200Z

How did we get to here from monoids?

borkdude 2020-10-06T16:23:28.239700Z

the thing with strings being seqables is that it leads to awkward core specs. like many functions take seqables, except strings

borkdude 2020-10-06T16:23:44.240100Z

so then you need a different spec than ::seqable which is annoying

slipset 2020-10-06T16:24:22.240300Z

yep

borkdude 2020-10-06T16:24:35.240700Z

I'm just ranting, don't mind me ;)

slipset 2020-10-06T16:24:53.241200Z

But then maybe the problem is that the fns that take seqables should have accepted strings?

slipset 2020-10-06T16:25:10.241500Z

(apply str (remove #{\a} "blabla")) is kinda nice

slipset 2020-10-06T16:26:09.242200Z

I mean, a string is just a sequence of characters so why bother implementing specific fns for it?

slipset 2020-10-06T16:27:13.242900Z

but then, maybe (into "" (remove #{\a} "blabla")) should have been a thing.

borkdude 2020-10-06T16:28:06.243700Z

oh maybe it was the nil that was annoying

slipset 2020-10-06T16:28:07.243800Z

Which would make sense in a way, since map/filter/etc aren't type-preserving anyway.

slipset 2020-10-06T16:28:35.244700Z

You're getting old. You can't remember why, just that you're annoyed πŸ™‚

slipset 2020-10-06T16:29:08.245400Z

The annoying thing is that clojure.string fns blow up on nil πŸ˜•

slipset 2020-10-06T16:29:22.245900Z

I understand and accept why, but I'm still annoyed.

borkdude 2020-10-06T16:29:45.246400Z

so nil is seqable? but can also be many other things. this annoyed me when creating the type system in clj-kondo, since it checks if something could have been of a certain type, so if something is nilable, it could have been a seqable....

slipset 2020-10-06T16:29:59.246700Z

dinner

borkdude 2020-10-06T16:30:09.247Z

btw @slipset, the type system in clj-kondo heavily borrowed from our core spec project :)

1
borkdude 2020-10-06T16:30:15.247200Z

have a nice dinner

dominicm 2020-10-06T17:18:40.249Z

😩 discovered today that queries are really slow if you have java util logging in with postgres. Was costing us 4x. I love the profiler we have in clojure, it's awesome.

orestis 2020-10-06T18:24:39.249600Z

How do you mean? We’re you logging each query/result?

dominicm 2020-10-06T19:51:42.249900Z

Postgres has built in logging

borkdude 2020-10-06T20:00:50.250100Z

what does that have to do with java util logging though?

borkdude 2020-10-06T20:01:43.250300Z

@slipset See https://github.com/borkdude/clj-kondo/blob/master/src/clj_kondo/impl/types/clojure/core.clj A lot of this resembles the speculative specs

slipset 2020-10-06T20:45:23.250700Z

Cool πŸ™‚

slipset 2020-10-06T20:47:40.250900Z

That’s a lot of work…

dominicm 2020-10-06T21:02:12.251100Z

That's what postgresql uses

borkdude 2020-10-06T21:02:52.251300Z

huh.... b-b-but postgres is not written in java is it

dominicm 2020-10-06T21:03:18.251500Z

Sorry, I mean the postgresql java driver!

dominicm 2020-10-06T21:03:44.251700Z

I see now that I ignored that key term πŸ˜‚ long day as you can imagine

borkdude 2020-10-06T21:03:46.251900Z

ah, right.

borkdude 2020-10-06T21:04:11.252100Z

I usually enable the logging in postgres itself to see the queries

dominicm 2020-10-06T21:05:21.252300Z

Yeah, I'm not sure what postgres is doing tbh