Summary by Dan Luu on the question about whether for statically typed languages, objective advantages (like having measurably fewer bugs, or solving problems in measurably less time) can be shown.
If I think about this, authors of statically typed languages in general at their beginning might not even have claimed that they have such advantages. Originally, the objective advantage was that for computers like a PDP11 - which had initially only 4 K of memory and a 16-bit adress space - was that something like C or Pascal compilers could run on them at all, and even later C programs were much faster than Lisp programs of that time. At that time, it was also considered an attribute of the programming language whether code was compiled to machine instructions or interpreted.
Todays, with JIT compilation like in Java and the best implementation of Common Lisp like SBCL being at a stone’s throw of the performance of Java programs, this distinction is not so much relevant any more.
Further, opinions might have been biased by comparing C to memory-safe languages, in other words, when there were perceived actual productivity gains, the causes might have been confused.
The thing which seems more or less firm ground is that the less lines of code you need to write to cover a requirement, the fewer bugs it will have. So more concise/expressive languages do have an advantage.
There are people which have looked at all the program samples in the above linked benchmark game and have compared run-time performamce and size of the source code. This leads to interesting and sometimes really unintuitive insights - there are in fact large differences between code sizes for the same task between programming languages, and a couple of different languages like Scala, JavaScript, Racket(PLT Scheme) and Lua come out quite well for the ratio of size and performance.
But given all this, how can one assess productivity, or the time to get from definition of a task to a working program, at all?
And the same kind of questions arise for testing. Most people would agree nowadays that automated tests are worth their effort, that they improve quality / shorten the time to get something working / lead to fewer bugs. (A modern version of the Joel Test might have automated testing included, but, spoiler: >!Joel’s list does not contain it.!<)
Testing in small units also interacts positively with a “pure”, side-effect-free, or ‘functional’ programming style… with the caveat perhaps that this style might push complex I/O functions of a program to its periphery.
It feels more solid to have a complex program covered by tests, yes, but how can this be confirmed in an objective way? And if it can, for which kind of software is this valid? Are the same methodologies adequate for web programming as for industrial embedded devices or a text editor?
Then why is the SBCL implementation of Common Lisp about as fast as modern Java? I linked the benchmarks.
Java is still interpreted. It compiles to bytecode for a virtual machine, which then executes a for a simulated CPU. The bytecode interpreter has gotten very good, and optimizes the bytecode as it runs; nearly every Java benchmark excluded warm-up because it takes time for the huge VM to load up and for the optimization code to analyze and settle.
Java is not the gold standard for statically typed compiled languages. It’s gotten good, but it barely competes with far younger, far less mature statically typed compiled languages.
You’re comparing a language that has existed since before C and has had decades of tuning and optimization, to a language created when Lisp was already venerable and which only started to get the same level of performance tuning decades after that. Neither of which can come close to Rust or D, which are practically infants. Zig is an infant; it’s still trying to be a complete language with a complete standard library, and it’s still faster than SBCL. Give it a decade and some focus on performance tuning, and it’ll leap ahead. SBCL is probably about a fast as it will ever get.
Modern JVM implementations use just-in-time (JIT) compilation of bytecode to native machine code. That can be faster than C code which is optimized without profiling (because the optimizer gets relevant additional information), and for example in the Debian computer languages benchmark game, for numerically-intensive tasks it runs typically at about half the speed of the best and most heavily optimized C programs.
And now, I have a bummer: These most heavily optimized C programs are not written in idiomatic C. They are written with inline assembly, heavy use of compiler intrinsics and CPU -dependent code, manual loop unrolling and such.
TIL there’s such a thing as idiomatic C.
Jokes aside, microbenchmarks are not very useful, and even JS can compete in the right microbenchmark. In practice, C has the ability to give more performance in an application than Java or most other languages, but it requires way more work to do that, and it unrealistic for most devs to try to write the same applications in C that they would use Java to write.
But both are fast enough for most applications.
A more interesting comparison to me is Rust and C, where the compiler can make more guarantees at compile time and optimize around them than a C compiler can.