Every time I look at Ada I find some cool little features I forgot about:

- Representation clauses that let you separately specify the layout of record types
- Requiring `aliased` on record fields for them to be individually addressable
- Variant records whose tag is immutable
- Variant records whose allocation size is variable and dependent on a parameter, sort of like C flexible array members but supporting multiple arrays (and of course differing between variants).
- Ragged arrays with non-uniform dimensions

It really is an alternate PL history branching off from Algol-68.

@zwarich Have you looked at the newer ownership/borrowing features in SPARK?
@pervognsen I haven’t seen good docs for them. It was my understanding that at the beginning they were just adding better checking (both static and dynamic) for the Ada accessibility rules than prior toolchains, but I heard that more recently they’ve done things that are more Rust-inspired. If you have a good link I’d love to take a look.
5.9. Pointer Support, Ownership, and Dynamic Memory Management — SPARK User's Guide 27.0w

@pervognsen Thanks for the link! I'm surprised this didn't come up in my Google search.

This system (combined with Ada's more classical Algol feel) reminds me of Reynolds' Syntactic Control of Interference. They even distinguish between the "borrow" mode (which is `&mut` in the Rust parlance) and the "observe" mode (which is `&`), with the latter sounding similar to Reynolds' "passive" mode.

One thing I was almost expecting by the end was support for unrestricted mutability within storage pools using pool-specific access types, but I can see how this might not really be a fit for their target audience.

@zwarich representation clauses also let you specify where and how big the discriminant tag is, which is pretty neat
@zwarich you can almost do automatic untrusted parsing of variable length packed binary data in the type system itself with a combination of Unchecked_Conversion, 'Valid_Scalars, representation clauses, and dynamic predicates

literally the only thing missing is that discriminants can't be used to specify bit offsets (which sucks because the compiler has to support this for field offsets anyway!):
https://stackoverflow.com/questions/22768834/ada-packing-record-with-variable-sized-array
Ada: packing record with variable sized array

I am looking to create a packed record that can hold an array the varies in length from 5 - 50 elements. Is it possible to do this in such a way that the record can be packed with no wasted space?...

Stack Overflow
@duk I was having a very related discussion today on the Rust Discord about "parse, don't validate". This ceases to be such a hard-and-fast rule once your type system has the ability to validate predicates and then rely on the predicates down the line to eliminate error conditions (which obviously works out better with static enforcement). I wouldn't have imagined you could (almost) do something like this with Ada dynamic predicates, though.

@duk I do like that discriminants are explicitly named so they can be referred to elsewhere. I think the notation for specifying discriminants and distinguishing between constrained and unconstrained discriminants is a bit confusing, especially by modern notation. The discriminant syntax looks like a type parameter, which it arguably is in the constrained case, but in the unconstrained case it's not really a parameter. Also, the way that the constrained case is specified by the absence of a default value for the discriminant is a bit surprising, as is the interaction with heap allocation.

I get why all of these problems exist and don't have a comprehensively better solution, so I shouldn't rag on them too much.

@zwarich oh yeah the syntax is confusing for sure and Ada's heap allocation stuff was very, very obviously tacked on retroactively

there's a lot of stuff in Ada but language-wise it doesn't really compose as well as one would hope unfortunately, and there are weird gnarly edge cases around subtyping arrays and such that can bite you
@zwarich Algol's UNION is still the best design in the whole enum/union design space.