Found this, which I thought people might find interesting. The essential idea is that modern languages are all playing catch-up with Ada. A lot of the essays seem to be very contrarian. Here’s the direct link, if you don’t want to go through x.com
Thanks Mark !
Why does the reply have to be 20 characters long when all I want to do is thank someone? ![]()
That’s what the Like button is for. The limit is there to encourage more thoughtful conversation and combat spam.
I’m a huge ML fan, but I have a hard time using web forums. I find them a step backward in terms of usability. Thanks for clarifying that ![]()
A well-written, non-slop article and about Ada, no less.
Thanks.
Could someone clarify for me the conceptual relationships between Ada’s exception requirements and Java’s checked exceptions and between Ada’s requirements on access types and C#’s nullable types?
I.e., is what the author of that article says true that Ada exceptions are somehow similar to Java’s checked exceptions and access types are somehow similar to C#’s nullable types?
Very insightful!
(A stark contrast to the usual bland, cliché-ridden publications that only serve to highlight their authors’ ignorance like this one : 100 Languages Speedrun: Episode 09: Ada - DEV Community)
The article is completely nonsensical here, Ada access types allow null by default and there’s absolutely no enforcement of unwrapping as you would see in C#.
Again, just completely nonsensical. Ada absolutely does not require a subprogram to specify what exceptions can be raised.
Also:
The requirement that exceptions be declared and that their propagation be through a structured call stack — rather than through setjmp/longjmp or signal handlers — was part of the original Ada 83 design.
Ada says nothing about how exceptions should be implemented internally and GNAT used SJLJ exceptions by default in the past. I believe they’re still supported although they’re no longer the default. The default is now ZCX (Zero Cost Exceptions).
I think you’re not interpreting correctly their words. They seem knowledgeable in all the languages that I know.
The article is completely nonsensical here, Ada access types allow null by default and there’s absolutely no enforcement of unwrapping as you would see in C#.
But the need to be null is declaring the object as an access, but if it cannot be null, Ada allows managing objects in ways other languages didn’t and don’t have, like in-out parameters, unconstrained types, etc.
Again, just completely nonsensical. Ada absolutely does not require a subprogram to specify what exceptions can be raised.
If you read carefully, including the footnotes, you will note that they understand perfectly the model and the difference between the checked exceptions from Java (“checked exceptions widely considered a mistake”) and the less checked version of Ada. But it’s true that you have to declare exceptions (and you usually do it in the package where the subprograms raise them, and you document it; that means the same as the “Ada’s idea that callers should know what exceptions a subprogram may raise”).
Ada says nothing about how exceptions should be implemented internally and GNAT used SJLJ exceptions by default in the past. I believe they’re still supported although they’re no longer the default. The default is now ZCX (Zero Cost Exceptions).
Those paragraphs are describing what Ada requires, not how must be implemented. They put that in contrast with the other low-level mechanisms that many programmers had to use in languages lacking exceptions.
They’re very clearly referring to access types, as seen in the below excerpt, which is simply objectively wrong:
Ada access types are initialised to
nullby default and the compiler requires explicit null exclusion or null checking before use.
They’re very clearly not saying that:
Java’s checked exceptions — the requirement that certain exception types be either caught or declared in the method signature — are a direct borrowing of Ada’s idea that callers should know what exceptions a subprogram may raise. Java added the mechanism to C-style method declarations; Ada had it in its subprogram specifications as a standard feature from the beginning.
They are saying it is part of the subprogram specification itself. Show me how a subprogram specification requires showing what exceptions a subprogram may raise.
This part puzzled me too.
If I were to steelman their case, I’d say they probably confused features of Ada, SPARK, maybe Eiffel or regurgitated some myth read online without double-checking.
Still, I evaluate the article to be entirely accurate in spirit.
(One wishes Ada had with Raises => My_Error or Constraint_Error or ... syntax for all explicit raise calls in subprogram body.)
The problem there is how it propagates when you make a change, you could be 50 calls deep and suddenly you have a new exception that shouldn’t be handled anywhere and instead should just crash the program. Now you have 50 subprograms to modify. I’m yet to see a really good solution to this in any language.
I don’t use exceptions all that much (often using a light runtime) but isn’t it true that in a small program exceptions will be shown for the package in the spec and in a large program without use then the body will show what package and exception is raised. I totally agree that a verified spec showing them per procedure would be better than maintaining procedure comments. Whilst exceptions are ideal with that. Personally I think they were a mistake in terms of Ada adoption as not everyone outside the D.O.D. wants to afford making a runtime handle them or have stack space for them. Adoption probably should have been (in this case IMO) but wouldn’t have been a priority for the D.O.D. and if it had been then a less modern language probably would have been the result due to Ada being ahead of what is thought to be desired by the masses in a language.
That should hang off the spec so you can see in interface docs.
It may have been said already, but in SPARK, since a few years already, one can list the allowed Exceptions that are allowed to be raised by a function/procedure and that the caller must either handle or pass onto the caller.
See Exceptional_Cases documentation in 5.2. Subprogram Contracts — SPARK User's Guide 27.0w
Best regards,
Fer
I’ve emailed the author (you can find a contact email on the main page) so we shall see what happens!
Essay looks like it’s been updated, with a whole bunch of changes listed at the end of the essay
It’s on top of HN now, let it grow ![]()
Glad to most of see the corrections (I wondered about some of them).
Very sad to see this change, as I liked them very much:
Epigraphs. Three epigraph quotations attributed to Jean Ichbiah, Bjarne Stroustrup, and Tucker Taft appeared in the original version. None could be traced to a reliable primary or secondary source. They have been removed.
I can’t see it anymore, but the Strousroup quote reminded me of one I’ve seen attributed to P.J. Plauger.
I read about discriminated union
the mechanism that functional programmers have been advocating for decades as the correct way to model data that can be one of several things.
There is an huge difference between functional languages like OCaml/Haskell and Ada about ADT or discriminant unions.
In OCaml/Haskell (and also Rust), with the pattern matching, you can’t compile a program that access fields without testing the kind (and having an adequate kind). With Ada, the compiler doesn’t verify anything at compile time, then you can have a runtime error “discriminant check failed”.