Hacker News new | past | comments | ask | show | jobs | submit login
Clojure Web Development Evolved [video] (youtube.com)
129 points by yogthos on July 29, 2022 | hide | past | favorite | 43 comments



Another attempt at the Rails for Clojure. Great. The web stacks (yes stacks, there are many at this point) are very mature. I'm getting tired of seeing people re-inventing the wheel over and over again.

I love Clojure, but this language is going to die off if people don't start putting more effort into building mundane, everyday libraries. (I know I am). Clojure has high velocity, but it's always offset by having to create new libraries or update rotting ones.

I've noticed a ton of software rot in what were once major Clojure libraries, like Onyx and Cortex, now fading into obsolescence.

I'm sorry, but I will keep bitching about this on HN until people help me.


I feel your frustration. Clojure, in my opinion, has always been niche, but is still effective and may actually be immortal? New things are always being tried by small groups of people leaving corpses strewn about.

I don't think it is the building, so much as the burying that needs more work, so that we know what libraries do or don't need tombstones.

To the best of my knowledge, Onyx and Cortex were both backed by companies which either needed to move onto more successful products, or in the case of Cortex, they closed up shop. It might be better to look at libraries that have stronger community support.

Onyx is an amazing library but it competes with other libraries like KafkaStreams which has community buy in, and commercial support if needed.

Cortex might be replaced with mxnet which got clojure bindings sometime in the last couple of years (see gigasquid). (Although libpython might make this redundant -- assuming language purity isn't a blocker to being pragmatic).

Others will have better examples, but here are some simple ones that are well maintained, but lets not forget that the java ecosystem is also available:

clojure clojurescript core.async mxnet integrant

Its good to remember that what might be considered "rot" in some ecosystems, is just a sign of maturity and of a library being finished. Many older libraries with no commits in years function as is, as documented.


> Its good to remember that what might be considered "rot" in some ecosystems, is just a sign of maturity and of a library being finished. Many older libraries with no commits in years function as is, as documented.

I’ve noticed that pattern in the lisps and Erlang. Things are dead, they just don’t really need any changes.


Yes, and if I may add a few more libraries that are actively maintained, with wonderful documentation and great functionalitY -- next.jdbc for SQL, Timbre for logging, Sente for websockets, Reitit for routing, Carmene for Redis, re-frame for frontend state management, Datascript for frontend DB, and many more.


I think Onyx and Cortex always were redundant. You have Kafka and Spark/SparkML and Storm, you can use them from Clojure without problems.

If Onyx had been the first, it could have become what Spark is, possibly.

My point being, I don't really think every language needs a distributed compute, just need one and have bindings from your language to use it. Clojure being Java has access to many bindings for many of those popular libraries.


Clojure libraries are good but you have Java and JS interop for mundane, everyday libraries. Is there anything wrong with interop?

I think most Clojure libraries rightfully focus on things that either only possible or needed in Clojure. Things like core async, typed clojure are not even possible to implement in other languages as libraries.

When thinking of examples: the cognitect/aws-api is amazing in it's ease and fun, yet AWS Java SDK is also easy to use from clojure. I prefer the former, but there isn't anything wrong with the latter.


As someone alluded to, Interop can be frustrating with big frameworks.

Interop also relies heavily on reflection, and may require type hinting once it becomes a performance problem. Interop also implies the use of side-effects since we're relying on Java object. While a lot of Clojure's sequence and collection operations do work on Java sequences and Collections, it's not perfect and very easy to get bitten, requiring a Clojure.walk/postwalk and zipmap with coercion to get a good Java->Clojure container/sequence/collection.

If we used interop for everything mundane, Clojure would really just be an S-expression shaped husk over Java code. Not a very great solution imho.


I'll politely disagree. The mundane libraries I think you're talking about tend to be about IO, that's always going to be side-effectful in nature. Their APIs wouldn't be all that different even if implemented directly in Clojure.

Type hinting isn't hard or time consuming, literally you can take 10min and have everything type hinted.

Now I don't know about big frameworks, maybe I don't find a need for big frameworks? But even then, what kind of framework are you talking about? Using Spring MVC for example?


A problem I have run into (admittedly, having not written as much clojure code as I'd like) is that some java libraries in particular can make interop distinctly unpleasant. Anything around the Spring framework, for instance, made me tear my hair out. Yes it's possible, but by the time you've compensated for the impedance mismatch you might as well have done a rewrite.


Hum, I've used Spring with Clojure a lot, never had issues.

Things that are difficult to interop are java annotations based stuff, having to implement interfaces or subclass classes, and functional interfaces.

But you can use Spring without annotations, which is my preferred way anyways, because I favor explicit over implicit.


If you're using interop for mundane, everyday things, why use Clojure then? I imagine you would end up writing non-idiomatic Clojure code to do the interop (e.g. working with mutable objects and not immutable datastructures).


The recommended design for Clojure programs is imperative shell, functional core. You use Clojure as your functional core, and it interops with mundane libraries for the imperative shell, such as database clients, http clients, logging, http server, graphics, sound, etc.

It works beautifully, and the REPL helps with all of it.


I've been in the Clojure world for over 10 years but I don't really recognise the problem you're calling out here. There will always be libraries in an ecosystem that lack maintainers, particularly if they did not see the hoped adoption or an alternative de facto solution has emerged.

Many Clojure libraries are conceptually simple and solve one problem well, so it's common for them to reach 'feature completeness' and not see much activity after that. clj-commons has also ensures the active future of many libraries.

A friend and I adopted a library we felt was stagnating and still had lots of useful features to add. I don't see this more in Clojure than anywhere else though.

Any more examples that need engineers? Onyx always seemed to be entering a crowded space.


What kind of mundane libraries don't exist? And do you mind sharing what you are working on?


not the OP but this struck home for me because I just recently worked with Clojure and I was surprised that there was no standard library to deal with filepath operations. Having to use Java's nio, immediately exposed some weirdnesses, like having to pass an empty array to Paths.get() because just calling it with a string with one parameter made it chose the wrong overloaded function.


Vararg support in interop and type creation (deftype/defprotocol) seems like a reasonable ask.



You can type hint to pick the one of the type you're looking for. It's not any weirder than in Java, no need to pass an empty array.


Yeah. I've just started on a couple things, and it's slow going because I have contract work and burgeoning Clojure blog. However, I'm working on a stripe API library that is up to date, and a syslog server library.

It's these API-wrapping and protocol-handling type libraries that either are way out of date, or just don't exist.


For better or for worse, this is the lisp curse at work.


I was doing a lot of data science with Clojure a few years back (gorilla repl). I looked up incanter, and the last commit was in 2020. I was surprised, as this space is so well suited for Clojure’s strengths. How does a robust library essentially end up abandoned?


It happens the way anything else gets abandoned… not enough contributors. Many of the libraries mentioned in the comments here were created by one person. When that person loses interest (or gets a new job!) the library goes stagnant.

It’s kind of a tragic irony. Clojure gives a solo dev enough leverage to create such a library. But because it only needs one dev to create it, the bus number stays at 1.


This would make sense, but the project has 98 lifetime contributors and 298 forks.


What mondane library are you missing? Everything I need is there, so I'm curious what people are waiting for?


That sounds like a blog post you could submit to get more visibility :)


I write a lot about Clojure, but I haven't written about this specifically.

I'll start today.


If you're still interested, I wrote the post and submitted it here https://news.ycombinator.com/item?id=32288291


Clojure's webstack has actually made webdevelopment interesting again. Most of the other "innovations" in webdev has added tons of complexity without benefits that match.


I have been taking a look at Clojure for the past couple of weeks. Although I'm not a fan of web development as is in JavaScript, Clojure looks more inviting to me.


I like programming in Clojure. My brain flowed pretty easily in it-- it felt very much like opening and collapsing computations-- in a natural way, like algebra.

I just don't like its enigmatic stack traces when an error occured-- it was difficult to understand the how/why/where of errors.

I did not like its relation to with Java. Nor the Java tooling. And ReAgent isn't exactly foolproof. ReAgent felt... buggy, and certainly not as easy to use as I felt ReactJS is. (ReAgent compiles to ReactJS)

Then again, it has been about 3 years, maybe I'll try it again sometime. Or at least another functional programming focused language.

I liked Clojure, but I was happy to return to NodeJS & ReactJS-- the latter being in higher demand, and felt easier to work with in terms of stack tracing, build system, and debugging. But yeah, as a language, Clojure itself is nice to work with.


This is a great article on the errors: https://lambdaisland.com/blog/2022-04-07-Clojure-Error-Messa...

Also the REPL makes it so easy to debugging: https://www.cognitect.com/blog/2017/6/5/repl-debugging-no-st...


Skip to minute 25 if you want to see the demo first.


I really wanted to use Clojure but even with this modern tooling it feels a bit "Java"-ish.


You might be more interested in this video:

https://www.youtube.com/watch?v=3HxVMGaiZbc

"ClojureScript in the Age of TypeScript — David Nolen"

Skip to 30:00 for the live coding demo: https://youtu.be/3HxVMGaiZbc?t=1800


Ok this is excellent stuff.


Meh. ClojureScript is just as leaky as Clojure. Clojure brings all the XML pain of Java dependencies and slow start times, ClojureScript gets callback hell. They're fantastic languages but I couldn't help but wonder if there were a better VM to base them on.


What XML pain are you referring to? It's not something I've had to deal with in ~3-4 years of professional Clojure work

The slow start times are meaningless for long lived servers, which Clojure is best suited for. For fast startup time there is now Babashka which is great for many tasks, and GraalVM as another option.


Where the hell do you see XML in java development anymore, let alone in Clojure?


Presumably in Maven POM files for Java


> ClojureScript is just as leaky as Clojure

By leaky, I assume you are refering to the interop with the host platform. Overall, this seems like a benefit, simply for having access to many more libraries than would otherwise exist in Clojure(script).

> Clojure brings all the XML pain of Java dependencies

Do you mean pom.xml?

> better VM

The JVM seems extremely powerful with regards to performance and memory management, with 20+ years of backwards compatibility (mostly), and improvements still being made with GC and JIT.


> Clojure brings all the XML pain of Java dependencies

You don't have to use pom.xml for Clojure projects. The default, included-with-the-clojure-cli support to define your dependencies in deps.edn makes dependency management extremely simple

  ;deps.edn
  {:deps {org.postgresql/postgresql {:mvn/version "42.4.0"}}}


and React brings all the XML pain into HTML templates.


And Reagent removes all that pain in ClojureScript https://reagent-project.github.io/




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: