Wednesday, December 16, 2009

ParaSail module details

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:
  • Element is Assignable<>
  • String<>
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
  • 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> 
    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>
     procedure Sort(Arr : ref var Sortable);
     procedure Reverse_Sort(Arr : ref var Sortable);
end interface Sorting;

No comments:

Post a Comment