ParaSail has two kinds of
modules,
interface modules and
class modules. Every
class module has a corresponding
interface module. Every non-
abstract interface module has at least one
class module implementing it. All modules are effectively
generic templates, in that they have
formal module parameters which typically represent the
types on which the module operates, or other module characteristics, represented by simple values. A
type is produced by
instantiating a module, which means specifying
actual module parameters for each of the
formal module parameters, or relying on the
defaults associated with the formal parameters.
As indicated above, the typical formal module parameter is that of a type. Such a formal module parameter is of the form:
- [type_identifier is] interface_name '<' actual_parameter_list '>'
for example:
or
If a
type_name is omitted, then within the module, the
interface_name is treated as a type name. If actual parameters are omitted, then any
instance of the named
interface is acceptable as the
actual type. If one or more actual parameters are specified, then the actual type ultimately provided must have matching actual parameters, for those that are specified. Any actual parameters not specified are unrestricted.
Another kind of formal module parameter is a simple value:
- value_identifier : type_name
or
- value_identifier : interface_name '<' actual_parameter_list '>'
[ '{' constraint '}' ]
Simple values can be used to control
selection among multiple
classes that implement the same
interface. A
class may specify a
constraint on one of its value parameters which is more
restrictive than the
constraint on the corresponding parameter for its
interface. This class will only be used as the implementation if the actual value
satisfies the given constraint. If the actual values given satisfy multiple
classes implementing the same
interface, then the
class with the highest
preference value is chosen. For example, an
interface for a numeric type might have value parameters that specify the
range or
precision of numeric values that are to be represented by the numeric type. Generally the
class that uses a faster or more compact representation would be preferred, so long as the specified
range or
precision is
satisfied:
interface Float
<First : Univ_Real; Last : Univ_Real;
Digits : Univ_Integer := 6>
is
operator "+"(Left, Right : Float) -> Float;
operator "-"(Left, Right : Float) -> Float;
operator "=?"(Left, Right : Float) -> Ordering;
...
end interface Float;
Note that here we are presuming that
Univ_Real and
Univ_Integer are predefined, infinite precision numeric types, and
Ordering is the predefined enumeration type returned by the
comparison operator "=?" (see the blog entry on "Using the "=?"
operator" for details).
The final kind of parameter is a
function or
procedure. This is intended to be a short-hand for constructing an
interface with a single
function or
procedure in it, and then using that as a formal parameter. It might be used to specify a special
comparison function to be used for sorting, when the desired sort should not use the normal
comparison operator of the type. A parameter that represents a
function or a
procedure follows one of the following general patterns:
- function function_identifier '(' formal_parameter_list ')' '->' formal_result
- procedure procedure_identifier '(' formal_parameter_list ')'
- operator operator_string '(' formal_parameter_list ')' [ '->' formal_result ]
Here is an example Sorting interface that has a formal module parameter that is a
comparison function:
interface Sorting
<Sortable is Array<>;
operator "=?"(Left, Right : Sortable::Element)
-> Ordering>
is
procedure Sort(Arr : ref var Sortable);
procedure Reverse_Sort(Arr : ref var Sortable);
end interface Sorting;
No comments:
Post a Comment