{{fbdoc item="title" value="Type (UDT/Alias/Temporary) and Union"}}----
The different keywords **Type (UDT)**, **Type (Alias)**, **Type (Temporary)**, and **Union**.

{{fbdoc item="section" value="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):
		- ##[[KeyPgType|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.
		- ##[[KeyPgTypeAlias|Type(Alias)]]##:
				Declares a user defined type name from other user defined or standard data types.
		- ##[[KeyPgTypeTemp|Type (Temporary)]]##:
				Creates a temporary instance of a user defined type.
		- ##[[KeyPgUnion|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.

{{fbdoc item="section" value="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 (##[[KeyPgPublic|Public]]##/##[[KeyPgVisProtected|Protected]]##/##[[KeyPgPrivate|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.
		**""-""** ##[[KeyPgNamespace|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).

{{fbdoc item="section" value="Example"}}
	Example: 'Named Type' <- 'Nested Anonymous Union' <- 'Nested Anonymous Type':
		{{fbdoc item="filename" value="examples/manual/proguide/typeunion/nested_type_union_1.bas"}}%%(freebasic)
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):
		{{fbdoc item="filename" value="examples/manual/proguide/typeunion/nested_type_union_2.bas"}}%%(freebasic)
'' 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:
		{{fbdoc item="filename" value="examples/manual/proguide/typeunion/nested_type_union_3.bas"}}%%(freebasic)
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:
		{{fbdoc item="filename" value="examples/manual/proguide/typeunion/nested_declaration.bas"}}%%(freebasic)
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
%%	
{{fbdoc item="section" value="See also"}}
	- [[ProPgUDTs|Overview (User Defined Types)]]
	- [[ProPgTypeAliases|Type Aliases]]
	- [[KeyPgTypeTemp|Temporary Types]]
	- [[ProPgCtorsDtors|Constructors and Destructors (basics)]]
	- [[ProPgMemberAccessRights|Member Access Rights and Encapsulation]]

{{fbdoc item="back" value="CatPgProgrammer|Programmer's Guide"}}