This is something that has been frustrating me in Clojure ever since I started using it (pre-1.0) and every time I go back to it I see nothing has changed:
Terrible start-up time. Clojure could’ve been a choice for writing Android apps but just isn’t, because the Clojure developers haven’t cared enough in the last 10+ years to optimize it. In the beginning people said “JVM startup is slow” but these days java starts fast enough.
Terrible errors/exceptions. The stack traces are awful, extremely long and understanding them is more of a “interpreting art” thing than anything else because often the reason something falls apart is a nil value 30 stack frames below.
Yet none of these issues seem to be even remotely an issue woth looking at. Instead we get an idiosyncratic version of type checking called Clojure Spec and niche data structure optimizations called transducers.
The startup time issue while quite present is a bit more muddy. Apparently startup time is linearly related to the amount of code you’re loading, including dependencies, since effectively you compile the universe on every JVM startup.
For development there’s not much you can do but there’s some: avoid Lein and use the Clojure cli tools. Lein launches two JVMs and adds some layers that might be unnecessary. Precompile your deps as per https://clojure.org/guides/dev_startup_time
For production you can generate an AOT Uberjar that at least removes the compiler from the picture. That’s your ceiling, you cannot go faster than that unless you start selecting your dependencies with startup size in mind, or going the route of dynamically loading namespaces when needed (amortizing the cost).
Regarding the error messages, there was some work done but it covers only some cases. In my experience, the core team actually listens to complains but is batching work so the response is slow. If you have some specific stacktrace and some idea of what it should be, I would go to ask.clojure.org and open a question.
Nowadays, there is babashka that covers a lot of use cases where startup time is an issue. Meanwhile, I find that ClojureScript works pretty well for mobile development. Obviously there are cases where Clojure isn’t a good fit, but for many situations it does work very well.
Errors and exceptions have been getting a lot better in recent versions. Personally, I don’t actually know why people keep saying interpreting stack traces is hard. Vast majority of the time you just got to the end of the trace and look for the last reference to a namespace from your code. My experience is that errors tend to be very close to the line listed, and typically in the same function. There is also lots of REPL middleware, such as this one, that makes exceptions easier to read.
i don’t get what point you’re trying to make - how would someone writing a music dsl in clojure be expected to fix the language’s performance issues when the core developers have been unable to? this wasn’t his app being slow, it was the fixed startup cost clojure itself imposed.
I think that performance would be better if Clojure had a more open development story as it would distribute the work on more shoulders. That’s the cost of Clojure’s “no contributions” style of development.
This is something that has been frustrating me in Clojure ever since I started using it (pre-1.0) and every time I go back to it I see nothing has changed:
java
starts fast enough.nil
value 30 stack frames below.Yet none of these issues seem to be even remotely an issue woth looking at. Instead we get an idiosyncratic version of type checking called Clojure Spec and niche data structure optimizations called transducers.
The startup time issue while quite present is a bit more muddy. Apparently startup time is linearly related to the amount of code you’re loading, including dependencies, since effectively you compile the universe on every JVM startup.
For development there’s not much you can do but there’s some: avoid Lein and use the Clojure cli tools. Lein launches two JVMs and adds some layers that might be unnecessary. Precompile your deps as per https://clojure.org/guides/dev_startup_time
For production you can generate an AOT Uberjar that at least removes the compiler from the picture. That’s your ceiling, you cannot go faster than that unless you start selecting your dependencies with startup size in mind, or going the route of dynamically loading namespaces when needed (amortizing the cost).
Regarding the error messages, there was some work done but it covers only some cases. In my experience, the core team actually listens to complains but is batching work so the response is slow. If you have some specific stacktrace and some idea of what it should be, I would go to ask.clojure.org and open a question.
Nowadays, there is babashka that covers a lot of use cases where startup time is an issue. Meanwhile, I find that ClojureScript works pretty well for mobile development. Obviously there are cases where Clojure isn’t a good fit, but for many situations it does work very well.
Errors and exceptions have been getting a lot better in recent versions. Personally, I don’t actually know why people keep saying interpreting stack traces is hard. Vast majority of the time you just got to the end of the trace and look for the last reference to a namespace from your code. My experience is that errors tend to be very close to the line listed, and typically in the same function. There is also lots of REPL middleware, such as this one, that makes exceptions easier to read.
I guess the lesson here is: Rewriting things anew is fun, profiling existing code … not so much.
Anyway, author can do whatever he prefers with his time, so go ahead!
however willing the author was to profile their code, i don’t see what they could have done about clojure’s startup time
Nowadays, you could probably just use babashka for that use case.
True. I forgot that Clojure is pretty much only open-source in the Google sense (“you can read the code, and that’s it”).
i don’t get what point you’re trying to make - how would someone writing a music dsl in clojure be expected to fix the language’s performance issues when the core developers have been unable to? this wasn’t his app being slow, it was the fixed startup cost clojure itself imposed.
I think that performance would be better if Clojure had a more open development story as it would distribute the work on more shoulders. That’s the cost of Clojure’s “no contributions” style of development.
Three different langauges (clojure, go, kotlin) also seems like a bit much, personally…