Pages

Tuesday, September 11, 2012

AdaTutor - Generics and Tasking

Generics

It would be easy to write a package that creates a single stack of 10 Integers,
and lets us Push and Pop on it. However, the code would be about the same
regardless of the size of the stack, and regardless of the type of objects on
the stack. For example, a second package that creates a stack of 50 Dates
would look about the same. We can write one generic package, and instantiate
it for any size and almost any type we need. The specification is:

Actually, there are a number of ways to specify a generic type. How we specify
the generic type determines what actual types we may use in the instantiation,
and what we may do with objects of that type in the body of our generic package
or subprogram. Let's look at the alternatives.

If the generic part says type Dummy is private; then, in our subprogram or
package body, what we may do with objects of type Dummy is similar to what we
may do with objects of a private type outside an ordinary package: create them,
assign them, test them for equality or inequality, and call other subprograms
already available to us. Although this list is short, we can instantiate with
almost any type at all: Dates, Floats, Strings (see the next paragraph),
Rainbow_Colors, and any type for which we can assign objects and test them for
equality. That means any type except a limited type. We can't instantiate
Stack_Package for type Ada.Text_IO.File_Type (a limited private type), or for
task types (a limited type discussed later), because in our package body we're
allowed to assign and test for equality objects of type Dummy.

We can't create objects of an unconstrained type like String. So, in Ada 83,
if our package or subprogram creates objects of type Dummy, we can't
instantiate it for type String; we must use a constrained subtype of String.
Thus we could write subtype Name is String(1 .. 30); and then instantiate our
package with package Stack_Of_50_Names is new Stack_Package(50, Name);. In
Ada 95 we can instantiate with an unconstrained type if and only if the formal
type name in the generic part of the specification (Dummy in our example) is
followed by (<>). In that case, the subprogram or package body must initialize
any objects of that type that it creates, in order to constrain them.

We can instantiate our package or subprogram even for limited types like
Ada.Text_IO.File_Type if the generic part says type Dummy is limited private;.
However, the only things our package or subprogram body could do with objects
of that type is create them and call other subprograms already available to us.
Ordinarily, that's not very useful.

If the generic part says type Dummy is (<>); then we can instantiate the
package or subprogram for any discrete type. That means any enumeration or
integer type: Character, Boolean, Counter, No_Of_Apples, etc. In the body,
attributes like 'First are available.

If the generic part says type Dummy is range <>; then we can instantiate for
any integer type. In the body, we can do things that can be done with all
integer types, such as add, etc.

If the generic part says type Dummy is digits <>; then we can instantiate for
any floating point type, such as Float or the Real we created.

If the generic part says type Dummy is delta <>; then we can instantiate for
any fixed point type, to be discussed in the section on More Records and Types.

In Ada 95, some additional forms are allowed; beginners shouldn't expect to
grasp them until later. If the generic part says type Dummy is tagged private;
then we can instantiate with any tagged type, to be covered in the section on
More Records and Types.

If the generic part says type Dummy is new X; or type Dummy is new X
with private; then we can instantiate with type X or with any type derived from X.
If with private is included, then we must instantiate with a tagged type.

In both cases above, as with type Dummy is private; and type Dummy
is limited private; we can follow Dummy with (<>) to
allow instantiating with unconstrained types. The body must initialize
any objects of an unconstrained type that it creates. We can also replace
is in the generic part with is private to allow instantiating with
abstract types, to be covered later.

If the generic part says type Dummy is mod <>; then we can instantiate with any
modular type, to be covered in the section on More Records and Types.

Finally, if the generic part says with package Dummy is new P
(<>); where P is the name of a generic package, then we can
instantiate with any package that we obtained by instantiating P.

1 - No, when the generic part says type Dummy is range <>;, the procedure may be
instantiated for any integer type. No_Of_Apples is a type derived from
Integer, so it's an integer type.

2 - No, when the
generic part says type Dummy is range <>;, the procedure may be
instantiated for any integer type. The definition of the user-defined
type Counter has the word range, so Counter is an integer type.

3 - You're
right! When the generic part says type Dummy is range
<>;, the procedure may be instantiated for any integer type.
Answer is a discrete type, but not an integer type.