Be sure to follow the link to the full changelog (https://github.com/clojure/clojure/blob/master/changes.md). In particular, a huge feature that wasn't discussed in detail in this blog post is the new socket server and REPL. In short, you can now get a REPL into any Clojure app by passing a flag on startup. Previously you would have had to manually start a REPL server during app startup.
Or just drop them completely in favour of Clojuredocs or Grimoire. New users get very confused as to which resource is the official one (since the official docs rank so low on G). Ie:
As someone who started using Clojure recently, the documentation has been the hardest part. Once I've understood something in the core lib, I'm blown away how well built it is, but it's been a confusing & misleading process getting in the meantime.
The design never bothered me, the issue I have is that docs are all over the place. I would like to see documentation consolidated, with improved completeness, and better search. To get there, it needs to be easier for developers to contribute to clojure.org, instead of spinning off their own version of docs, which seems to be the case at the moment.
Just for a glimpse of the documentation landscape, and what it's like getting started, here are the resources I've touched on:
* Main reference pages (recently redesigned) are nice for getting a high level gist of something, but I found it doesn't go in depth enough to really understand atom/transient/transducers/etc. [1] I walk away with a sense of: "sure, this all sounds good in theory".
* Main API docs are helpful for reference once you understand what's going on, also useful for finding new things to research elsewhere. [2]
* I've discovered there are wikis on the libs that have really good examples, but they're not complete, and I will still have to Google for more examples by people writing blog posts. [3]
* Clojuredocs has decent search, and sometimes people comment on a function with a good example. But most of the time comment unfinished code that's really misleading. [4]
* Google is really the best resource for finding examples, explanations, and idiomatic usage. There are a lot of idiomatic things that are hard to uncover, like to zipping is done by `(map vector [1 2 3] '(a b c))`.
* The #clojure IRC channel has pretty low response rate of actually getting help with something. As compared to #node.js/#python/#postgresql. The community is smaller, so it makes sense, but it's discouraging.
* There are quite a few other websites, but I haven't found them useful, so I never check them. [5] [6]
Part of the new clojure.org update is that the site content is now in github and accepts contributions. The guides area is already being built out by community contributions and that will continue. See: https://github.com/clojure/clojure-site and http://clojure.org/community/contributing_site . Over time this should improve the situation with respect to having both good reference and good tutorial content in one place on the site.
#clojure has always been up and down in terms of volume. These days, there are upwards of 5000 people on the Clojurians slack channel and pretty constant and helpful communication for chat. Join at http://clojurians.net.
I used Clojure for an small application last year and once I got up and running (after watching many Rich's excellent videos and reading up) I got a glimpse of how powerful bottom up functional programming could be, a refreshing change from OOP. I wish Jetbrains would create a full featured IDE for it.
You mean Direct Linkage? To be clear the difference is not whether functions are compiled ahead of time but whether function calls go through the standard indirections or are turned into static method calls more amenable to JIT optimisation. I haven't tried it but would expect it makes more of a difference to peak performance than startup time. The VM will still need to do those initial method lookups, and the normal var and Fn parts will have become very hot very quickly.
From personal experience class io, verification, method linkage, and reflection play a big role in startup of jvm languages (along with call site target setting if you're using invokeDynamic bytecodes), but removing indirection helps for long running processes.
Direct linking does (indirectly) affect startup time. Specifically, using direct linking means that many vars in the function class initializer are no longer needed. There is some new logic that avoids adding unused var initialization in the compiled class. The result is a reduction in class size and static initializer size, which reduces classloading time (a significant part of startup costs).
> From personal experience class io, verification, method linkage, and reflection play a big role in startup of jvm languages (along with call site target setting if you're using invokeDynamic bytecodes), but removing indirection helps for long running processes.
Yes, but Clojure itself is the one to blame for slow startup as it as been proven multiple times by community members.
“[It] spends 95% of the startup-time loading the clojure.core namespace (the clojure.lang.RT class in particular) and filling out all the metadata/docstrings etc for the methods. This process stresses the GC quite a bit, some 130k objects are allocated and 90k free-d during multiple invokes of the GC (3-6 times), the building up of meta data is one big source of this massive object churn.”
Keep in mind the timings in the first blog are 4 years old and the second blog are 2 years old. Both Java and Clojure have made improvements and released new versions.A simple hello world uberjar with the default settings is about 0.775 s for me.
Also, Clojure can be AOT compiled with direct-linking and elided metadata which alleviate some of the broader concerns (they're unlikely to affect a hello world type app though). See: http://clojure.org/reference/compilation
Var class loading is still a concern, so there is of course still room for improvement. Experiments in this area are ongoing. Delayed var loading has the significant downside of making every var call thereafter slower (as the code needs a guard to check whether the class has been loaded or not). invokedynamic shows some promise is getting the best of both worlds there.
Probably not enough to matter. Even if it halved the startup time it would still be too slow for the tasks it is too slow for. Note: Clojure itself performs fine, I am just talking about the startup time.
That being said, I use Clojure for scripting tasks frequently and it isn't so bad. It just isn't as awesome as it could be.
POTENTIAL SOLUTION: I think for script startup time someone is going to have to bite the bullet and write some kind of nREPL client in a language with no startup time (Go, C, etc). Then you could just send code to be evaluated to already running environments. You could use boot.pods to isolate the Clojure runtimes. Seems straightforward-ish.
That change in linkage seems like it would have a serious effect on anything that wanted to hook functions (like this library for doing it: https://github.com/technomancy/robert-hooke/). Isn't the point of rebinding that you don't necessarily know what you're going to want to rebind ahead of time?
Most of the rebinding that people do is at development time from the REPL. When you AOT compile an app for production and deploy it somewhere, you are (usually) not doing that anymore (other than very specific cases that you would typically know ahead of time).
Direct linking is a compiler option so it affects any source you are compiling with the flag on.
If the dependency jar has source files (.clj) and you transitively AOT compile your app with direct linking, then yes.
If the jar has class files (.class) then you won't affect that dependency jars calls within itself or out to other libs. But you can compile your own app to directly link into a compiled dependency if it was compiled with Clojure 1.8 (and has the direct methods to call).
Clojure core itself is AOT compiled (that has always been true) with direct linking on. So calls within clojure core itself are direct linked - how you compile your own code to call into them is up to the choices you make when you compile. Code compiled with direct linking actually retains both the direct and dynamic call paths so this is always a compile-time decision.
For B, https://pragprog.com/book/vmclojeco/clojure-applied is very nice if you are coming from a traditional Java or OO background, and if you are familiar with design patterns but are wondering how to structure your code in a language style that is unfamiliar.
Anybody know if this update addresses any of the issues with Java 8 interop? It'd be really great if you could just pass a conventional Clojure function to Java methods that expect to receive lambdas.
Clojure user here. What I find really annoying what came from the Java world:
- JAR dependencies and dependency hell. My project.clj is usually full of exclusions, forcing versions and stuff like this.
- Logging. Oh my, how I hate everything about logging, from terribly documented .properties files, even worse documented logback.xml files, to appenders which drop messages at peak times and this log4j/slf4j mess.
On the other hand, startup times are ok. The biggest problem wrt to startup times is the nrepl-refactor JAR which I load in some profiles for refactoring features in CIDER. Probably not worth it.
This post is really old.
Even Scala has improved in startup time.
I don't think that numbers from 2012 are reasonable.
Especially when Java 1.8 will hit these languages. It reduces build times and startup times since these lanaguages could share their bytecode when it comes to lambda's and such things.
With -Xexperimental on Scala 2.11 and changing some things to lambda it will reduce the code size by 10-15% which is a lot in such a big codebase. And I think closure will have such stuff, too. This also means faster startup times.
Also Java 9 and Java 10 will also help these languages to improve.
So is Clojure 1.8 performance any better than those numbers?
For a long time I played with the idea of using it as common code between Android and Windows Phone, but the performance on Android and outdated CLR support demotivated me to pursue it, so it was back to C++11 (now C++14) for common code.
Still a lot of old code, and sorry for my misinformation.
Java 6 to Java 8 will reduce code size by a order of magnitude. Even Scala will reduce code size and Scala 2.12 is just amazing how good it fits to Java 8.
I hope Clojure will do the same.
We written a small ERP project and looking forward to have a calculation layer in clojure.
It's changed a lot for the better over the last few releases to the point where it doesn't matter anymore.
If it's still a concern, you can do what I did a while back and just write the app on top of Node.js. Then the startup time is more or less gone altogether.