Nested Types and Unions

Forum for discussion about the documentation project.
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Nested Types and Unions

Post by coderJeff »

October 2022, fbc 1.10.0, feature added that allows declaring TYPEs and UNIONs inside another TYPE or UNION:

For example:

Code: Select all

type t1 extends object
  type t2 extends object
    type t3 extends object
      '' etc...
    end type
  end type
end type
Topics I will try my best to explain here (work in progress):
- Terminology
- Purpose for this feature and what it does
- Difference from anonymous inner types
- What is expected to work now
- Limitations
- Features missing but will be implemented
- Potential bugs
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Nested Types and Unions

Post by fxm »

Indeed, I think there is quite a lot to add to the documentation to properly and clearly describe the two kinds of nested Types/Unions available:
- anonymous inner Types/Unions,
- named inner Types/Unions.

All this on the same existing page: TYPE ?
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Nested Types and Unions

Post by coderJeff »

Terminology
fxm wrote: Oct 16, 2022 14:14 All this on the same existing page: (TYPE) ?
I think is probably worthwhile to only mention it on TYPE page and perhaps add a new page TYPE (Nested) to document this new feature.
fxm wrote: Oct 16, 2022 14:14 - anonymous inner Types/Unions,
- named inner Types/Unions.
yea, there is a number of overlapping concepts. fbc source comments use 'nested' and 'inner' somewhat interchangeably with respect to TYPE declarations. And 'scope' is used sometimes as a synonym for the concept of 'namespace'. TYPE is also a kind of namespace that can have other symbols declared within it's declarative scope. So it can be a bit of a mess.

Here is what I am thinking:
- when I refer to "TYPE" I usually am inferring "TYPE|UNION"
- "nested type" to refer to this new feature: a named TYPE only inside the namespace of another TYPE - it's not a field, only a declaration
- "anonymous inner TYPE" to refer to a structure inside a TYPE that has fields and adds size to the TYPE, but has no name
- "named inner type" should probably be avoided - fields are named and can be of a TYPE

Code: Select all

type T
	union U         '' nested type in T's namespace
		a as short
		b as byte
	end union
	fld as U        '' field having type 'U'
	union           '' anonymous inner type
		c as short
		d as byte
	end union
end type

print sizeof( T.U.a )   '' ok, accessing declaration
print sizeof( T.d )     '' ok, accessing declaration

dim x as T

print sizeof( x.fld.a ) '' ok, accessing fields
print x.fld.a           '' ok, accessing fields
print sizeof( x.d )     '' ok, accessing field
print x.d               '' ok, accessing field

print sizeof( x.U.a )   '' not allowed, U is not a field, U is a declaration
print x.U.a             '' not allowed, U is not a field, U is a declaration
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Nested Types and Unions

Post by fxm »

coderJeff wrote: Oct 16, 2022 14:50 I think is probably worthwhile to only mention it on TYPE page and perhaps add a new page TYPE (Nested) to document this new feature.
Yes I agree (hence my previous question).

coderJeff wrote: Oct 16, 2022 14:50 Here is what I am thinking:
- when I refer to "TYPE" I usually am inferring "TYPE|UNION"
- "nested type" to refer to this new feature: a named TYPE only inside the namespace of another TYPE - it's not a field, only a declaration
- "anonymous inner TYPE" to refer to a structure inside a TYPE that has fields and adds size to the TYPE, but has no name
- "named inner type" should probably be avoided - fields are named and can be of a TYPE
To be clearer, I would prefer the following exhaustive naming: "named nested type" and "anonymous inner type".
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Nested Types and Unions

Post by coderJeff »

fxm wrote: Oct 16, 2022 15:07 To be clearer, I would prefer the following exhaustive naming: "named nested type" and "anonymous inner type".
Not sure if there are clear opposites.

I find "anonymous" ambiguous:
- anonymous because there is no declaration name for the type structure
- anonymous because there is no parent field name to access the structures fields.

For me "Named" doesn't seem to hurt anything, but it doesn't seem to add anything either.

Code: Select all

   Named  Named   Occupies
   Type   Field   Space       What is it?
   -----  ------  ---------   --------------
0  no     no      no          n/a          
1  no     no      yes         anonymous inner type
2  no     yes     no          n/a          
3  no     yes     yes         not supported
4  yes    no      no          named nested type
5  yes    no      yes         n/a
6  yes    yes     no          n/a
7  yes    yes     yes         field
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Nested Types and Unions

Post by fxm »

Or "nested named type" and "inner anonymous type" ?

Elsewhere in the documentation it is also referred to "unnamed type" versus "named type" ?
For an average user, it would be easier to talk about "nested type" which can be either a "named type" or a "unnamed type".
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Nested Types and Unions

Post by coderJeff »

"Nested Named Type" is a good descriptor for the new feature discussed.

We need not necessarily follow c++ terminology, but it has some specific meanings:

Code: Select all

   Named  Named   Occupies
   Type   Field   Space       What is it?
   -----  ------  ---------   --------------
1  no     no      yes         anonymous type (supported by fb)
3  no     yes     yes         unnamed type (unsupported by fb)
4  yes    no      no          named type (supported by fb)
7  yes    yes     yes         field (supported by fb)
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Nested Types and Unions

Post by fxm »

So let's go for "Nested Named Type" and "Nested Anonymous Type" ?
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Nested Types and Unions

Post by coderJeff »

fxm wrote: Oct 16, 2022 19:31 So let's go for "Nested Named Type" and "Nested Anonymous Type" ?
Sounds good to me.
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Nested Types and Unions

Post by fxm »

The new page "TYPE (Nested)" (named or anonymous type) will must also contain the description for "UNION (Nested)" (I do not see the point of writing 2 separate pages).
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Nested Types and Unions

Post by coderJeff »

fxm wrote: Oct 16, 2022 20:28 The new page "TYPE (Nested)" (named or anonymous type) will must also contain the description for "UNION (Nested)" (I do not see the point of writing 2 separate pages).
That seems ok to me. Mostly everything you can do in a named TYPE|UNION can also be done in a nested named TYPE|UNION. I suppose it could be in the programmer's guide instead? The feature is not 100% finished so I thought it might be a good idea on a separate keyword page so that any differences could be shown separately.



----
Purpose for this feature and what it does ...

The main purpose of nested named types is to allow the author to express relationships between TYPEs in a manner that is comprehensible. A TYPE has it's own namespace in which to organize related symbols and offers visibility access (public:/protected:/private:) to give finer grain control over access to members.

I have used some patterns over the years to try and protect myself from myself due to typos or bad use of procedures but they have drawbacks as well. Without nested named types, relationships can still be expressed between TYPEs but have the disadvantage that all TYPEs must be publicly accessible. Use of NAMESPACEs can help organize scope of visibility but the problem remains that *all* TYPEs must be visible. In some situations this allows a user (or the author themselves) to inadvertently use a TYPE in a way that it was never intended, potentially creating valid yet error prone code. This problem can be reduced by hiding TYPEs through of forward typedefs and putting private symbols in a separate module however creates new problems by fragmenting the code.

Here's an example of what we are trying to do with nested named types.
It is the declaration only but gives a few interesting things to point out.

Code: Select all

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 = cast(any 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
angros47
Posts: 2321
Joined: Jun 21, 2005 19:04

Re: Nested Types and Unions

Post by angros47 »

Actually, another possible purpose for nested types is interfacing with nested classes in C++, since the name mangling for nested class is different and it cannot be replicated without them.

In my FLTK headers, in some files (Fl_Device.bi and Fl_Text_Display.bi) I encountered that problem (some methods belonging to a nested class), and the only solution I found out was to mangle their name manually, and building a "reverse-wrapper" function: it works, but it's extremely ugly to see. Nested types should make that unnecessary.
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Nested Types and Unions

Post by fxm »

I only introduced the two Nested Type/Union kinds ('Nested Anonymous Type/Union', and 'Nested Named Type/Union') in the two already existing pages (TYPE and UNION):
- KeyPgType → fxm [added Nested Named Type/Union capability]
- KeyPgUnion → fxm [added Nested Named Type/Union capability]

The new dedicated page TYPE (Nested) will be added later if needed (otherwise, just examples to be added in the two existing pages).
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Nested Types and Unions

Post by fxm »

Problem with static member variable in a Nested Named Type ?

That only works if static member variables are also declared in all Types that nest this Type.
Is it normal ?

Example that works:

Code: Select all

Type T1
    Dim As Integer I
    Type T2
        Dim As Integer J
        Type T3
            Dim As Integer K
            Static As Integer X
        End Type
        Static As Integer Y
    End Type
    Static As Integer Z   
End Type
Dim As Integer T1.T2.T3.X = 1
Dim As Integer T1.T2.Y = 2
Dim As Integer T1.Z = 3

Print T1.T2.T3.X
Print T1.T2.Y
Print T1.Z

Example that does not work:

Code: Select all

Type T1
    Dim As Integer I
    Type T2
        Dim As Integer J
        Type T3
            Dim As Integer K
            Static As Integer X
        End Type
''        Static As Integer Y
    End Type
    Static As Integer Z   
End Type
Dim As Integer T1.T2.T3.X = 1
''Dim As Integer T1.T2.Y = 2
Dim As Integer T1.Z = 3

Print T1.T2.T3.X
'Print T1.T2.Y
Print T1.Z
...\FBIDETEMP.bas(13) error 131: Declaration outside the original namespace, before '.' in 'Dim As Integer T1.T2.T3.X = 1'

Other example that does not work:

Code: Select all

Type T1
    Dim As Integer I
    Type T2
        Dim As Integer J
        Type T3
            Dim As Integer K
            Static As Integer X
        End Type
        Static As Integer Y
    End Type
''    Static As Integer Z   
End Type
Dim As Integer T1.T2.T3.X = 1
Dim As Integer T1.T2.Y = 2
''Dim As Integer T1.Z = 3

Print T1.T2.T3.X
Print T1.T2.Y
'Print T1.Z
...\FBIDETEMP.bas(13) error 4: Duplicated definition, T1 in 'Dim As Integer T1.T2.T3.X = 1'
...\FBIDETEMP.bas(14) error 4: Duplicated definition, T1 in 'Dim As Integer T1.T2.Y = 2'



But no problem with static member procedure in a Nested Named Type:

Code: Select all

Type T1
    Dim As Integer I
    Type T2
        Dim As Integer J
        Type T3
            Dim As Integer K
            Declare Static Sub test()
        End Type
    End Type
End Type

Sub T1.T2.T3.test()
    Print "T1.T2.T3.test()"
End Sub

T1.T2.T3.test()


[edit]
OK now, after the changes.
Last edited by fxm on Oct 26, 2022 4:54, edited 2 times in total.
Reason: Update after fbc changes.
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Nested Types and Unions

Post by fxm »

Everything else (other than static member variable) seems to work for Nested Named Types:
- non static member variable: OK
- static member variable: NOK
- non static member procedure: OK
- static member procedure: OK
- member property: OK
- member bitfield: OK
- member initializer: OK
- operator let: OK
- operator cast: OK
- constructor: OK
- destructor: OK
- non static member object (dynamic array of UDT with constructor/destructor): OK
- inheritance: OK
- virtual/abstract procedure: OK
- polymorphism: OK




[edit]
- static member variable: NOK => - static member variable: OK
OK now, after the changes.
Last edited by fxm on Oct 27, 2022 15:33, edited 1 time in total.
Reason: Update after fbc changes.
Post Reply