Here is my list of shortcomings when it comes to Ada
1) Ada is not a magic bullet, the seminal case study of why computer bugs are bad taught in CS courses around the world is the failed 1996 Ariane 5 rocket launch where the rocket veered off course and then exploded due to a software error that caused it not to understand the data it was getting from a sensor. More recently there are plenty of demonstrations of poor security in commercial plane avionics systems.
2) Ada is not easy to write, it's around the level of C I grant you, but it is not easy by any means, more importantly it is complex not simple. Each of those "features" like assert adds a layer of complexity to the system making it far harder for the programmer to write for. I think we all agree if we could program with simple functions that each do one thing and one thing well then combine those functions makes for a much simpler language and easier to think about.
3) Overhead, each of these features like assert adds a lot of overhead into the system, this is just not viable in a lot of systems, whats more those features are optional, so it is the first thing to drop where possible.
4) Toolchain and library support, most of us can't afford expensive toolchains and libraries, we don't work for very rich government contractors. Also we need libraries and toolchains are well maintained. Java has a massive standard library and a lot of free 3rd party libraries available, C/C++, python, perl, ruby, rust, javascript, c#, clojure... are all similar in that they have well maintained tool chains and good library support freely available either directly by language authors or from a third party.
>I think we all agree if we could program with simple functions that each do one thing and one thing well then combine those functions makes for a much simpler language and easier to think about.
Well, I don't agree. You could end up with tons of small functions, and complex interactions between them (whether they are pure or not) than make for spaghetti logic.
I also don't see how Ada's pre/post conditions make it more difficult to program. More tedious, maybe, but about as much as writing tests. Not more difficult as in conceptually more challenging.
As for the Ariane error, Ada could have prevented it, if it was left to -- but the programmers didn't let it. It's not a silver bullet of course, but nothing is, not even formally proven programs.
Finally, the overhead is true, but some domains don't need much speed anyway, and for others, you could always have the checks for all demo/dev runs and drop them for the final production output.
> You could end up with tons of small functions, and complex interactions between them (whether they are pure or not) than make for spaghetti logic.
I think 'one thing well' is pretty much the opposite of this idea. It implies encapsulation and composition, not smushing together. If some functions are pure, there is no such thing as 'complex interactions between them', only simple ones.
On the other hand, it would definitely be weird if Ada were used as a functional programming language.
Not all things can be expressed by simple interactions between simple functions. A program doing complex tasks composed of pure functions will be either wide (fewer functions but having many parameters) or tall (long string of functions with few parameters).
I do not believe that a simple paradigm shift will help you create arbitrarily complex programs simply. At some point the complexity must be handled.
1) and 3) are related as far as I remember - Ada WOULD have found the problem which was responsible for the Ariane 5 launch failure, but the section involved was speed critical, so the asserts were dropped to make the code run fast enough.
Sad reality: The best security features in the world are useless if they are too slow for your use case.
Ironically, it's also Ada's asserts which contributed to the failure (though far from the root cause): The result of the erroneous calculation wasn't actually used, so just ignoring it like C would have would have been fine. It was the fact that the wrong cast caused the software to abort which resulted in the crash.
This is why static checking is better than runtime checking.
Rust has some, but not enough. What is needed is something like Isabelle sledgehammer, quickcheck and metis logic and higher function correctness checkers. (Yes, Haskell has a bit more primitive version of Quickcheck.)
A smaller less featured one, but very useful nonetheless. (Specifically, sledgehammer is superior as a checker and automated proof library check is also invaluable in simplification.)
Technically, Why3 (intermediate language and prover manager used in SPARK for verification) can interface with Isabelle too. I should try it out.
More edit: someone has done it, called HOL-SPARK. Excellent.
It was actually an engineering error. The software in question was designed for Ariane 4, and the condition that happened in Ariane 5 could not occur. But a shortcut was taken, and the suitability of the software was not reassessed. Then Ada's exception mechanism was pulled into play when it never should have been given the requirements of the Ariane 4.
A Denial of Service vulnerability is a security vulnerability no matter the cause. That COULD be an attacker, but it could also be that your code runs too slowly or the UI is too hard to learn.
I feel like I have to rule out some misconceptions and defend Ada a bit, even though I don't use it very often any longer.
Ada is not a magic bullet
1) Nothing is a magic bullet. (And certainly no actual user of Ada has ever claimed that it is a magic bullet.)
Ada is not easy to write, it's around the level of C I grant you.
2) Ada is way harder to write than C, unless you're very proficient with it, of course. It's a much bigger language, and the syntax is not easy. Ada is designed for easy readability and maintainability, not for easy writing. It also requires a lot of repetition if you write good style. (You can write Ada code like C and Pascal, but then you loose most of the language's main advantages.)
Overhead, each of these features like assert adds a lot of overhead into the system, this is just not viable in a lot of systems.
3.) Ada is blazingly fast even without any optimization, and after optimization basically around the performance of C (or C++, if you use tagged types with dynamic dispatch). That's not very surprising, since GNAT uses gcc's backend optimizations. As for overhead, every runtime-check in Ada can be switched off. You can even discard the whole runtime system and use your own minimal runtime system, if you feel ambitious.
There is reason to believe that future versions of Rust (or even the current compiler) are faster than idiomatic, well-styled Ada. The goal of Ada was never to produce the fastest executables, and the fact that GNAT creates so fast ones is merely due to the authors of GCC and Ada's strong focus on compile-time operations and checks that it shares with Rust.)
Toolchain and library support, most of us can't afford expensive toolchains and libraries
4) Absolutely true, library support is not comparable to C and not even remotely comparable to C++. However, see my other remark here, an Ada library that appears to be abandoned will compile and work 100% fine and you can understand it by reading the source code (no documentation needed). But yeah, there are way less libraries, of course.
As for Java or Python, these are bad comparisons. They are both much slower than Ada and way less maintainable.
In regards to level of ease of writing, I'm assuming some level of competency in the languages we are talking about, all languages have a learning curve.
In regards to speed as other comments have also pointed out some of the asserts were optimised out of some of the Ariane 5 code, while the ones left in worked towards the cause of the issue ;)
The reason Java is in there is due to the libraries available, you can use those libraries with other JVM hosted languages like clojure ;) now tell me it's not maintainable. Similar reasons why python is in that list, I believe no OOP language is truly maintainable at this point, it adds to much complexity.
1) Ada is not a magic bullet, the seminal case study of why computer bugs are bad taught in CS courses around the world is the failed 1996 Ariane 5 rocket launch where the rocket veered off course and then exploded due to a software error that caused it not to understand the data it was getting from a sensor. More recently there are plenty of demonstrations of poor security in commercial plane avionics systems.
2) Ada is not easy to write, it's around the level of C I grant you, but it is not easy by any means, more importantly it is complex not simple. Each of those "features" like assert adds a layer of complexity to the system making it far harder for the programmer to write for. I think we all agree if we could program with simple functions that each do one thing and one thing well then combine those functions makes for a much simpler language and easier to think about.
3) Overhead, each of these features like assert adds a lot of overhead into the system, this is just not viable in a lot of systems, whats more those features are optional, so it is the first thing to drop where possible.
4) Toolchain and library support, most of us can't afford expensive toolchains and libraries, we don't work for very rich government contractors. Also we need libraries and toolchains are well maintained. Java has a massive standard library and a lot of free 3rd party libraries available, C/C++, python, perl, ruby, rust, javascript, c#, clojure... are all similar in that they have well maintained tool chains and good library support freely available either directly by language authors or from a third party.