Hacker News new | past | comments | ask | show | jobs | submit login
Clojure 1.8 (cognitect.com)
272 points by 147 on Jan 19, 2016 | hide | past | favorite | 60 comments



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.


That's one of the three features mentioned in the blog post and links to the fuller docs at http://clojure.org/reference/repl_and_main#_launching_a_sock...


I'm really excited to see how this simplifies CIDER and the Clojure web app tool chain, if at all.


This was already discussed by Bozhidar Batsov at last year's ClojureX talk:

https://skillsmatter.com/skillscasts/7225-cider-the-journey-...

I think that particular point is somewhere towards the end of the talk.


Slightly off-topic: Packt Publishing offers Akhil Wali's book "Clojure for Machine Learning" for free today (https://www.packtpub.com/packt/offers/free-learning).


Thanks for that!


Solid. I would like to see better Clojure docs before 2.0 though. I can even volunteer for a redesign.


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:

http://clojure.github.io/clojure/clojure.core-api.html#cloju...

http://conj.io/store/v1/org.clojure/clojure/1.6.0/clj/clojur...

https://clojuredocs.org/clojure.core/assoc


This. As a new user, this still confuses me somewhat.


That's on the list as well, will probably copy some of the design elements of the new clojure.org site.


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]

[1] http://clojure.org/reference/agents [2] http://clojure.github.io/core.logic/ [3] https://github.com/clojure/core.logic/wiki/A-Core.logic-Prim... [4] http://clojuredocs.org/clojure.core/keep-indexed [5] http://clojure-doc.org/ [6] http://conj.io/


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.


It looks like they just did: https://cursive-ide.com/


It's not their IDE, but I agree that it is excellent.


Congratulation, Clojure get better and better with each release.


Has anybody tried the ahead of time compilation? Does it significantly reduce script startup time?


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.


Here is the reason for the slow startup time. This is also why AOT compilation does not solve it.

http://martinsprogrammingblog.blogspot.de/2012/02/why-is-clo...

“[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.”

See also:

http://blog.ndk.io/clojure-bootstrapping.html


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.


You can also target nodejs with ClojureScript, which leads to blazing fast scripts/startup time.

See as an example: https://github.com/georgewsinger/yaml-table

This script takes about 100 ms on my computer and about 2.25 seconds (!) to run via pure clojure on the JVM.


I think https://github.com/technomancy/grenchman is exactly what you're looking for.


Congratulations! When is the 2015 State of Clojure coming out?


Soon, just editing stuff before release.


Seems like they've been so busy making us things to talk about them. I'm okay with that! I do look forward to seeing the survey.


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).


There's a flag to disable the static linking if you need the dynamism.


Does this work with jars you get via deps in your Lein project.clj file, like clojure core?


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.


> Socket server and socket server REPL - adds the ability to allow remote Clojure REPL connections

Now that's something!


I've been meaning to get my feet wet in Clojure, can anyone recommend a good:

A. Web tutorial intro B. Book


Check out Clojure for the Brave and True - http://www.braveclojure.com/


A reasonable recommendation. The book I'd recommend as an intro is Programming Clojure. It can be found used for cheap.


And after those you can try the "Joy of Clojure".


I used Aphyr's series to get started (I'm still a novice) and found it very useful to get going from zero: https://aphyr.com/tags/Clojure-from-the-ground-up


A) https://iloveponies.github.io/120-hour-epic-sax-marathon/ind... (I used this exact tutorial myself for learning clojure).

B) Living Clojure


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.


It requires that you know some Clojure already...


Good gravy we're still on 1.6 ... really need to put some time aside for the upgrade.


Actually you may not need that much time, the 1.6 -> 1.8 upgrade is pretty smooth!


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.


No changes in that area.


I like the idea of clojure a lot, but I just despise having to touch the Java platform at all, everything is so over-engineered and bloated.


Care to add any specifics?

Looking at half of JS language features, I could say that's bloated too.


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.


Well, for a very first point JVM startup time STILL sucks, even with an SSD.


The JVM startup time is actually negligible. What you're seeing is the time it takes to load the clojure jar.


Does it matter? I don't experience this with nim or go or even python - but it does show up with every jvm language, including clojure.


Don't blame the JVM for what it is a Clojure implementation problem.

http://blog.ndk.io/jvm-slow-startup.html

http://martinsprogrammingblog.blogspot.de/2012/02/why-is-clo...

If you program directly in Java it can be as fast as Nim or Go.

Granted, if you want AOT to native code, your only option is a commercial JVM.


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.


I'm not sure, I don't know how much Clojure 1.8 improved.

Currently this will bring a big one: https://github.com/clojure/clojure/blob/master/changes.md#11...

Also Clojure isn't tied to Java 8, it's compatible back to Java 5, so this brings a lot of overhead.


Clojure has required a minimum of Java 6 since Clojure 1.6.


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.


You might like Dylan? It's a similar style but compiles to native code.




Join us for AI Startup School this June 16-17 in San Francisco!

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

Search: