Type (UDT/Alias/Temporary) and Union

The different keywords Type (UDT), Type (Alias), Type (Temporary), and Union
.

Definition
   There may be confusion in the user mind between the different keywords 
   Type and Union (despite the documentation that distinguishes them from 
   each other through some different pages):
      * Type (Udt):
            Declares/Defines a user structure of non overlapping data with 
            possibly member procedures:
               - Named Type: Type that has a name that can be referenced to 
               declare the data type.
               - Anonymous Type: Type that does not have a name and so 
               cannot be referenced by a name.
      * Type(Alias):
            Declares a user defined type name from other user defined or 
            standard data types.
      * Type (Temporary):
            Creates a temporary instance of a user defined type.
      * Union:
            Declares/Defines a user structure of overlapping data with 
            possibly member procedures but no object fields (or bases) with 
            constructors or destructors (directly on indirectly):
               - Named Union: Union that has a name that can be referenced 
               to declare the data type.
               - Anonymous Union: Union that does not have a name and so 
               cannot be referenced by a name.

   Complexity level for a Type/Union structure:
      - Trivial structure: Named or Anonymous structure that has no member 
      procedures (directly on indirectly).
      - Complex structure: Named Structure that has member procedure(s) 
      (directly or indirectly).
      - Extended structure: Named structure that inherits from another 
      named structure.

   Type/Union structure can be also nested inside another Type/Union 
   structure:
      - Nested Named Type: Named Type that is nested inside another Named 
      Type/Union structure.
      - Nested Anonymous Type: Anonymous Type that is nested inside another 
      Named or Anonymous Union structure.
      - Nested Named Union: Named Union that is nested inside another Named 
      Type/Union structure.
      - Nested Anonymous Union: Anonymous Union that is nested inside 
      another Named or Anonymous Type structure.

   Type (Alias) declaration can be also nested inside a Type/Union 
   structure:
      - Nested Type (Alias) declaration allows declaration of an inner 
      alias inside a Type/Union and according to the access right of the 
      place.

Description
   The main purpose of Nested Named Types/Unions is:
      - To allow relationships between Types and Unions to be expressed in 
      an understandable way.
      - Such a Type or Union has its own namespace in which to organize 
      related symbols - and provide visibility access (Public/Protected/
      Private) for Types only - to give finer-grained control over access 
      to members.
      - When there are circular dependencies between Types/Unions, Nested 
      Named Type/Union usage can avoid using Type (Alias) and forward 
      referencing.
   Without Nested Named Types/Unions:
      - Relationships can still be expressed between Types/Unions but have 
      the disadvantage that all Types/Unions must be publicly accessible.
      - Namespace use can help organize scope of visibility but the problem 
      remains that *all* Types/Unions must be visible.
      - In some situations this allows a user (or the author himself) to 
      inadvertently use a Type/Union in a way that it was never intended, 
      potentially creating valid but error-prone code.
      - This problem can be reduced by hiding Types/Unions through of 
      forward declarations (via Type (Alias)) and putting private symbols 
      in a separate module, but creates new problems by fragmenting the 
      code.

   Anonymous Type (or Union):
      - Does not have a name and cannot be referenced by name.
      - May only appear nested within a Named Union (or Type) or another 
      Anonymous Union (or Type) .
      - Declares fields within the structure that nests it, either at 
      separate memory locations (Nested Type) or overlapping memory 
      locations (Nested Union).
      - Fields can be referenced.
      - Cannot contain any static members or procedures declarations 
      (directly or indirectly) => Trivial structure.

   Named Type (or Union):
      - Has a name that can be referenced to declare the data type for 
      fields, variables, parameters, arrays, etc.
      - Can appear on its own or nested inside another Named Type (or 
      Union).
      - Declaration of the Type (or Union) only.
      - Does not declare any fields within the structure that nests it, so 
      it does not add any size to it.
      - Can contain static member(s) or procedure declaration(s) (directly 
      or indirectly) => Trivial/Complex structure.

   Complexity level for Type/Union structure versus scope location:
      - Trivial structure: Named or Anonymous Type/Union that can be 
      declared at global / namespace / nested scopes or inside local scopes 
      (like Scope or Sub).
      - Complex structure: Named Type/Union that must be declared at the 
      global / namespace / nested scope with definitions at the global / 
      namespace scope.
      - Extended structure: Named Type/Union declared in a scope that has 
      visibility to its Base's scope (currently in same scope than its 
      Base).	

   The main structure (Type/Union) must be always Named, the other (Nested) 
   structures can be Anonymous or Named.
   Mostly everything it can be done in a Named Type/Union can also be done 
   in a Nested Named Type/Union, including the inheritance capability (as 
   base or as derived).
   Nested Anonymous Type/Union can not have procedure members or static 
   data members (same restriction than for a Named Type/Union inside a 
   local scope).

Example
   Example: 'Named Type' <- 'Nested Anonymous Union' <- 'Nested Anonymous 
   Type':
   Type T  '' named
      Union  '' anonymous
         Dim a As Short
         Type  '' anonymous
            Dim b1 As Byte
            Dim b2 As Byte
         End Type
      End Union
      Declare Sub proc()
   End Type

   Sub T.proc()
      b1 = 1
      b2 = 2
      Print b1, b2, a
   End Sub

   Dim x As T
   x.proc()

   Sleep

   Example of circular dependencies between two main types solved by Nested 
   Named Type usage (to avoid using type aliases and forward referencing):
   '' example of two dependent types, with a type alias and a forward referencing:
   '
   'Type list As list_
   '
   'Type listnode
   '    text As String
   '    parent As list Ptr
   'End Type
   '
   'Type list_
   '    first As listnode Ptr
   '    count As Integer
   'End Type

   '' same example of two dependent types, but with simply one of them a Nested Named Type: 

   Type list
      count As Integer
      Type listnode
         text As String
         parent As list Ptr
      End Type
      first As listnode Ptr
   End Type

   Example to check access syntaxes and access rights:
   Type UDT1
      Private:
         Dim As Integer I1 = 123
         Type UDT2
            Private:
               Dim As Integer I2 = 456
            Public:
               Declare Function returnI2() As Integer
         End Type
      Public:
         Type UDT3
            Private:
               Dim As Integer I3 = 789
            Public:
               Declare Function returnI3() As Integer
         End Type
         Declare Function returnI1() As Integer
         Dim As UDT2 t2
         Dim As UDT3 t3
   End Type

   Function UDT1.returnI1() As Integer
      Return This.I1
   End Function

   Function UDT1.UDT2.returnI2() As Integer
      Return This.I2
   End Function

   Function UDT1.UDT3.returnI3() As Integer
      Return This.I3
   End Function

   Dim As UDT1 t11

   'Print t11.I1            '' error 202: Illegal member access
                      ''    I1 is in the private section of UDT1

   Print t11.returnI1()     '' OK, returnI1() is in the public section of UDT1

   'Print t11.t2.I2         '' error 202: Illegal member access
                      ''    t2 is in the public section of UDT1, but I2 is in the private section of UDT2

   Print t11.t2.returnI2()  '' OK, t2 is in the public section of UDT1, and returnI2() is in the public section of UDT2

   'Print t11.t3.I3         '' error 202: Illegal member access
                      ''    t3 is in the public section of UDT1, but I3 is in the private section of UDT3

   Print t11.t3.returnI3()  '' OK, t3 is in the public section of UDT1, and returnI3() is in the public section of UDT3
   Print

   'Dim As UDT1.UDT2 t21    '' error 202: Illegal member access
                      ''    UDT2 is in the private section of UDT1

   Dim As UDT1.UDT3 t31     '' OK, UDT3 is in the public section of UDT1

   'Print t31.I3            '' error 202: Illegal member access
                      ''    I3 is in the private section of UDT3

   Print t31.returnI3()     '' OK, returnI3() is in the public section of UDT3

   Sleep

   Example of what we can do with nested named types.
   This is just the declaration part, but gives a few things worth pointing 
   out:
   Type MemoryTable
      Private:
         '' private members visible within MemoryTable only
         Const default_alignment = 16
         m_bytes_per_node As UInteger = 0
         m_nodes_per_chunk As UInteger = 0
         Type Chunk
            m_owner As MemoryTable Ptr
            m_nodes As UInteger
            m_prevChunk As Chunk Ptr
            m_data As Any Ptr
         End Type
         Declare Sub allocChunk()
         m_headChunk As Chunk Ptr = 0
      Protected:
         '' protected members visible within MemoryTable and derived types
         Declare Constructor()
         Type Iterator
            Private:
               m_chunk As Chunk Ptr
               m_index As Integer
            Protected:
               Declare Constructor()
               Declare Constructor(ByVal table As MemoryTable Ptr)
               Declare Property item() As Any Ptr
            Public:
               Declare Property hasItem() As Boolean
               Declare Sub nextItem()
         End Type
         Declare Function newNode() As Any Ptr
      Public:
         '' public member visible from outside the type
         Declare Constructor(ByVal bytes As UInteger, nodes As UInteger)
         Declare Destructor()
   End Type

	
See also
   * Overview (User Defined Types)
   * Type Aliases
   * Temporary Types
   * Constructors and Destructors (basics)
   * Member Access Rights and Encapsulation

