Modula-2 Reloaded

A Modern Typesafe & Literate Programming Notation

Site Menu

Project

Specification

Implementation

Recommendations

Reference

Needs Updating

Work in Progress

Wastebasket

Wiki Manual

edit SideBar

Verification Of Operator Bindings Static And Dynamic Types

Synopsis

This article describes three possible approaches how to enforce permitted operator bindings based on semantic types but also taking into account that some semantic types are static in nature while others are dynamic.

Problem Description

The grammar (status April 14, 2010) defines syntax that allows a semantic type to be specified in a RECORD declaration only. If a type is declared as an opaque pointer, such as would be the case for types of dynamic nature, e.g. string and collection types, then there is no syntax to specify a semantic type.

Possible Solutions in Brief

1) No additional syntax, but shared semantics for strings and collections

With this approach no additional syntax is added. No type specifiers exist for strings and collections.

TYPE SHORTINT = OPAQUE RECORD ("Z-Type") ... END;
TYPE String = OPAQUE; (* strings and collections share the same bindings *)

2) Additional syntax to allow semantic type specifier in opaque pointer declarations

With this approach additional syntax is provided for opaque pointer declarations. Each semantic type requires a type specifier.

TYPE SHORTINT = OPAQUE RECORD ("Z-Type") ... END;
TYPE String = OPAQUE ("S-Type");

3) Modified syntax to move semantic type specifier into the module declaration

With this approach the syntax is changed to put the type specifier into the module header. Each semantic type requires a type specifier.

DEFINITION MODULE SHORTINT ("Z-Type");
DEFINITION MODULE String ("S-Type");

Discussion in Detail

With approach #1 string and collection types would have to share one set of permitted bindings. Either the bindings for < and > would have to be permitted for collection types, or the presence of a binding for LENGTH or COUNT would have to determine which set of bindings are permitted. The former would leave the semantics of operators < and > for collection types undefined and open to library implementors. The latter would lead to some overhead in semantic analysis. Either way would introduce some inconsistency into the language. Overall this approach may give the impression that operator bindings for string and collection types were bolted-on afterwards. Adding further semantic types in the future may become difficult without rendering existing source code incompatible.

Approaches #2 and #3 both have consistent syntax and semantics. Bindings are only permitted if a semantic type is specified. Every semantic type has a specifier and an associated set of permitted bindings. Both approaches can accommodate the addition of further semantic types in the future without rendering existing source code incompatible.

The syntax of approach #2 emphasises the notion that bindings are a property of the type. In the event that the same library also defines other auxiliary types, this syntax has the advantage that it is always clear to which type the semantic type specifier applies.

The syntax of approach #3 emphasises the notion that bindings are a property of the library. Since the definition module of a library also serves as its documentation, this syntax has the advantage that it indicates the semantic model of the library at the top of its documentation. It also has a minor advantage in that the grammar is slightly simpler.

Type Specifier for Collection Types

Since approaches #2 and #3 require a specifier for each semantic type, both necessitate the introduction of a new specifier for collection types. The most obvious mnemonic "C-Type" is not available because it is already in use for complex number types. Suitable alternatives would be "A-Type" as a mnemonic for "array notation", or "AA-Type" as a mnemonic for "associative array".

TYPE Dictionary = OPAQUE ("A-Type");
TYPE UniString = OPAQUE ("S-Type");

Another alternative would be "Collection" but this would be inconsistent with other semantic type specifiers. This inconsistency could be resolved by using "String" instead of "S-Type" and reserve single letter based specifiers for numeric types only.

TYPE Dictionary = OPAQUE ("Collection");
TYPE UniString = OPAQUE ("String");

Overall, "A-Type", "S-Type", "Z-Type", "R-Type", "C-Type" and "V-Type" would seem to be the more consistent set of specifiers.

Static Semantics

For approach #1 the static semantics would be as follows:

  • if there is a record type declaration with a specifier and the same name as the module then bindings associated with the specifier are permitted.
  • if there is an opaque pointer type declaration with the same name as the module then string and collection bindings are permitted.
  • if string and collection bindings are permitted then LENGTH and COUNT bindings are mutually exclusive.
  • if there is a binding to LENGTH, then only string bindings are permitted.
  • if there is a binding to COUNT, then only collection bindings are permitted.

For approach #2 the static semantics would be as follows:

  • the type with the specifier must have the same name as the module.
  • Z, R and C type specifiers can only be used in a record declaration.
  • S and A type specifiers can only be used in a opaque pointer declaration.

For approach #3 the static semantics would be as follows:

  • the type specifier is applied to the type with the same name as the module.
  • if the module header has a Z, R or C specifier, the type must be a record.
  • if the module header has an S or A specifier, the type must be an opaque pointer.

Full Examples

Conclusion

Approach #1 is the least favourable because it introduces inconsistencies, requires more semantic analysis and may inhibit the addition of more semantic types in the future. Approaches #2 and #3 are favourable and both are equally suitable. If it is desired to emphasise bindings as a property of the type, #2 may be given preference. If it is desired to emphasise bindings as a property of the library, #3 may be given preference. If the newly required type specifier for collection types is to be chosen with the highest overall consistency in mind then "A-Type" is the most suitable choice.