- Allows use of the [[ ... ]] operation, which converts the operand to a universal type.
- The user defines which universal type(s) a given type converts to by defining the "to_univ" operator(s). Once the value has been converted to a universal type, it will be implicitly converted to any other type which defines a "from_univ" operator from that same universal type.
- Using a prefix can disambiguate if necessary: T2::[[T1_Obj]] will convert T1_Obj first to a universal type using T1's "from_univ" operator, and then to T2 using T2's "to_univ" operator.
- Allows use of the target type's name as a function name.
- This will convert between two types that are structurally equivalent (that is, the same module parameters were used in their defining instantiation), but which were distinguished by one or both being defined as new. For example:
- type T1 is new Vector<Integer<>> and type T2 is new Vector<Integer<>> define two distinct types because of the use of new, but T2(T1_Obj) and T1(T2_Obj) will convert T1_Obj to type T2, and T2_Obj to type T1, respectively.
- The target type's name can also convert an object from some source type if the user defines a "convert" operator for either of the two types, and this operator's input and output parameter types match the source and target of the conversion. Note that this matching might be thanks to the input or output formal being itself parameterized. For example, the interface Int_Vector below provides a "convert" operator that converts to any other instance of Int_Vector:
interface Int_Vector<Element is Integer<>> is ... operator "convert"(X : Int_Vector) -> Result_Type is Int_Vector<Target_Element is Integer<>>; end interface Int_Vector;These capabilities seem to provide enough flexibility for the user to define the desired explicit conversion functions. Note that the only implicit conversion in ParaSail is from a universal type to a type with an appropriate "from_univ" operator.