Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Ada, it seems to be the general practice to declare specific subtypes, but why?

Tags:

ada

In this question, I asked how to define an unlimited upper bound for a range (turns out that the answer was fairly obvious, but not to someone new to Ada). In the answer, it was suggested to create a Specific Subtype for this.

A specific subtype of of the sort referred to in the question would look like this:

Type Speed is Float range 0 .. Float'Last

Additionally, I've noticed that a good portion of the code in this Ada project has specific types - like Feet_Float and Meters_Float and the like. Why is this the preferred practice, as opposed to just putting a range constraint on a basic float member variable in the class/package?

like image 414
theMayer Avatar asked Nov 22 '17 23:11

theMayer


2 Answers

Ada doesn't prefer subtypes - Ada programmers do.

New types and subtypes (they are different, and both have their uses) help catch so many errors at so little cost or time penalty it's a mystery why good type systems fell so far out of fashion.

For example, recognise that the index for any array belongs to a subtype (possibly anonymous, but accessible as myArray'range as in for i in myArray'range loop ... end loop; or subtype myIndextype is myArray'range; theIndex : myIndextype; and you'll see that every buffer overflow vulnerability - or attack - ever written was simply a type error - or could have been, in Ada.

When you get a bug past the compiler, the first time your executable falls over with an Exception : Constraint_Error pointing spookily close to the mistake, you'll start to get a sense of the value of range-constrained types.

To expand on this a bit, I'll refer to a couple more Q&As.

First note that the compiler you're probably using, Gnat, may not be strictly Ada compliant unless you add a couple of optional flags on the command line (or project file) as described in the first example. Recent versions have turned some of them on by default.

Here's an example of a subtype being declared, used and going out of visible scope, (in a declare block, where the range of the subtype is unknown until runtime. Unlike many dynamic typed languages, this is both fast and safe, because the relevant storage is usually on the stack, if you're interested in the implementation details.

And an example of how not to use a declare block.

Here's an extreme example of not only declaring subtypes but telling the compiler how to pack them in storage. Common in embedded programming, either where space is tight (I have a complete digital watch in a processor with 1kbyte memory!) or for accessing specific bits in hardware registers. (Note that this example would be cleaner if updated to use Ada-2012 aspects.)

And this Q&A briefly covers the difference between new types and subtypes, for someone coming from Java. (I'm a little disappointed none of the Java experts managed an answer before it was closed, describing how they would handle the same issues)

like image 152
user_1818839 Avatar answered Jan 01 '23 23:01

user_1818839


The declaration of specific types has the following benefits:

  • Specific types prevent inappropriate mixing of abstractions. For instance, dividing the distance between the Moon and Earth in meters by the gross national product of Belgium expressed in Euros.
  • The name of the type more clearly documents the intended use of the type
  • Use of ranged types clearly documents the valid values for instances of the type.
like image 26
Jim Rogers Avatar answered Jan 01 '23 21:01

Jim Rogers