John B. Matthews wrote:
I see; this may be two sides of the same coin. The lack of genericity in
Pascal prompted a variety of (incompatible) schemes including UNIV type
parameters and type-risky pointer schemes.
The improvements made to type checking in Ada are one of my favorite
peices of programming elegance. The way they solved the Pascal
introduced type constraint problem on scalar types was particularly
brilliant. The key concept is that any scalar type, be it array,
integer subtype, enumerated type, etc. can be treated as if was a set.
which meant for example:
Type Things is Array(1..100) of Integer;
Type OtherThings is Array(50.5000) of Integer;
Could then be processed safely by the same piece of code:
foo: Integer;
bar: (array of either of the above types)
For foo in bar'first to bar'last loop
begin
...
end;
or even better:
For foo in bar'type loop
begin
...
end;
Once you bring generic types into this, then you have true seperation
from algorithm and underlying data. The same technique could be applied
to iterations over enumerations, integer subtypes, etc.
And best of all, you lose no flexibility whatsoever.
Unfortunately, when I got around to appreciating the brilliance of
object oriented programming in the mid nineties, the Ada crew bolted on
possibly the ugliest set of OO extensions to an otherwise beautiful
language I've ever seen, and they lost me.
It's ironic that many who declare such languages as constrained and
inefficient fail to realise that none of the constraints actually
exist, and worse, that it's possible for compilers that have such type
information available to produce faster code. Instead, we deal with
less 'typey' languages, and in order to create efficiency in critical
sections we fiddle with bitwise operations and other such things, that
have little to do with the algorithm we're implementing, and in the
process often inadvertantly bind ourselves to a specific machine
architecture, by exploiting machine characteristics in 'by hand'
optimisations.