Hacker News new | ask | show | jobs
by lemming 25 days ago
No, it doesn't. In JVM Clojure's case, the vars are usually compiled to the moral equivalent of a global variable holding a pointer to a function. This allows you to update the function if the developer redefines it in the REPL, but it comes at a performance cost (the JVM can't inline it or otherwise optimise it). Clojure also allows you to compile with "direct linking", e.g. for production deployments, where you know you're unlikely to be wanting to dynamically update the code. In those cases defns are compiled down to static methods which call each other - much faster since the JVM can perform its magic with them, but you can't update them at the REPL.

I'm unsure exactly how jank works WRT this tradeoff, but the article makes it sound like it's closer to the direct linking version, but with the inlining etc being done by jank rather than the JVM. I don't know if this is only for AOT or also in JIT cases.

1 comments

> the vars are usually compiled to the moral equivalent of a global variable holding a pointer to a function. This allows you to update the function if the developer redefines it in the REPL, but it comes at a performance cost (the JVM can't inline it or otherwise optimise it)

might be out of my depth but I find it surprising; I thought compilation through invokedynamic should be able to handle redefinition while still allowing inlining and other jit optimizations

Clojure (AFAIK) does not use invokedynamic, except perhaps in the latest version for some of the new interop stuff. It still officially supports JVM 1.8 bytecode. It’s a language which greatly values stability and backwards compatibility, so it’s been very slow to adopt newer JVM features.
Though there may be other reasons not to use it, invokedynamic is not a new feature of the JVM. If they're targeting 1.8 binary compatibility, they certainly have it at their disposal, since it landed in 1.7.
I can't speak for the core team, but from memory invokedynamic took a long time to become performant. So if you still want to support older JVM versions, the performance will be pretty terrible on those older systems if invokedynamic is used for something as integral as var lookups.