Chapter 19. Generic types

Description

A generic type is a source code template used to define standard types.

Each generic type has a number of parameters which represent types used within the source code template. Each time the type of an object reference (i.e. the type of an attribute, command input/output argument, constant or variable) is specified in the source code template, a parameter can be used as a placeholder, instead of a hardcoded fixed type. Therefore, generic types are also called parameterized types.

A standard type can be defined by using a generic type and specifying a type for each parameter of the generic type. Such a type created from a generic type is called a generified type.

Before explaining the precise rules for defining and using generic types, it might be useful to get a first impression with the following simple example:

generic type pair

   param item_type end

   type
      attribute item1 type: {item_type} end
      attribute item2 type: {item_type} end
   end

end

The above generic type can be used to define any type that represents a pair of items of the same type. The type of the items is denoted by parameter item_type, and that parameter must be enclosed between { and } whenever it is used in the source code.

A pair of books, for example, can now be defined as follows:

type pair_of_books

   !pair<book>

end

Here is another generified type; a pair of dogs:

type pair_of_dogs

   !pair<dog>

end

Without using a generic type, pair_of_dogs would be coded as follows:

type pair_of_dogs_

   attribute item1 type: dog end
   attribute item2 type: dog end

end
[Note]Note

This is also the code that the compiler creates when generic type pair is used. However, there are some differences concerning type compatibility, as explained later.

As we can see so far, generic types are used to define similar types that differ only by their types used for object references.

Rules

  1. The syntax for defining a generic type is as follows:

    Table 19.1. Generic type syntax

    ProductionSyntaxLinks
    generic_type

    "generic" "type" ( "id" ":" ) ? generic_type_id
       generic_parameter +
       type
    "end" "generic" ?

    Remarks:

    • properties id and default_factory must not be specified for type
    • each time a generic_parameter is used in the source code of type, it must be enclosed between { and }
    Chapter 19, Generic types
    generic_type_id"ge_" ? identifier 
    generic_parameter

    "param" ( "id" ":" ) ? generic_parameter_id "end"

     
    generic_parameter_id"pa_" ? identifier 

    As we can see:

    • A generic type is introduced with the keywords generic type.

    • Each generic type is identified by a generic type identifier, which is a prefixed identifier starting with ge_

    • Each generic type has one or more parameters which are placeholders for types that will be used for object references in the generified types.

    • Each parameter can be used in the source code of type to specify a variable type for an object reference. The syntax for such a variable type consists of the parameter's identifier enclosed between { and } (e.g. attribute item type: {type_of_item}).

    Here is a reprint of the above example of a generic type:

    generic type pair
    
       param item_type end
    
       type
          attribute item1 type: {item_type} end
          attribute item2 type: {item_type} end
       end
    
    end
  2. The syntax for defining a generified type is as follows:

    Table 19.2. Generified type syntax

    ProductionSyntaxLinks
    generified_type

    "type" ( "id" ":" ) ? type_id
       generic_type_selector
    "end" "type" ?

    Chapter 19, Generic types
    generic_type_selector"!" ( library_selector "." ) ? generic_type_id generic_type_parameter_assignments ?Chapter 19, Generic types
    generic_type_parameter_assignments"<" generic_type_parameter_assignment ( ";" ? generic_type_parameter_assignment ) * ">" 
    generic_type_parameter_assignment ( generic_type_parameter_id ":" ) ? object_type_selector

    remark: generic_type_parameter_id : can only be omitted if the generic_type has exactly one parameter

     

    As we can see, the body of a generified type is introduced by a !, and then simply defined by referencing the generic type and providing an object type for each parameter in the generic type.

    Here is a reprint of the above example of a generified type:

    type pair_of_books
    
       !pair<book>
    
    end

    Generified types are used the same way standard types are used.

    For example, a variable could be declared as:

    var pair_of_books two_books

    And, after creating a pair of books, the first book could then be retrieved with:

    var book first_book = two_books.item1
  3. A generified type can also be defined 'on the fly'.

    'On the fly' means that there is no need to define a type as explained in the previous rule. Instead, the following syntax can be used wherever the type of an object reference (e.g. the type of an attribute) must be specified in source code:

    Table 19.3. 'On the fly' generified type syntax

    ProductionSyntaxLinks
    generic_type_selector"!" ( library_selector "." ) ? generic_type_id generic_type_parameter_assignments ?Chapter 19, Generic types
    generic_type_parameter_assignments"<" generic_type_parameter_assignment ( ";" ? generic_type_parameter_assignment ) * ">" 
    generic_type_parameter_assignment ( generic_type_parameter_id ":" ) ? object_type_selector

    remark: generic_type_parameter_id : can only be omitted if the generic_type has exactly one parameter

     

    As we can see the syntax used to define a generified type 'on the fly' is the same as the syntax used in the previous rule.

    Thus, instead of declaring a variable as shown in the previous rule:

    var pair_of_books two_books

    the same can be achieved without defining type pair_of_books, and declaring the variable as follows:

    var !pair<book> two_books

    Generified types and 'on the fly' generified types can coexist, even if they use the same type parameters. The compiler automatically checks the parameters for generified types, and if two sets of parameters have the same values, then a single common type is used by the compiler.

  4. Currently, two generified types that use the same generic type are considered to be type compatible at compile-time, but a runtime error is immediately raised in case of any type incompatibility occurring at runtime.

    [Note]Note
    This rule will change in a future version, so that type compatibility will be verified at compile-time.

The following rules define how to define factories that implement generified types. The rules for factories are analogous to those for types.

  1. The syntax for defining a generic factory is as follows:

    Table 19.4. Generic factory syntax

    ProductionSyntaxLinks
    generic_factory

    "generic" "factory" ( "id" ":" ) ? generic_factory_id
       generic_parameter *
       factory
    "end" "generic" ?

    Remark: property 'id' must not be specified for 'factory'

    Chapter 19, Generic types
    generic_factory_id"ge_" ? identifier 
    generic_parameter

    "param" ( "id" ":" ) ? generic_parameter_id "end"

     
    generic_parameter_id"pa_" ? identifier 

  2. The syntax for defining a generified factory is as follows:

    Table 19.5. Generified factory syntax

    ProductionSyntaxLinks
    generified_factory

    "factory" ( "id" ":" ) ? factory_id "type" ":" type_selector
       generic_factory_selector
    "end" "factory" ?

    Chapter 19, Generic types
    generic_factory_selector"!" ( library_selector "." ) ? generic_factory_id generic_type_parameter_assignments ?Chapter 19, Generic types
    generic_type_parameter_assignments"<" generic_type_parameter_assignment ( ";" ? generic_type_parameter_assignment ) * ">" 
    generic_type_parameter_assignment ( generic_type_parameter_id ":" ) ? object_type_selector

    remark: generic_type_parameter_id : can only be omitted if the generic_type has exactly one parameter

     

  3. A generified factory can also be defined 'on the fly' with the following syntax:

    Table 19.6. 'On the fly' generified factory syntax

    ProductionSyntaxLinks
    generic_factory_selector"!" ( library_selector "." ) ? generic_factory_id generic_type_parameter_assignments ?Chapter 19, Generic types
    generic_type_parameter_assignments"<" generic_type_parameter_assignment ( ";" ? generic_type_parameter_assignment ) * ">" 
    generic_type_parameter_assignment ( generic_type_parameter_id ":" ) ? object_type_selector

    remark: generic_type_parameter_id : can only be omitted if the generic_type has exactly one parameter

     

See also