It probably isn't the same issue that is causing the Leiningen slowdown, but as near as I can tell the really slow startup time is the main reason Clojure on Android isn't currently a viable option. Which is too bad, because I'd love to see the Clojure community's take on Android development. I can imagine a UI framework spiritually similar to Facebook's ReactJS appearing and making everything so much cleaner. And with a Lisp like Clojure there would no longer be any reason to use XML for layout and Java for logic -- it could all be unified into one cohesive language. Maybe I'm dreaming too big, but that would be an exciting future.
Clojure is too slow, because of the vars creation that it does on startup.
Work is ongoing to improve the situation for Clojure 1.7, but apparently the slowness won't go fully away.
There as a post a few weeks ago on the mailing list about using ClojureScript instead, with compilation to Java bytecodes via Nashorn, before feeding the class files to Dalvik/ART.
All of this is just too hacky for me.
I would rather have a strong typed Clojure instead that wouldn't suffer from these pain points.
I'd be careful about introducing more caching to the ClojureScript build process - I've been getting some really strange errors occasionally, the kind that leave garbled errors in the js that the source maps can't decypher, that disappear after a full clean & rebuild.
I just released a site based on Clojure + Clojurescript, with the front end written in Reagent, and it was a pretty good experience overall. The above was my main issue with the setup.
I've written more about the experience here (it seems there's not much interest in the site here, but at least the writeup should be interesting to those reading this post):
The issues you encountered likely arise from not recompiling dependent namespaces when you change a source file. It's something we'll probably address soon.
Ah, interesting. This was both with the advanced and no optimisations, if that matters?
My overall impression was that ClojureScript was already 90% the way there, so you've done a damn fine job of maintaining and pushing the project forward. Thank you very much for that!
I wish leiningen wouldn't take so long to run. The only real trouble with Clojure is how unbearably _slow_ the tools are. I can deal with the runtime taking its time to get going (mostly), but the tooling...
It's not my experience that Clojure tooling is fundamentally slow, Leiningen is just one option. For many projects I don't use anything more than Maven bash scripts, inf-clojure, and clojure-mode - all overhead free. And projects like CursiveClojure drive home how powerful and responsive tooling for Clojure(Script) can be.
Even so the point of the post is not to bash on Leiningen but to demonstrate how the overhead issues are not insurmountable - it just requires really knowing the tools (surprise) and which knobs to turn. In fact an implicit free idea for someone to explore is to automate all the optimizations for Leiningen that I covered.
Same here. No problem at all if a command I run once a week per project takes a few seconds. I can't imagine coding in clojure without leiningen. It stops me from having to deal with a tonne of complexity I really don't want to think about.
As for cljsbuild, I'm guessing this is more a clojurescript compiler issue since again, I run leiningen once and leave it to recompile on file change in the background. Yes would be nice to have some compiler speed improvements but really it isn't that bad. I wait a second or two, not tens of seconds. At least, this is the case for me but then my cljs projects tend too be a couple of thousand lines at most.
Hmmm. I bumped my clojurescript to 0.0-2511, and I get the following:
$ lein trampoline run -m clojure.main
Exception in thread "main" java.io.FileNotFoundException: Could not locate cljsbuild/compiler__init.class or cljsbuild/compiler.clj on classpath: , compiling:(.../target/66ddb53f4f237c7eb26e49c2637097e7cd8567d9-init.clj:1:4)
...
Everything else works fine.
Do we have a more complete example project that I can check mine against?
The suggestion seems to be "In the meantime: don't use trampoline, or chain the task explicitly, before the trampoline, e.g. lein do cljsbuild once, trampoline repl."
As cool of a language as clojure might be, bad tooling is bad UX. Bad UX makes for a bad product. I don't care how many amazing features a language has, without great tools, it sucks.
PHP is a terrible language in terms of design, but deploys are ridiculously easy, and refreshing a page is near instantaneous. There are plenty of other things to complain about with PHP, but part of its popularity is the relatively pleasant experience with the main tools.
Extrapolating from the post that Clojure tooling is bad seems like a strange conclusion. I'm actually surprised that such a narrow post would find this much interest on HN.
Clojure deploys are pretty ridiculously easy - and refreshing pages on a Clojure based web stack is also instantaneous.
Seriously, Leiningen is great tooling. On pretty much every axis except startup speed I prefer it to everything else I've needed to use for work in other languages (Python, Ruby, and Node.js).
Hear, hear. I long for the day that lein and cljs tooling can replace bower/npm/grunt/gulp entirely. And I came to Clojure(Script) from JS, not Java, still have no clue what maven or pom.XML even means, but lein obviates all of that.
The main criticism I'd make, and this is something the boot (http://boot-clj.com) guys have mentioned (http://c2.com/cgi/wiki?CodeGenerationIsaDesignSmell), is that we are getting pretty dependent on code generation with lein templates, and they are getting increasingly larger and more complex just to handle our base scenarios (dev/prod builds, REPL, live reload). Maybe this is unavoidable, or not really an issue... I don't know.
I started using Django, as a relative newbie to python, back in 0.96, and it was a real pain in the ass to deploy. It took me a couple of days, minimum, all the while knowing I could have things halfway done in PHP.
Luckily I was given a stellar recommendation, and I stuck with it.
Django deploys now? Incredibly easy on the hosts I use (DO / Heroku). I expect Clojure to be the same in a year or so.
FWIW, I'm just starting to learn clojure. And just barely starting--these problems aren't annoying me yet.
> I expect Clojure to be the same in a year or so.
I'd say it was there years ago. On Heroku you can deploy any Clojure project that specifies a ":main" namespace. Deploying Clojure to a VPN is no different to any other language that runs behind an nginx proxy.
I disagree that the post can be summarized as bad tooling - leiningen is really great stuff - great tooling with a great UX (lein xyz for almost everything I need to do). I wish every language had something like leiningen.
Leining is a very useful tool. Starting up Clojure indeed is noticeable. I wonder how much of the performance is due to Maven, and if gradle would do better. Gradle is a newer project with a custom DSL based on Groovy.
Not sure what you mean? Leiningen is its own build tool, it isn't using Maven. I believe it uses the aether library for dependency management, but as far as I know that's all they have in common.
Because it interoperates with Maven. It can fetch and install code from Maven repositories, can read and write a pom.xml file, and uses the same groupId/artifactId/version format for specifying dependencies. And it also depends on a few org.apache.maven packages. So without looking at the source it would be easy to mistake lein for a Clojure wrapper around mvn. But it's more like a Clojure implementation of a superset of Maven's functionality, I guess.
You and I are definitely both correct about it being a dependency: it caused me some installation headaches. I may have misunderstood the docs about how deep of a dependency it is; I haven't read the source.
Returning to the OP's point, given that it is a dependency, it's still possible there is some resulting startup overhead, but I couldn't say for sure without profiling it.
My biggest headache with it was just figuring out how to tell it to use a local jar. It really wanted to fetch it from clojars or maven central but sometimes you just need to use a jar that's sitting on your hard disk. IIRC there's no standard way to do this and I had to create a local maven repo for lein to pull it from.
Reading between the lines in the Gradle docs, it looks like Gradle will ditch Groovy soon enough. Gradle 2 had almost no Groovy left in its own codebase, only was what was directly related to handling the Gradle DSL. No open source project's Gradle build script I've ever seen ever drops out of the DSL to use any of Groovy programming language, including Groovy's own build script. I suspect Gradleware will replace the Groovy with its own lightweight custom DSL parser soon enough.