Template

A generic program unit, parameterised by types and operations.

Declaration

Syntax

Template(symbol_table symtab, identifier name, identifier* args,
    require_instantiation* requires)

Arguments

Argument

Description

symtab

the symbol table of the template: its type parameters, the operations it requires, and the generic procedures it defines.

name

the name of the template.

args

the names of the parameters of the template, in order.

requires

the requirements the parameters must satisfy, each a Require.

Return values

None.

Description

A Template holds procedures written against type parameters instead of concrete types. It is not code: nothing in a template can be called or compiled directly, because the types are not known yet.

instantiate produces the code. Instantiating a template substitutes concrete types and procedures for args, checks them against requires, and copies the procedures of the template into the instantiating scope with the substitution applied. Those copies are ordinary Function symbols, so everything downstream of instantiation sees ordinary ASR.

Examples

An ASR text document that uses it:

(TranslationUnit
  :symtab (SymbolTable
    :id 0
    :symbols {
      "m" (Module
        :symtab (SymbolTable
          :id 1
          :symbols {
            "apply_t" (Template
              :symtab (SymbolTable
                :id 2
                :symbols {
                  "apply" (Function
                    :symtab (SymbolTable
                      :id 3
                      :symbols {
                        "x" (Variable
                          :parent_symtab 3
                          :name "x"
                          :dependencies []
                          :intent :In
                          :symbolic_value nil
                          :value nil
                          :storage :Default
                          :type (TypeParameter
                            :param "t"
                          )
                          :type_declaration nil
                          :abi :Source
                          :access :Public
                          :presence :Required
                          :value_attr false
                          :target_attr false
                          :contiguous_attr false
                          :bindc_name nil
                          :is_volatile false
                          :is_protected false
                          :pass_attr :NotMethod
                          :self_argument nil
                          :codims []
                        )
                        "z" (Variable
                          :parent_symtab 3
                          :name "z"
                          :dependencies []
                          :intent :ReturnVar
                          :symbolic_value nil
                          :value nil
                          :storage :Default
                          :type (TypeParameter
                            :param "t"
                          )
                          :type_declaration nil
                          :abi :Source
                          :access :Public
                          :presence :Required
                          :value_attr false
                          :target_attr false
                          :contiguous_attr false
                          :bindc_name nil
                          :is_volatile false
                          :is_protected false
                          :pass_attr :NotMethod
                          :self_argument nil
                          :codims []
                        )
                      }
                    )
                    :name "apply"
                    :function_signature (FunctionType
                      :arg_types [
                        (TypeParameter
                          :param "t"
                        )
                      ]
                      :return_var_type (TypeParameter
                        :param "t"
                      )
                      :abi :Source
                      :deftype :Implementation
                      :bindc_name nil
                      :elemental false
                      :pure false
                      :module false
                      :inline false
                      :static false
                      :restrictions []
                      :is_restriction false
                      :exec_space :Host
                    )
                    :dependencies [
                      "op"
                    ]
                    :args [
                      (Var
                        :v (SymbolRef 3 "x")
                      )
                    ]
                    :body [
                      (Assignment
                        :target (Var
                          :v (SymbolRef 3 "z")
                        )
                        :value (FunctionCall
                          :name (SymbolRef 2 "op")
                          :original_name nil
                          :args [
                            (call_arg
                              :value (Var
                                :v (SymbolRef 3 "x")
                              )
                            )
                          ]
                          :type (TypeParameter
                            :param "t"
                          )
                          :value nil
                          :dt nil
                        )
                        :overloaded nil
                        :realloc_lhs false
                        :move_allocation false
                      )
                    ]
                    :return_var (Var
                      :v (SymbolRef 3 "z")
                    )
                    :access :Public
                    :deterministic false
                    :side_effect_free false
                    :module_file nil
                  )
                  "op" (Function
                    :symtab (SymbolTable
                      :id 4
                      :symbols {
                        "x" (Variable
                          :parent_symtab 4
                          :name "x"
                          :dependencies []
                          :intent :In
                          :symbolic_value nil
                          :value nil
                          :storage :Default
                          :type (TypeParameter
                            :param "t"
                          )
                          :type_declaration nil
                          :abi :Source
                          :access :Public
                          :presence :Required
                          :value_attr false
                          :target_attr false
                          :contiguous_attr false
                          :bindc_name nil
                          :is_volatile false
                          :is_protected false
                          :pass_attr :NotMethod
                          :self_argument nil
                          :codims []
                        )
                        "z" (Variable
                          :parent_symtab 4
                          :name "z"
                          :dependencies []
                          :intent :ReturnVar
                          :symbolic_value nil
                          :value nil
                          :storage :Default
                          :type (TypeParameter
                            :param "t"
                          )
                          :type_declaration nil
                          :abi :Source
                          :access :Public
                          :presence :Required
                          :value_attr false
                          :target_attr false
                          :contiguous_attr false
                          :bindc_name nil
                          :is_volatile false
                          :is_protected false
                          :pass_attr :NotMethod
                          :self_argument nil
                          :codims []
                        )
                      }
                    )
                    :name "op"
                    :function_signature (FunctionType
                      :arg_types [
                        (TypeParameter
                          :param "t"
                        )
                      ]
                      :return_var_type (TypeParameter
                        :param "t"
                      )
                      :abi :Source
                      :deftype :Implementation
                      :bindc_name nil
                      :elemental false
                      :pure false
                      :module false
                      :inline false
                      :static false
                      :restrictions []
                      :is_restriction false
                      :exec_space :Host
                    )
                    :dependencies []
                    :args [
                      (Var
                        :v (SymbolRef 4 "x")
                      )
                    ]
                    :body []
                    :return_var (Var
                      :v (SymbolRef 4 "z")
                    )
                    :access :Public
                    :deterministic false
                    :side_effect_free false
                    :module_file nil
                  )
                  "t" (Variable
                    :parent_symtab 2
                    :name "t"
                    :dependencies []
                    :intent :In
                    :symbolic_value nil
                    :value nil
                    :storage :Default
                    :type (TypeParameter
                      :param "t"
                    )
                    :type_declaration nil
                    :abi :Source
                    :access :Public
                    :presence :Required
                    :value_attr false
                    :target_attr false
                    :contiguous_attr false
                    :bindc_name nil
                    :is_volatile false
                    :is_protected false
                    :pass_attr :NotMethod
                    :self_argument nil
                    :codims []
                  )
                }
              )
              :name "apply_t"
              :args [
                "t"
                "op"
              ]
              :requires [
                (Require
                  :name "r"
                  :args [
                    "t"
                    "op"
                  ]
                )
              ]
            )
            "r" (Requirement
              :symtab (SymbolTable
                :id 5
                :symbols {
                  "op" (Function
                    :symtab (SymbolTable
                      :id 6
                      :symbols {
                        "x" (Variable
                          :parent_symtab 6
                          :name "x"
                          :dependencies []
                          :intent :In
                          :symbolic_value nil
                          :value nil
                          :storage :Default
                          :type (TypeParameter
                            :param "t"
                          )
                          :type_declaration nil
                          :abi :Source
                          :access :Public
                          :presence :Required
                          :value_attr false
                          :target_attr false
                          :contiguous_attr false
                          :bindc_name nil
                          :is_volatile false
                          :is_protected false
                          :pass_attr :NotMethod
                          :self_argument nil
                          :codims []
                        )
                        "z" (Variable
                          :parent_symtab 6
                          :name "z"
                          :dependencies []
                          :intent :ReturnVar
                          :symbolic_value nil
                          :value nil
                          :storage :Default
                          :type (TypeParameter
                            :param "t"
                          )
                          :type_declaration nil
                          :abi :Source
                          :access :Public
                          :presence :Required
                          :value_attr false
                          :target_attr false
                          :contiguous_attr false
                          :bindc_name nil
                          :is_volatile false
                          :is_protected false
                          :pass_attr :NotMethod
                          :self_argument nil
                          :codims []
                        )
                      }
                    )
                    :name "op"
                    :function_signature (FunctionType
                      :arg_types [
                        (TypeParameter
                          :param "t"
                        )
                      ]
                      :return_var_type (TypeParameter
                        :param "t"
                      )
                      :abi :Source
                      :deftype :Implementation
                      :bindc_name nil
                      :elemental false
                      :pure false
                      :module false
                      :inline false
                      :static false
                      :restrictions []
                      :is_restriction false
                      :exec_space :Host
                    )
                    :dependencies []
                    :args [
                      (Var
                        :v (SymbolRef 6 "x")
                      )
                    ]
                    :body []
                    :return_var (Var
                      :v (SymbolRef 6 "z")
                    )
                    :access :Public
                    :deterministic false
                    :side_effect_free false
                    :module_file nil
                  )
                  "t" (Variable
                    :parent_symtab 5
                    :name "t"
                    :dependencies []
                    :intent :In
                    :symbolic_value nil
                    :value nil
                    :storage :Default
                    :type (TypeParameter
                      :param "t"
                    )
                    :type_declaration nil
                    :abi :Source
                    :access :Public
                    :presence :Required
                    :value_attr false
                    :target_attr false
                    :contiguous_attr false
                    :bindc_name nil
                    :is_volatile false
                    :is_protected false
                    :pass_attr :NotMethod
                    :self_argument nil
                    :codims []
                  )
                }
              )
              :name "r"
              :args [
                "t"
                "op"
              ]
              :requires []
            )
          }
        )
        :name "m"
        :parent_module nil
        :dependencies []
        :loaded_from_mod false
        :intrinsic false
        :has_submodules false
      )
      "main" (Program
        :symtab (SymbolTable
          :id 7
          :symbols {}
        )
        :name "main"
        :dependencies []
        :body []
      )
    }
  )
  :items []
)

See Also

Requirement, TypeParameter, Function