Wonderful to see someone really taking a moment and question what they want. As someone who is mostly in the software industry, and not research, my stomach started to churn when he described his language. Hijacking the parser during parsing?? It’s hard enough to understand a program when the parser is static.
One comment on JITs: I’ve found many people only focus on the possibility of highly optimized code from a JIT, but completely leave about any other cost, such as in memory, startup time, etc. For the most part, I have seen little evidence that JITed code is much better than AOT for realistic workloads. It’s somewhat hard to separate JIT from the big languages that have it, but Java has a huge minimal memory cost and warm up time cost. I suspect .Net is about the same. I think, for most programs, focusing on execution performance is the wrong thing, they should probably be focusing on memory efficiency.
Memory continues to drop in price but CPUs are not getting much faster.
Allocations, deallocations, garbage collection all take CPU time and the more memory you’re using the more expensive they are.
Application memory consumption makes those things slower; does JIT memory consumption (presumably code caches and the like that won’t be part of the application memory pool) actually slow performance? For long-running server applications I’m very happy to sacrifice some startup time and a large but constant amount of memory if it gets me improved execution performance, which seems like the tradeoff Java is making.
My point is that JIT comes with costs and there doesn’t seem to be much evidence that the complexity, startup time, memory consumption, costs of JIT actually produce performance better than AOT binaries, so maybe we should drop that path of exploration for production languages for a bit and focus on other known deficiencies, like memory.
The programming language shootout seems to have rewritten their website to be unusable, but my general impression was that Java performed better than or at least as well as any comparably safe AOT-compiled language (and perhaps offering a better generics support/compile-time craziness ratio).
Is it possible to get the same level of cross-platform consistency that the JVM gives you (e.g. memory model) from an AOT language? I wouldn’t be willing to give that up even for a performance improvement.
I agree that there’s not a compelling performance advantage for JIT, but I don’t see that that means it should be abandoned - I don’t think there’s a compelling argument for AOT either (outside the relatively small segment that has very tight memory constraints), so implementors should feel free to use whichever approach is easier for them (if a given implementor finds AOT simpler then great, but I don’t think it’s a general principle that AOT is necessarily simpler), and research on both should continue.
Last I looked, Java, Ocaml, and Go were all about equal on average. Note that implementations of Ocaml and Go both have received orders of magnitude less attention than Java. But I haven’t checked it too much. I also don’t know if the Java, Ocaml, and Go code do unsafe things to get their speed.
Is it possible to get the same level of cross-platform consistency that the JVM gives you (e.g. memory model) from an AOT language?
You would have to be compiled per target, but there is no reason you can’t get those guarantees. Java has to provide them somehow, right? And that isn’t what the JIT is doing, the JIT is just implementing the on-demand compilation.
It depends on usecase, but IME, we pretty much only compile software for one system. Pretty much any Java backend deployment does not need 90% of the platform independence that is baked into the runtime.
I agree that there’s not a compelling performance advantage for JIT, but I don’t see that that means it should be abandoned
I think JIT is a valid path of research, I’m never against research, I just have not found it beneficial in production systems. It is a huge complexity, at least in the main languages used (LuaJIT is not so bad, AFAIK, but it is used at a much smaller scale). Its complexity that I do not want in a production system because it’s effectively just dead code in the environment that gets in the way of knowing what is going on. That is the compelling argument for AOT, IMO: simplicity. Do less things, give me just want I need. But, YMMV.
You would have to be compiled per target, but there is no reason you can’t get those guarantees. Java has to provide them somehow, right?
Well sure, but it involves running a substantial amount of Java-runtime code around your program code, doesn’t it? Obviously it’s possible to “AOT compile” by bundling together the runtime and the bytecode as a single executable, but at that point there’s no simplicity advantage.
(I can imagine any kind of cross-platform low-level representation offering most of the same kind of guarantees. But AIUI e.g. LLVM IR isn’t platform-independent. And I suspect it’s hard to ensure consistent threading behaviour short of, at a minimum, calling into a runtime library at every context switch, though I’d be happy to be wrong there).
Its complexity that I do not want in a production system because it’s effectively just dead code in the environment that gets in the way of knowing what is going on.
In theory I’d agree with that. But my experience of running the JVM in production is that it’s the easiest place to know what’s going on: its debugging support is second to none, as is the kind of instrumentation/monitoring you can do.
I don’t know what I want, honestly. I don’t know how much depends on the JIT specifically, how much depends on the VM/runtime but could be done without JIT, and how much is completely incidental or just my own experience. I just know I’ve found the JVM much nicer to work with in production than native binaries.
It depends on what you mean by all of this. If Java can give you some semantics than an AOT program can give you the same semantics. Java’s JIT is just producing op codes at runtime that are hopefully optimized for the particular workload you’re doing. It’s hard to imagine an AOT version could be any more complicated or have a larger performance impact than a JIT, which is doing the same thing on the fly.
This has not really been my experience, but YMMV. The JVM certainly has some nice features, though, but it comes at a pretty big cost IMO, and all of those things could be gotten elsewhere and possibly at a better level. For example, dtrace gives a view of the entire system, not just the JVM, and if you add dtrace probes to your application (which is often not needed) you can do a lot of interesting correlations and understanding at the entire system level.
But there is a lot of momentum with the existing tooling.
She. Sorry to nitpick.