clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
javahippie 2020-11-16T08:10:14.106800Z

That’s a good point, thanks! I guess it is not too far of to assume, that there might be multiple classloaders at work when connecting Cider to a REPL… :thinking_face:

2020-11-16T17:38:22.108900Z

Is there anything in the Clojure ecosystem approaching an auto-generated admin web interface, à la Django or JHipster?

lukasz 2020-11-16T17:40:04.109600Z

For read-only tasks you could use Metabase, I'm not aware of any solutions providing R/W access.

dominicm 2020-11-16T18:16:47.109800Z

I've used retool and react-admin via a REST interface for this sort of thing.

dominicm 2020-11-16T18:17:09.110Z

Does anyone have a source for "don't write wrapper libraries that are thin wrappers around Java unless you're adding value", I want to use some appeal to authority :)

p-himik 2020-11-16T18:23:47.110200Z

I think I remember @hiredman saying something like that a few times.

nbardiuk 2020-11-16T18:24:49.110400Z

Similar quote

Because the Java invocation syntax in Clojure is clean and simple, it's
idiomatic to use Java directly, rather than to hide Java behind Lispy wrappers.
in Programming Clojure https://pragprog.com/titles/shcloj3/programming-clojure-third-edition/

nbardiuk 2020-11-16T18:29:16.110800Z

another one

Clojure embraces Java and its libraries. Idiomatic Clojure code calls Java
libraries directly and doesn't try to wrap everything under the sun to look
like Lisp. This surprises many new Clojure developers but is very pragmatic.
Where Java isn't broken, Clojure doesn't fix it.

2020-11-16T18:30:59.111Z

this was the primary feature of the defunct Caribou project (what I worked on at my first ever Clojure job ages ago...)

2020-11-16T18:32:12.111200Z

personal experience: it's like a framework, it works perfectly until you leave the original author's happy path, then you need to fork it because they misunderstood or incompletely covered the underlying API

2020-11-16T18:32:51.111400Z

doing interop in the first place is less work than maintaining a fork of a thin wrapper

2020-11-16T18:33:01.111600Z

also the wrapper adds layers / complexity

dominicm 2020-11-16T18:33:27.111800Z

Wonderful, thanks :)

borkdude 2020-11-16T18:33:29.112Z

it totally depends. wrappers can give idiomatic access while leaving the Java world open for extension

2020-11-16T18:34:00.112200Z

right - ring for example

dominicm 2020-11-16T18:34:01.112400Z

@noisesmith Exactly right. Even just minor things like spending 30 minutes wondering why a property that's clearly in the libs docs isn't being applied until you reason the wrapper is shit and only passes along the 3 keys that the original author cared about. /tableflip.

2020-11-16T18:34:07.112600Z

but I haven't seen this for thin wrappers

dominicm 2020-11-16T18:34:16.112800Z

Ring is not a thing wrapper - it's a unique abstraction :)

borkdude 2020-11-16T18:34:30.113Z

@dominicm What wrapper is this about?

dominicm 2020-11-16T18:34:54.113200Z

@borkdude just some react component that's pretty thin when used from Helix anyway.

borkdude 2020-11-16T18:35:39.113400Z

ok. what I had in mind, e.g. babashka.process: https://github.com/babashka/process it's a convenient way of creating processes from Clojure while still having access to the raw underlying java stuff

1👍
dominicm 2020-11-16T18:41:00.113800Z

That's not thin. It's a little bit of an abstraction. Like a cracker, but not quite a biscuit.

timsgardner 2020-11-16T18:42:31.114Z

though ideally I wouldn't have to, the node process should be able crash without clojure sticking around

borkdude 2020-11-16T18:46:30.114200Z

@timsgardner Babashka supports killing all sub-processes on shutdown. It has great startup time. So you could consider booting node from bb and then kill all on shutdown

timsgardner 2020-11-16T18:47:12.115100Z

I might switch to it, thanks

borkdude 2020-11-16T18:48:54.115300Z

An example using clojure:

$ bb -e "(require '[babashka.process :as p]) (p/process [\"clojure\"] {:inherit true :shutdown p/destroy-tree}) @(promise)"
Clojure 1.10.1
user=> (+ 1 2 3)
6
user=> ^C%

borkdude 2020-11-16T18:51:03.115500Z

You can also do this in Clojure proper btw, babashka/process is also available on the JVM. Or you could just write the JVM interop code yourself

2020-11-16T18:51:28.115700Z

ah, interesting! https://github.com/caribou

2020-11-16T18:56:34.116Z

it's very old, and not under active development

2020-11-16T19:14:47.116200Z

yeah, might still be interesting to peruse and see the approach taken, as compared to the aforementioned frameworks

2020-11-16T19:21:33.116400Z

the general idea was defining the content of the site via database, then using DB CRUD to control what's displayed

2020-11-16T19:22:30.116600Z

use case was the end user has content admins who could be trained to use the admin UI, with the power to create new assets paths and layouts via DB upload without dev work

2020-11-16T19:22:48.116800Z

yeah, that sounds quite similar to what Django was originally envisioned to do, actually

2020-11-16T19:22:52.117Z

the original sponsors ended up switching to squarespace

2020-11-16T19:23:09.117200Z

yeah, django was definitely an inspiration

2020-11-16T19:23:34.117400Z

I have no clue how many deployments kept the auto admin interface, though, versus rolling their own

2020-11-16T19:23:55.117600Z

@jeffrey.wayne.evans one example of an idea from that project that could be imported elsewhere: using a db data model for paths, and then consuming that in the back end to create a router

Asko Nõmm 2020-11-16T20:01:02.119400Z

Does anyone have any experience with jdbc / mysql here? Namely I have an issue where after some time of inactivity, and then again trying to connect to the database .. it fails with a Operation timed out (Read failed) . I’ve been trying to find a way to configure it to reconnect on timeout, but haven’t yet found a way. Does anyone have any ideas?

seancorfield 2020-11-16T20:01:46.120100Z

#sql is your best bet as a channel for that Q @asko

Asko Nõmm 2020-11-16T20:02:16.120200Z

Ah, didn’t know of it! Thank you for pointing me in a direction :)

2020-11-16T21:21:21.120400Z

I like wrapper libraries. I have written many which I would characterize as thin but add a modicum of value. There are many situations where Java libraries have unwieldy class structure and wrapping eases the pain.

2020-11-16T21:21:50.120600Z

I really don't like when engineers create context-free edicts for all to follow. We don't need that much religion.

dgb23 2020-11-16T21:24:18.120900Z

This is a good point and puts the quotes into context. Obviously if your wrapper provides some tangible benefits outside of just hiding Java interop, then it adds value. The point of the quotes are rather: Java interop by itself is both idiomatic and ergonomic and doesn’t require wrapper per se.

2020-11-16T21:27:44.121100Z

I agree, I have moved away from clj-time, but more importantly java-time , for example, and prefer java.time access via interop.

2020-11-16T23:28:54.121300Z

I don't have one either, was just curious.

2020-11-16T23:30:40.121500Z

By the way, I don't know if it helps. But where I've landed with my experimentation is something very similar to how symbols and namespaces work. I quickly details it here: https://clojureverse.org/t/spec-ing-entities-and-how-to-organize-the-specs-and-our-entity-keys-a-new-approach/6817/8?u=didibus

walterl 2020-11-16T23:41:48.122300Z

This is a very informative discussion! It particularly reminded me of a recent case where I recommended not returning AWS data *Response Java objects from functions, but rather converting them to Clojure maps. Does the maxim discussed here suggest that that was wrong? In other words, does the interop argument extend to directly working with Java data structures (in object hierarchies), rather than wrapping them in a thin Clojure data translation layer? How about when all the operations and data involved are limited to a single namespace?

2020-11-16T23:56:17.122500Z

the watershed line is if the wrapper is an external dependecy

2020-11-16T23:57:54.122700Z

bringing in an external dependency that doesn't justify itself is bad, and wrapping is no justification

2020-11-16T23:58:33.122900Z

for internal stuff the question is a lot less clear cut

1👍