Monday, September 28, 2009

How a ParaSail class implements its interface

In ParaSail, a class implements an interface.  Unless an interface is marked as abstract, there is required to be a class with the same name as the interface, which provides the default implementation of the interface.  There may be multiple implementations of an interface.  Some may be specializations of the default.  Specializations specify certain restrictions on the generic parameters, along with a preference level, which allows the compiler to choose the appropriate implementation automatically if not specified explicitly.

Here is a class implementing the interface Array shown in an earlier post:

 class Array < Element_Type is Assignable<>;
                    Index_Type is Discrete<>>
   const First : Index_Type;
   const Last : Index_Type;
   function Length(Arr : Array) return Integer is
     return Last-First+1;
   end Length;
   var Data : Length(Array)*Element_Type;    
   function First(Arr : Array) -> Index_Type is
     return Arr.First;
   end First;
   function Last(Arr : Array) -> Index_Type is
     return Arr.Last;
   end Last;
   operator "[]"(Arr : ref Array;
     Index : Index_Type {Index in First(Arr)..Last(Arr)})
       -> ref Element_Type is
     return Data[Index-First];
   end "[]";
   function Create_Array(First, Last : Index_Type)
       -> Result:Array
           {First(Result) = First & Last(Result) = Last}
     return (First => First, Last => Last, Data => ());
   end Create_Array ;
 end class Array;

A class must include implementations for each operation in its interface, plus any number of local declarations as necessary to implement the exported operations.  The exported declarations inside a class follow the word exports.  Declarations preceding exports are local to the class.  Even though the interface associated with the class implies what operations are exported, we make the distinction explicit in the class itself, since changing the specification of an exported declaration has a much larger implication than does changing that of a local declaration.  Also, by segregating the exported declarations at the end, we make it easier to find them.  Finally, because a class might implement interfaces other than its own, the exported declarations allow it to fulfill the set of operations of other interfaces.  C uses "extern" vs. "static" to make a similar distinction.  Java uses "public" vs. "private".

Note that the above example is being pretty fast and loose with syntax and semantics.  But at this point, ParaSail's design isn't complete yet, so any examples should be taken with a grain of salt.  Nevertheless, it seems useful to try to produce examples.  It is guaranteed that the examples won't all be consistent with one another, since the syntax and semantics will continue to evolve during this design process.  And part of the reason for producing examples is to try out the evolving ideas, and see how they look.  One good concrete example can often shatter or confirm many days of abstract philosophizing.

No comments:

Post a Comment