Study of symbol lookups in namespaces and types

Forum for discussion about the documentation project.
Post Reply
Xusinboy Bekchanov
Posts: 783
Joined: Jul 26, 2018 18:28

Re: Study of symbol lookups in namespaces and types

Post by Xusinboy Bekchanov »

coderJeff wrote: Btw, this discussion is all based on a specific case of usage in your source code. Where the source is intentionally putting same named symbols in one scope (like Rect and Left). Why do that in the first place?
Rect is not that important to me anymore.
With the new changes, I have to choose between two options:
1) use both: 1 ..Left for string, 2. Component.Left (..Left doesn't look basic). Then with my library in events I always have to use ..Left, because Form inherits from Component (Sub Form1.CommandButton1_Click, Sub Form1.CheckBox1_Click, ...).
2) Remove the Component.Left property and use Left for the string.

This is not such a big problem. The topic can be closed.
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Study of symbol lookups in namespaces and types

Post by coderJeff »

Xusinboy Bekchanov wrote:This is not such a big problem. The topic can be closed.
It's important. I will keep working on it.

I'm looking for someone that is willing to take time and discuss it; to look at the general cases; the overall view; help form the solution. I'm probably asking too much.
fxm
Moderator
Posts: 12084
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Study of symbol lookups in namespaces and types

Post by fxm »

The current name look-ups for fbc 1.09 seems to verify the priority hierarchy as follows:
- (1) current namespace/type
- (2) parent namespace
- (3) import namespace (by using), or base type (by extends)
- (4) global namespace
(for fbc 1.08, (3) and (4) priority order is swapped)

This is true for procedure names, variable names, type names, ...

a) Test examples for Procedure names and fbc 1.09
  • Procedure name test example for fbc 1.09 and priority (1):
    - (1) current namespace/type
    - (2) parent namespace
    - (3) import namespace (by using), or base type (by extends)
    - (4) global namespace

    Code: Select all

    '  (1) current namespace/type
    '  (2) parent namespace
    '  (3) import namespace (by using), or base type (by extends)
    '  (4) global namespace
    
    Sub duplicate()
        Print "..duplicate()"
    End Sub
    
    Namespace M
        Sub duplicate()
            Print "M.duplicate()"
        End Sub
    End Namespace
    
    Namespace N
        Sub duplicate()
            Print "N.duplicate()"
        End Sub
        Type Parent Extends object
            Declare Sub Duplicate()
        End Type
        Type Child Extends Parent
            Declare Sub Duplicate()
            Declare Sub test()
        End Type
    End Namespace
    
    Sub N.Parent.duplicate()
        Print "N.Parent.duplicate()"
    End Sub
    Sub N.Child.duplicate()
        Print "N.Child.duplicate()"
    End Sub
    Sub N.Child.test()
        Using M
        duplicate()
    End Sub
    
    Dim As N.Child c
    c.test()           '' "N.Child.duplicate()" : (1) current namespace/type
    
    Procedure name test example for fbc 1.09 and priority (2):
    - (1) current namespace/type
    - (2) parent namespace
    - (3) import namespace (by using), or base type (by extends)
    - (4) global namespace

    Code: Select all

    '  (1) current namespace/type
    '  (2) parent namespace
    '  (3) import namespace (by using), or base type (by extends)
    '  (4) global namespace
    
    Sub duplicate()
        Print "..duplicate()"
    End Sub
    
    Namespace M
        Sub duplicate()
            Print "M.duplicate()"
        End Sub
    End Namespace
    
    Namespace N
        Sub duplicate()
            Print "N.duplicate()"
        End Sub
        Type Parent Extends object
            Declare Sub Duplicate()
        End Type
        Type Child Extends Parent
    '        Declare Sub Duplicate()
            Declare Sub test()
        End Type
    End Namespace
    
    Sub N.Parent.duplicate()
        Print "N.Parent.duplicate()"
    End Sub
    'Sub N.Child.duplicate()
    '    Print "N.Child.duplicate()"
    'End Sub
    Sub N.Child.test()
        Using M
        duplicate()
    End Sub
    
    Dim As N.Child c
    c.test()          '' "N.duplicate()" : (2) parent namespace
    
    Procedure name test example for fbc 1.09 and priority (3):
    - (1) current namespace/type
    - (2) parent namespace
    - (3) import namespace (by using), or base type (by extends)
    - (4) global namespace

    Code: Select all

    '  (1) current namespace/type
    '  (2) parent namespace
    '  (3) import namespace (by using), or base type (by extends)
    '  (4) global namespace
    
    Sub duplicate()
        Print "..duplicate()"
    End Sub
    
    Namespace M
        Sub duplicate()
            Print "M.duplicate()"
        End Sub
    End Namespace
    
    Namespace N
    '    Sub duplicate()
    '        Print "N.duplicate()"
    '    End Sub
        Type Parent Extends object
            Declare Sub Duplicate()
        End Type
        Type Child Extends Parent
    '        Declare Sub Duplicate()
        Declare Sub test()
        End Type
    End Namespace
    
    Sub N.Parent.duplicate()
        Print "N.Parent.duplicate()"
    End Sub
    'Sub N.Child.duplicate()
    '    Print "N.Child.duplicate()"
    'End Sub
    Sub N.Child.test()
        Using M
        duplicate()
    End Sub
    
    Dim As N.Child c
    c.test()          '' ambiguity between "M.duplicate()"        : (3) import namespace (by using)
                      ''               and "N.Parent.duplicate()" : (3) base type (by extends)
    
    Procedure name test example for fbc 1.09 and priority (4):
    - (1) current namespace/type
    - (2) parent namespace
    - (3) import namespace (by using), or base type (by extends)
    - (4) global namespace

    Code: Select all

    '  (1) current namespace/type
    '  (2) parent namespace
    '  (3) import namespace (by using), or base type (by extends)
    '  (4) global namespace
    
    Sub duplicate()
        Print "..duplicate()"
    End Sub
    
    Namespace M
    '    Sub duplicate()
    '        Print "M.duplicate()"
    '    End Sub
    End Namespace
    
    Namespace N
    '    Sub duplicate()
    '        Print "N.duplicate()"
    '    End Sub
        Type Parent Extends object
    '        Declare Sub Duplicate()
        End Type
        Type Child Extends Parent
    '        Declare Sub Duplicate()
            Declare Sub test()
        End Type
    End Namespace
    
    'Sub N.Parent.duplicate()
    '    Print "N.Parent.duplicate()"
    'End Sub
    'Sub N.Child.duplicate()
    '    Print "N.Child.duplicate()"
    'End Sub
    Sub N.Child.test()
        Using M
        duplicate()
    End Sub
    
    Dim As N.Child c
    c.test()          '' "..duplicate()" : (4) global namespace
    
b) Test examples for Variable names and fbc 1.09
  • Variable name test example for fbc 1.09 and priority (1):
    - (1) current namespace/type
    - (2) parent namespace
    - (3) import namespace (by using), or base type (by extends)
    - (4) global namespace

    Code: Select all

    '  (1) current namespace/type
    '  (2) parent namespace
    '  (3) import namespace (by using), or base type (by extends)
    '  (4) global namespace
    
    Dim Shared As String duplicate
    
    Namespace M
        Dim As String duplicate
    End Namespace
    
    Namespace N
        Dim As String duplicate
        Type Parent Extends object
            Dim As String duplicate = "N.Parent."
        End Type
        Type Child Extends Parent
            Dim As String duplicate = "N.Child."
            Declare Sub test()
        End Type
    End Namespace
    
    Sub N.Child.test()
        Using M
        Print duplicate
    End Sub
    
    duplicate = ".."
    M.duplicate = "M."
    N.duplicate = "N."
    
    Dim As N.Child c
    c.test()           '' "N.Child." : (1) current namespace/type
    
    Variable name test example for fbc 1.09 and priority (2):
    - (1) current namespace/type
    - (2) parent namespace
    - (3) import namespace (by using), or base type (by extends)
    - (4) global namespace

    Code: Select all

    '  (1) current namespace/type
    '  (2) parent namespace
    '  (3) import namespace (by using), or base type (by extends)
    '  (4) global namespace
    
    Dim Shared As String duplicate
    
    Namespace M
        Dim As String duplicate
    End Namespace
    
    Namespace N
        Dim As String duplicate
        Type Parent Extends object
            Dim As String duplicate = "N.Parent."
        End Type
        Type Child Extends Parent
    '        Dim As String duplicate = "N.Child."
            Declare Sub test()
        End Type
    End Namespace
    
    Sub N.Child.test()
        Using M
        Print duplicate
    End Sub
    
    duplicate = ".."
    M.duplicate = "M."
    N.duplicate = "N."
    
    Dim As N.Child c
    c.test()           '' "N." : (2) parent namespace
    
    Variable name test example for fbc 1.09 and priority (3):
    - (1) current namespace/type
    - (2) parent namespace
    - (3) import namespace (by using), or base type (by extends)
    - (4) global namespace

    Code: Select all

    '  (1) current namespace/type
    '  (2) parent namespace
    '  (3) import namespace (by using), or base type (by extends)
    '  (4) global namespace
    
    Dim Shared As String duplicate
    
    Namespace M
        Dim As String duplicate
    End Namespace
    
    Namespace N
    '    Dim As String duplicate
        Type Parent Extends object
            Dim As String duplicate = "N.Parent."
        End Type
        Type Child Extends Parent
    '        Dim As String duplicate = "N.Child."
            Declare Sub test()
        End Type
    End Namespace
    
    Sub N.Child.test()
        Using M
        Print duplicate
    End Sub
    
    duplicate = ".."
    M.duplicate = "M."
    'N.duplicate = "N."
    
    Dim As N.Child c
    c.test()          '' ambiguity between "M.duplicate"        : (3) import namespace (by using)
                      ''               and "N.Parent.duplicate" : (3) base type (by extends)
    
    Variable name test example for fbc 1.09 and priority (4):
    - (1) current namespace/type
    - (2) parent namespace
    - (3) import namespace (by using), or base type (by extends)
    - (4) global namespace

    Code: Select all

    '  (1) current namespace/type
    '  (2) parent namespace
    '  (3) import namespace (by using), or base type (by extends)
    '  (4) global namespace
    
    Dim Shared As String duplicate
    
    Namespace M
    '    Dim As String duplicate
    End Namespace
    
    Namespace N
    '    Dim As String duplicate
        Type Parent Extends object
    '        Dim As String duplicate = "N.Parent."
        End Type
        Type Child Extends Parent
    '        Dim As String duplicate = "N.Child."
            Declare Sub test()
        End Type
    End Namespace
    
    Sub N.Child.test()
        Using M
        Print duplicate
    End Sub
    
    duplicate = ".."
    'M.duplicate = "M."
    'N.duplicate = "N."
    
    Dim As N.Child c
    c.test()          '' ".." : (4) global namespace
    
I performed similar tests from the current namespace (instead of the current type).
I performed similar tests with type names (instead of procedure names or variable names).
I performed similar tests with fbc 1.08 (instead of fbc 1.09) to check that (3) and (4) priority order is swapped.
fxm
Moderator
Posts: 12084
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Study of symbol lookups in namespaces and types

Post by fxm »

fxm wrote:The current name look-ups for fbc 1.09 seems to verify the priority hierarchy as follows:
- (1) current namespace/type
- (2) parent namespace
- (3) import namespace (by using), or base type (by extends)
- (4) global namespace
I propose to distinguish the case "import namespace (by using)" from the case "base type (by extends)", with "base type (by extends)" more priority than "parent namespace".

So I would suggest proposing first that the new name look-ups for fbc 1.09 verifies the priority hierarchy as follows:
- (1) current namespace/type
- (2) base type (by extends)
- (3) parent namespace
- (4) import namespace (by using)
- (5) global namespace
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Study of symbol lookups in namespaces and types

Post by coderJeff »

fxm wrote:I performed similar tests from the current namespace (instead of the current type).
I performed similar tests with type names (instead of procedure names or variable names).
I performed similar tests with fbc 1.08 (instead of fbc 1.09) to check that (3) and (4) priority order is swapped.
Thank-you. Your examples are very helpful. The recent changes were to improve TYPES, but have had poor effects on NAMESPACEs.

Under the hood, there is only one mechanism for dealing with symbol lookups. I believe what I see emerging here is that symbols for TYPEs and NAMESPACEs can't be handled the same way.

1) For example, this hasn't changed in a NAMESPACE between fbc-1.08 and fbc-1.09, and I believe is incorrect - a current bug.

Code: Select all

namespace P
	dim A as integer
end namespace

namespace C
	using P
end namespace

? P.A
? C.A '' <<<--- this should not be allowed
2) Similar to 1) above but makes sense for TYPEs

Code: Select all

type P extends object
	dim A as integer
end type

type C extends P
	'' implicit 'using P'
end type

dim x as P, y as C

? x.A
? y.A '' <<--- OK
3) Here is another NAMESPACE example showing change from fbc-1.08

Code: Select all

dim shared A as integer = 1

namespace P

	sub proc()
		? A  '' 1
	end sub

	namespace C1
		dim A as integer = 2
		sub proc()
			? A  '' 2
		end sub
	end namespace

	namespace C2
		using C1
		sub proc()
			? A  '' 2 <<-- wrong for namespaces
		end sub
	end namespace

	namespace C3
		sub proc()
			? A  '' 1 <<-- correct for namespaces
		end sub
	end namespace

end namespace

P.proc()
P.C1.proc()
P.C2.proc()
P.C3.proc()
4) And similar to 3) above but for TYPES, showing the change from fbc-1.08

Code: Select all

dim shared A as integer = 1

type P extends object
	declare sub proc()
end type

sub P.proc()
	? A  '' 1
end sub

type C1 extends P
	'' implicit 'using P'
	dim A as integer = 2
	declare sub proc()
end type

sub C1.proc()
	? A  '' 2  
end sub

type C2 extends C1
	'' implicit 'using C1'
	declare sub proc()
end type

sub C2.proc()
	? A  '' 2  <<--- correct for types
end sub

type C3 extends P
	'' implicit 'using P'
	declare sub proc()
end type

sub C3.proc()
	? A  '' 1  <<--- still bugged for types
end sub

dim w as P, x as C1, y as C2, z as C3

w.proc()
x.proc()
y.proc()
z.proc()
So, what this means is I can't just make improvements to our 'lookup' function. I believe the symbol table needs some information added about how the symbol was imported. Well, the information is there, it's just not in a structure that is efficient to work with at the moment.
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Study of symbol lookups in namespaces and types

Post by coderJeff »

fxm wrote:I propose to distinguish the case "import namespace (by using)" from the case "base type (by extends)", with "base type (by extends)" more priority than "parent namespace".
Yes, excellent. I also think this is needed.
fxm
Moderator
Posts: 12084
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Study of symbol lookups in namespaces and types

Post by fxm »

By referring to your two last examples 3) and 4)

fbc1.09 and example 3)
1
2
2
1

fbc 1.09 and example 4)
1
2
2
1

fbc1.08 and example 3)
1
2
1
1

fbc 1.08 and example 4)
1
2
1
1

From my point of view, 3) and 4) results are correct for fbc 1.09.

Example 2) : It's OK

Example 3) : It's NOK ???
marcov
Posts: 3455
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: Study of symbol lookups in namespaces and types

Post by marcov »

fxm wrote:
So I would suggest proposing first that the new name look-ups for fbc 1.09 verifies the priority hierarchy as follows:
- (1) current namespace/type
- (2) base type (by extends)
- (3) parent namespace
- (4) import namespace (by using)
- (5) global namespace
But if a symbol is marked overload, also search deeper ?
fxm
Moderator
Posts: 12084
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Study of symbol lookups in namespaces and types

Post by fxm »

fxm wrote:Example 3) : It's NOK ???
After reflection, I think we can consider that all these syntaxes are valid:

Code: Select all

namespace P
   dim A as integer
end namespace

namespace C
    using P
    sub proc()
        ? A
    end sub
end namespace

? P.A

c.proc()

? C.A     '' namespace C imports namespace P

using C   '' inport C that imports P
? A
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Study of symbol lookups in namespaces and types

Post by coderJeff »

fxm wrote:Example 3) : It's NOK ???
I think it's not OK.

Code: Select all

dim shared A as integer = 1

namespace N
	dim A as integer = 2
end namespace

using N

print A  '' 1
In above and example 3), ..A is directly reachable without resorting to checking imports. I think logic should be similar inside nested namespaces .

I messed up on example 4, so my comments are wrong. I was trying to show both an improvement and the remaining bug of https://sourceforge.net/p/fbc/bugs/948/ at the same time. But it didn't work out.
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Study of symbol lookups in namespaces and types

Post by coderJeff »

fxm wrote:After reflection, I think we can consider that all these syntaxes are valid:
I'm not sure about that. It's almost like should be looking for something like:

Code: Select all

namespace A
  dim x as integer
end namespace
namespace B
  dim y as integer
end namespace
namespace N
    public using A
    private using B
end namespace

using N
? x '' OK
? y '' NOK
fxm
Moderator
Posts: 12084
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Study of symbol lookups in namespaces and types

Post by fxm »

marcov wrote:
fxm wrote:
So I would suggest proposing first that the new name look-ups for fbc 1.09 verifies the priority hierarchy as follows:
- (1) current namespace/type
- (2) base type (by extends)
- (3) parent namespace
- (4) import namespace (by using)
- (5) global namespace
But if a symbol is marked overload, also search deeper ?
In the single scope (if no ambiguity) retained after a procedure name look-up, then, an overload resolution is applied in addition if necessary.
fxm wrote:I think that coding such a resolution process (the best from human intelligence) is cumbersome, because from the start having to take into account the complete signature of the called procedure (symbol name + type and number of parameters + calling convention + return type if it exists).
In addition, it must be taken into account that the signature deduced from the call may not necessarily be identical but just compatible with those declared.

I think the current process (similar to the one of C ++ for example) simplifies the problem by dealing with it in two successive phases:
- selection of a single scope among all those which are accessible by only taking into account the symbol name regardless of the arguments supplied by the caller (if at least two scopes containing the symbol name have equivalent accessibility priority => ambiguity).
- within this single scope retained, one final overload resolution taking into account the full signature.

The problem is thus simplified to one single full overload resolution within a same scope (instead of a full overload resolution within each scope candidate, and then the difficult choice of the best result among the scope candidates).
Such a process uses the principle of 'name hiding'.
fxm
Moderator
Posts: 12084
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Study of symbol lookups in namespaces and types

Post by fxm »

coderJeff wrote: I think it's not OK.

Code: Select all

dim shared A as integer = 1

namespace N
	dim A as integer = 2
end namespace

using N

print A  '' 1
I consider this following as OK ('dim A as integer = 1' and 'print A' in the same scope):

Code: Select all

dim A as integer = 1

namespace N
   dim A as integer = 2
end namespace

using N

print A  '' 1
Why by adding 'Shared' in the first declaration should modify the behavior ?
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Study of symbol lookups in namespaces and types

Post by coderJeff »

@fxm, I will read your posts carefully. I've been thinking about this lookup problem for many days now and I think I need to reset to some kind of starting point.
marcov
Posts: 3455
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: Study of symbol lookups in namespaces and types

Post by marcov »

fxm wrote:
coderJeff wrote: I think it's not OK.

Code: Select all

dim shared A as integer = 1

namespace N
	dim A as integer = 2
end namespace

using N

print A  '' 1
I consider this following as OK ('dim A as integer = 1' and 'print A' in the same scope):
Using is done after the definitions, so its scopes are on the scope stack before older definitions.

But more logical would be to require using to be valid only at the top.
Post Reply