clojure-europe

For people in Europe... or elsewhere... UGT https://indieweb.org/Universal_Greeting_Time
dharrigan 2021-01-21T07:26:09.000300Z

Good Morning!

djm 2021-01-21T07:31:38.000500Z

šŸ‘‹

slipset 2021-01-21T07:35:52.000700Z

morning

matlux 2021-01-21T07:39:47.000900Z

Morning

orestis 2021-01-21T07:43:24.001100Z

Good morning

orestis 2021-01-21T07:44:53.003Z

Would people pay for commercial licenses for Clojure libraries that deal with things such as SAML, emails, etc? All the boring bits and plumbing that you have to wade through just to get to something useful.

orestis 2021-01-21T07:45:35.004300Z

Iā€™m not talking about low level stuff, more like solving high level problems including eg email validation, monitoring, throttling, etc etc

javahippie 2021-01-21T07:47:52.006100Z

For me, licensing valuable libraries is okay, as long as the licensing process is not too heavy, I can evaluate before buying and the licensing does not bind me for 20 years. I prefer buying support for open source libraries, but thatā€™s a business model that is easily exploited (as we heard this week)

ordnungswidrig 2021-01-21T07:51:49.006300Z

Guten morgen!

orestis 2021-01-21T07:52:42.007100Z

I like the license model where the closed license expires after a few years.

matlux 2021-01-21T07:53:29.007300Z

I can't see any issue. As long as x is never mutated further down the let or after an escape somewhere else. You are closing over it and reading it in another thread. Is the point of using immutable data structure in Clojure not to be able to pass that kind of references across threads without worrying? You only need an atom if your threads mutate x.

1šŸ‘
javahippie 2021-01-21T07:53:33.007700Z

(forgot: Morning)

javahippie 2021-01-21T07:54:07.008500Z

Thatā€™s a good one. For closed source libraries, bankruptcy of the vendor is a huge concern for companies, this would address that

javahippie 2021-01-21T07:59:38.009600Z

I like the pricing of jOOQ. Itā€™s free with Open Source databases, and the enterprisier the DBs you use get, the more expensive the license gets, too: http://www.jooq.org/download/

orestis 2021-01-21T07:59:50.010200Z

Agree, itā€™s one of the things that deters me from datomic usage.

thomas 2021-01-21T08:17:30.010700Z

morning

raymcdermott 2021-01-21T08:19:21.010900Z

morning

dharrigan 2021-01-21T08:40:46.011200Z

I use JOOQ quite a bit, when doing Kotlin.

ordnungswidrig 2021-01-21T08:40:59.011500Z

What does it even do? JPA but better?

dharrigan 2021-01-21T08:41:10.011700Z

much better, not JPA at all

dharrigan 2021-01-21T08:41:26.012100Z

It basically introspects your db and creates a DSL for writing plain old sql

djm 2021-01-21T08:42:02.012900Z

I've used jOOQ. It's quite nice, but I didn't ever manage to make complex queries not look horrible

ordnungswidrig 2021-01-21T08:42:14.013400Z

Well, SQL is quite optimized for what it does.

dharrigan 2021-01-21T08:42:30.013800Z

I'm spoilt now with HoneySQL

djm 2021-01-21T08:44:12.014800Z

And when trying to extract stuff into methods, you can end up with crazy return types like SelectConditionStep<Record4<Long, Integer, Integer, Integer>>

dharrigan 2021-01-21T08:44:34.015100Z

Are you using Kotlin?

dharrigan 2021-01-21T08:44:41.015600Z

You can destructure that very nicely

djm 2021-01-21T08:44:44.015800Z

No, Java

djm 2021-01-21T08:44:51.016300Z

But that sounds interesting

dharrigan 2021-01-21T08:45:00.016600Z

.map { (foo, bar, baz, quz) -> ..... }

dharrigan 2021-01-21T08:45:32.017300Z

Using Kotlin really does make using JOOQ a lot lot nicer

ordnungswidrig 2021-01-21T08:45:37.017500Z

Oh, yes. These times where I had to build a domain model User extends Entity<UserKey>> and so on. God bless persitent datastructuresā€¦

javahippie 2021-01-21T08:46:24.018200Z

ā€œThese timesā€ are still relevant for me šŸ˜«. Searching a way out of those Enterprise-Big-Company projects

borkdude 2021-01-21T08:46:59.019100Z

Morning. Does anyone have a Raspberry Pi (64bit) here? There is now a non-official binary for babashka: https://github.com/babashka/babashka/issues/241#issuecomment-764009022

dharrigan 2021-01-21T08:47:32.019700Z

My Pi 4 Model B is due to arrive today

djm 2021-01-21T08:47:47.020Z

In Kotlin-land I'd like to play around with SQLDelight, but Kotlin + jOOQ could be fun

djm 2021-01-21T08:47:58.020300Z

I only have 32bit RPis

dharrigan 2021-01-21T08:48:22.020700Z

I can give bb a whirl later

djm 2021-01-21T08:48:36.021Z

(Zero and 3B+)

djm 2021-01-21T08:50:21.021600Z

I thought about getting an RPi 4, but it sounded like the power consumption was quite a lot higher

dharrigan 2021-01-21T08:50:41.021800Z

I've got a PoE Hat for it

dharrigan 2021-01-21T08:50:45.022Z

plug'n'play šŸ™‚

dharrigan 2021-01-21T08:51:53.022500Z

Here's a little bit of JOOQ + Kotlin, if people aren't offended šŸ™‚

dharrigan 2021-01-21T08:52:00.022700Z

magnumDslContext
            .select(POI_TYPE.POI_TYPE_ID, POI_TYPE.UUID, POI_TYPE.NAME, POI_TYPE.ICON)
            .from(POI_TYPE)
            .where(POI_TYPE.UUID.eq(UUID.fromString(uuid)))
            .and(POI_TYPE.TENANT_ID.eq(tenantId))
            .fetchOne { (poiTypeId, uuid, name, icon) ->
                PoiType(_id = poiTypeId, id = uuid.toString(), name = PoiType.Type.valueOf(name), icon = icon)
            }

ordnungswidrig 2021-01-21T08:52:55.023500Z

Does Kotlin support something like dynamic languageā€™s ā€œad hocā€ datastructures? Oh do you still need to define a static language model (classes) to hold data?

dharrigan 2021-01-21T08:53:13.023800Z

It's static, so you need what are called data classes

dharrigan 2021-01-21T08:53:17.024Z

i.e.,

dharrigan 2021-01-21T08:53:50.024900Z

data class Foo (val name: String? = "", val age: Int? = 0)

borkdude 2021-01-21T08:53:59.025300Z

I recently played with golang. I expected it to be hard to do dynamically typed things, but it's incredibly easy just by casting everything to interface{} :)

1šŸ˜ˆ
dharrigan 2021-01-21T08:54:34.026Z

but with the Kotlin Dataclass, it takes default's, so I can just do var foo = Foo() and it'll prepopulate it with name = "" and age = 0

dharrigan 2021-01-21T08:54:52.026400Z

it supports destructing, so I can then do val (name, age) = foo

dharrigan 2021-01-21T08:55:24.027Z

tbh, it's a very nice language, and when I'm working with my fellow co-workers, and in Kotlin lang, I'm quite happy

dharrigan 2021-01-21T08:55:51.027400Z

but you can pry Clojure from my cold dead hands :)

2šŸ˜‚
djm 2021-01-21T09:01:23.027800Z

If you're interested, when trying to do something vaguely complex, we ended up with http://djm.blinkenshell.org/jooq_repository_example1.txt , which we refactored to use CTEs to try to make more readable, and ended up with http://djm.blinkenshell.org/jooq_repository_example2.txt I'm not sure if Kotlin has anything that would help with that

djm 2021-01-21T09:01:39.028Z

I'm also not sure if the CTE version is actually more readable :man-shrugging:

dharrigan 2021-01-21T09:02:02.028200Z

interesting!

djm 2021-01-21T09:02:38.028400Z

We needed to pull out data for the first of the year, and the last day for each month that actually had any data

jasonbell 2021-01-21T09:04:40.028800Z

Morning

dharrigan 2021-01-21T09:06:01.028900Z

I certainly favour this approach far more than JPA.

dharrigan 2021-01-21T09:06:11.029100Z

Which I don't think I've used for many-a-year now!

djm 2021-01-21T09:07:21.029300Z

Plain SQL is hard to beat, but we wanted the type safety of jOOQ... which did come in handy as the database was outside of our control, and kept changing, a lot!

djm 2021-01-21T09:08:49.029500Z

Using Kotlin for the tests also helped for that, val expected = FooRecord.apply { id = 1, foo = 2, bar = 3, ... }, meant that our tests didn't keep breaking when the database changed

dharrigan 2021-01-21T09:09:21.029700Z

I share your pain, I have a db that is not under my control too, so yes, having JOOQ is superdoopar handy

mpenet 2021-01-21T09:15:25.030200Z

@borkdude a suggestion clj-kondo upgrade

mpenet 2021-01-21T09:18:13.030600Z

might belong to #clj-kondo

2021-01-21T09:19:14.030700Z

correct, sorry, I thought you were mutating stuff

jkxyz 2021-01-21T09:25:20.031Z

Good morning!

2021-01-21T09:36:19.031200Z

morning

slipset 2021-01-21T09:43:15.031900Z

I think Iā€™d be happy to pay for libs to solve auth etc, but I would want to have the source available to me.

orestis 2021-01-21T10:15:36.033200Z

I wonder if it makes economic sense via Patreon/GH sponsors etc to take on this role in a community.

slipset 2021-01-21T10:51:11.034300Z

I think what I would want is a system like the one used for Cursive, albeit a bit more complicated in some way, because Iā€™d need access to the source code (at least once I started paying, or when I went into some agreement/NDA with them).

2021-01-21T10:51:53.035200Z

I'm happy (and do) contribute to open source. I'm always very nervous about anything proprietary in my stack

slipset 2021-01-21T10:51:55.035400Z

Not having access to source code is a major PITA when you need to debug

2šŸ‘
2021-01-21T10:52:12.035900Z

sry, contribute financially

2021-01-21T10:52:18.036400Z

I also do PRs šŸ˜‰

ordnungswidrig 2021-01-21T10:52:26.036800Z

@slipset one of my biggest concerns, too.

slipset 2021-01-21T10:52:33.037100Z

The thing I hope my company would be happy to pay for is a security lib that was, well secure.

ordnungswidrig 2021-01-21T10:53:03.037500Z

@slipset how would you know when itā€™s open source?

slipset 2021-01-21T10:53:13.037700Z

Know what?

ordnungswidrig 2021-01-21T10:53:20.037900Z

that itā€™s secure

slipset 2021-01-21T10:55:55.040200Z

Iā€™m not sure I understand the question, but any how. Say that https://www.pac4j.org was delivered by a company who sold pac4j licenses to companies. I would probably be willing to pay for that, given that I also had access to the source code of the lib(s) I licensed.

slipset 2021-01-21T10:56:24.040700Z

If there were libs/shims for Clojure, Iā€™d probably be willing to pay more.

slipset 2021-01-21T10:57:37.041500Z

Basically, I want to out-source security and the responsibility for fixing bugs in security libraries to a (knowledgeable) third party.

slipset 2021-01-21T10:58:18.041700Z

I guess something like https://www.pac4j.org/commercial-support.html is offering.

slipset 2021-01-21T10:59:06.041900Z

The company https://www.casinthecloud.com/index-en.html

simongray 2021-01-21T11:01:08.042400Z

belated goodmorning

ordnungswidrig 2021-01-21T11:01:29.042800Z

@slipset I was refering to the access to source code.

orestis 2021-01-21T12:16:01.044200Z

Security evaluation is kind of a social thing, right? I trust latacora based on their reputation and because Iā€™ve met lvh and heā€™s wicked smart, and spending all his time in security. I have no means to evaluate objectively if theyā€™re actually good at security or not.

orestis 2021-01-21T12:16:59.045100Z

So paying a company to deal with security and releasing libraries that I could use, is helping them make such a reputation for themselves and hire good people etc etc. Much better than using a library that some company developed in-house and released after.

orestis 2021-01-21T12:17:20.045600Z

Thereā€™s a limit on how much auditing of 3rd-party dependencies on can reasonably do.

slipset 2021-01-21T13:50:37.047Z

It is also nice as a consumer of a security lib to be in a somewhat more formalized contract situation than ā€œIā€™ll fix it wheneverā€.

slipset 2021-01-21T13:50:55.047300Z

Even though I donā€™t like to enter into SLAā€™s myself.

2021-01-21T14:05:15.047800Z

and I'm not sure most commercial companies would have an SLA that would bind them to fixing something in a particular time frame

2021-01-21T14:05:22.048Z

(the joke of one throat to choke)

raymcdermott 2021-01-21T14:14:31.049600Z

most companies, like most organisations (and people!) will only be pushed into changing things if their largest donors threaten to abandon them

2021-01-21T14:37:57.050100Z

yeah, but successful companies won't be too beholden to any one customer

jtkdvlp 2021-01-21T14:42:34.050300Z

@matlux I agree with you, I assumed it as you described. The strange thing macroexpanding it gives an error. So I was wondering if it is a bad idea. Do you have an idea whats wrong expanding it?

(clojure.walk/macroexpand-all
   '(let [x 5]
      (clojure.core.async/go
        (println x))))

;; => Syntax error macroexpanding clojure.core.async/go at (your_project.cljc:93:3).
;;    Could not resolve var: x

mpenet 2021-01-21T14:44:05.051500Z

indeed. it's a crappy situation (happened to a place where I worked in the past). 1 client that was basically 30% of the yearly revenue

raymcdermott 2021-01-21T14:45:13.052800Z

sure, having a large set of diverse customers is the dream

slipset 2021-01-21T14:55:54.053500Z

I think thatā€™s what Basecamp has done.

1šŸ¤˜
matlux 2021-01-21T15:30:10.053600Z

Strange indeed that it doesnā€™t macroexpand-all correctly. It does compile and execute though:

(let [x 5]
    (clojure.core.async/go
      (println x)))
=>
#object[clojure.core.async.impl.channels.ManyToManyChannel
        0x67080483
        "clojure.core.async.impl.channels.ManyToManyChannel@67080483"]
5

matlux 2021-01-21T15:35:21.053800Z

I have managed to macroexpand-all it by cheating the compiler:

(clojure.walk/macroexpand-all '(let [x 5]
                                 (clojure.core.async/go
                                   (println "x"))))
and then re-introduced the x symbol back in and it compiled and executed too. So the code is definitely valid. Must be a bug or a corner case in the macro-expansion. I reckon it is because x is a local and it doesnā€™t get added to the env of the macroexpansion-all code. The macro-expansion must be only looking at global var s or something. It might be interesting to find out what exactly upset the macroexpand-all hereā€¦ ??

1šŸ‘1šŸ˜„