John Lawrence Aspden writes about learning Clojure and Lisp, with posts on performance, the lambda calculus, and retro-style graphics.
Commenters call his post on Clojure beating machine code an 'ah ha' moment, and link his ZX Spectrum graphics article and Clojure speed posts.
Being a sometime embedded man myself, I was nodding sagely at your comment until this bit: "Java itself is far from the fastest thing possible, and the speed of Java is itself a strict upper bound on Clojure's speed"
Clojure doesn't compile to Java, it compiles to JVM bytecode, and I think (although I don't know) that that's supposed to be very fast.
In this post:
http://www.learningclojure.com/2010/09/clojure-faster-than-machine-code.html
I compiled a (lookup into a map (potentially constructed at run time)) into a series of nested if statements, which then ran very fast indeed.
I shouldn't think I've achieved anything like the holy grail here, it all goes wrong at the end anyway, and I think that clojure 1.3 might actually have broken the optimization techniques I used.
But I think there's a case for saying that an immutable lisp on the JVM might one day be the fastest language in the world, because you can do those sorts of tricks in lisp in a way that you can't feasibly do in assembler, and the JVM does optimization dependent on run-time behaviour, as well as on static analysis.
I don't have the data. I'm not asserting this.
But I am asserting that Java speed is not a strict upper bound on JVM language speed, (unless every JVM bytecode program is also a Java program, which I can't imagine is the case!).
A clojure program written in "canonical" style will usually be slower than the equivalent "canonical" java program (as long as canonical != enterprisey canonical), if only because canonical Clojure uses immutable datastructures and therefore spends quite a bit of time churning memory but Clojure lets you type-hint programs (to generate more type-tight bytecode, closer to what statically typed Java would provide), use Java mutable types and alongside compile-time metaprogramming that can be used to generate code which will likely be as efficient as tight Java code: http://www.learningclojure.com/2010/09/clojure-faster-than-machine-code.html
A bigger drawback to Clojure, in my experience, is that error messages are complete shit (most errors will yield stack traces to compiled bytecode, so you get java traces with a layer of obfuscation in that they're tracing the bytecode generated by clojure). The same issue exists when trying to improve performances, you get performance counters for java bytecode and have to match them to clojure code "by hand".
Is it just me? I don't like this design.
What's the point of wrapping an algorithm in strategy, when there is no reuse, nor any need to exchange algorithm?
And more. Why FizzBuzz(15), Buzz(5), Fizz(3); in enum and not in the constructor?
Why "mod" attribute, when the rest of the code doesn't use shortened words? It should be modulo.
Why FizzBuzzOperator when FizzBuzzStrategy's initialization is that easy? Also, again there's no requirement for reusability.
The code here is a classic example of why people make jokes about (usually in J2EE) overengineering solutions where even FizzBuzz will be designed for 1000MD-average-task-size scale.
I have switched to Clojure for good. Our FizzBuzzes are oneliners http://www.learningclojure.com/2014/05/fizz-buzz-interview-question.html
Off topic, but my "ah ha" moment with both Clojure and Lisp was this blog post by John Lawrence Aspden:
http://www.learningclojure.com/2010/09/clojure-faster-than-machine-code.html
He managed to get a statement to go as fast the JVM could possibly go, and he did this by getting the code to write code (the code added type castings to every variable, which apparently gave the JVM the info it needed to optimize like crazy). And there is no way to do that without hard-coding, and if you don't know what kind of data you are going to get, then obviously there is no way to hard-code anything. In other words, this kind of stunt can only be done in a language that allows this kind of code-that-writes-code.
This reminds me of another great article.
http://www.learningclojure.com/2010/09/graphics-like-its-1979-how-to-get.html
The author talks about how its harder to get graphics on the screen without installing prerequisite software than it used to be, and goes on to sing the praises of the ZX Spectrum and its concise and well written manual. He finishes the article with some fun coding experiments writing Clojure code in the spirit of the ZX.
I've seen some lispers going 'full stack' programming. Clojurians (like this guy http://www.learningclojure.com/2010/09/clojure-is-fast.html) also aim to cpu cycles when they program. It's an interesting workflow to prototype high and fast and the project it down baremetal.