Page 1 of 1

Change the way UseModule checks for ambiguity

Posted: Sun Jun 30, 2013 8:34 pm
by luis
As a remainder in the appropriate section + example.


http://www.purebasic.fr/english/viewtop ... 57#p415657
fred wrote:for now it raises an error if one function collide. But we could change that to raise the error when the ambiguous function is called, so you have to choose the right one for this case.


Example:

Code: Select all

 Procedure hello()
  Debug "external hello"
 EndProcedure

DeclareModule test
 Declare one()
 Declare two()
 Declare hello()
EndDeclareModule

Module test
 Procedure one()
  Debug "one"
 EndProcedure

 Procedure two()
  Debug "two"
 EndProcedure

 Procedure hello()
  Debug "module's hello"
 EndProcedure
EndModule

hello()

; the line below would cause the compiler to raise an error
; UseModule test 

; we can solve the problem only this way for now

test::one()

test::two()

test::hello()
In the example above, it's impossible to use UseModule because the compiler would raise an error on the line "UseModule test" since it finds another "hello()" clashing with the "hello()" inside the module.

Making the compiler to raise the error only if we try to invoke in an ambiguous way the "hello()" procedure (and not before just assuming we could do it) we have more freedom:

Code: Select all

 Procedure hello()
  Debug "external hello"
 EndProcedure

DeclareModule test
 Declare one()
 Declare two()
 Declare hello()
EndDeclareModule

Module test
 Procedure one()
  Debug "one"
 EndProcedure

 Procedure two()
  Debug "two"
 EndProcedure

 Procedure hello()
  Debug "module's hello"
 EndProcedure
EndModule

hello()

UseModule test ; compiler keeps silent for now, maybe we will not call the module's "hello()" ... it waits

one() ; no problem

two() ; no problem 

; the "hello()" below would cause the compiler to raise an error

; hello()  

test::hello() ; we resolve the conflict using "::" and we don't lose the ability to use "UseModule" just for a single problematic procedure
Thanks

Re: Change the way UseModule checks for ambiguity

Posted: Sun Jun 30, 2013 10:21 pm
by BorisTheOld
FreeBasic gets around this problem by putting everything that's not in a Module (Namespace) into a unnamed default global module. Because this global area is unnamed, the module prefix is blank.

In PB notation, all items in the unnamed global module are referenced as ::ItemName from within named modules. This methodology is bullet proof and easy to comprehend.

Using your example, calling "hello()" from within "test" would always execute the local version.

To call the global version from within "test" you would use "::hello()"

To call the global version from the global area you would use "hello()"

And to call the version in "test" from the global area you would use "test::hello()"

Re: Change the way UseModule checks for ambiguity

Posted: Sun Jun 30, 2013 10:26 pm
by luis
I tried to push something of that kind here -> http://www.purebasic.fr/english/viewtop ... 15#p415615

See bottom of the first post.

I'm trying to fallback grasping what I can before the bouncer has completely thrown me out the door. :shock:

Using ::procname to solve conflicts at the top level like in my example also would be useful.
I can see why doing that from inside a module could be not well received though.
If you start to call global objects from inside a module, it loses quickly its "black box self-sufficient" status.
Calling other modules can make sense, but maybe global "top-level" objects should be avoided if possible.

EDIT: well just found out in some case it's hard to avoid it. So having "::obj_name" would be indeed not just useful, but VERY useful.

Re: Change the way UseModule checks for ambiguity

Posted: Mon Jul 01, 2013 1:15 am
by BorisTheOld
The interesting thing about modules is that it starts one thinking about overall program structure and functional units. The fact that it removes some of the burden of item naming is just an added bonus.

Not everything in an application can reside in a module -- some of it must be "global" in order to boot the application. We display the main window and process the message loop. Everything else is in modules. Actually, we use classes, but the idea is the same.

Nothing in the application mainline is visible to the modules. Any code or data that needs to be shared is isolated in a series of service modules. We have one service module that provides services common to all our applications, one that is specific to the application, and several that provide services such as printer and file support. But in total, this shared code accounts for less than one percent of an application.

Each major part of an application is a module. Typically, each menu item links to a module that handles a window and all its functionality. Other non-gui modules handle all the grunt work, such as generating reports -- one module per report.

With this kind of structure it's not necessary for PB to support an unnamed global module, since all the working code is in modules. Therefore, the current "ModuleName::ItemName" usage is all that's required. Which won't be a burden, because very little inter-module communication is needed. Most of the modules in our applications have a single "visible" entry point.

By the way, with this approach, even the UseModule feature is redundant.

Re: Change the way UseModule checks for ambiguity

Posted: Mon Jul 01, 2013 9:40 am
by User_Russian
BorisTheOld wrote:In PB notation, all items in the unnamed global module are referenced as ::ItemName from within named modules. This methodology is bullet proof and easy to comprehend.
I agrees.
For example, it is now the this only way to access a constant #PB_Editor_CreateExecutable.

Code: Select all

DeclareModule x
  
EndDeclareModule

Module x
  CompilerIf ::#PB_Editor_CreateExecutable
    
  CompilerEndIf
EndModule