Modules and name clashing.

Just starting out? Need help? Post your questions and find answers here.
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Modules and name clashing.

Post by luis »

I'm trying to see how PB modules works.
Suppose you write a lib in source form using modules, and when the user of your lib includes it in his main project there is some name clashing.

Example of a worst case scenario:

Code: Select all

Procedure func()
 Debug "main"
EndProcedure

DeclareModule lib1
 #test_const = 111
 
 Declare func(par)
EndDeclareModule

Module lib1
 Procedure func(par)
  Debug "lib1 func:" + par  
 EndProcedure
EndModule

DeclareModule lib2
 #test_const = 222
 
 Declare func(par)
EndDeclareModule

Module lib2
 Procedure func(par)
  Debug "lib2 func:" + par  
 EndProcedure
EndModule

lib1::func(lib1::#test_const)

lib2::func(lib2::#test_const)

func()
The user want to use a lib1 made from you, a lib2 made from someone else, and inside his project he has a function "func()" clashing twice: with lib1 and lib2.

It seem (if I'm not missing something) right now the only option (apart changing some of the sources OBVIOUSLY please don't suggest that) is to use the fully qualified name for everything, as I did above.

This can be ok if you have not much to call, but imagine if it's not the case.

Couldn't be partially solved accepting this code (currently not compilable because raises an error) ?

Code: Select all

Procedure func()
 Debug "main"
EndProcedure

DeclareModule lib1
 #test_const = 111
 
 Declare func(par)
EndDeclareModule

Module lib1
 Procedure func(par)
  Debug "lib1 func:" + par  
 EndProcedure
EndModule

DeclareModule lib2
 #test_const = 222
 
 Declare func(par)
EndDeclareModule

Module lib2
 Procedure func(par)
  Debug "lib2 func:" + par  
 EndProcedure
EndModule

; all the above is identical

UseModule lib1 ; don't raise an error anymore here
func(#test_const) ; and here call the func in the only matching module instead

UseModule lib2 ; now the matching modules would be two... potential problem
lib2::func(lib2::#test_const) ; but not if I fully qualify it (or close the previous module before, I can choose)

::func() ; I want to call the global func(), so I just prepend "::" to it
In many circumstances this could end up in a lot of less typing, by choosing wisely the best path.

Just thinking out loud, and considering probably it's still a GOOD idea to use prefix like lib1_func() etc, even when using modules.

Comments about all this ?

EDIT: corrected a typo
Last edited by luis on Sat Jun 22, 2013 8:00 pm, edited 1 time in total.
"Have you tried turning it off and on again ?"
A little PureBasic review
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Modules and name clashing.

Post by Little John »

As far as I can see at the moment, I think UseModule maybe better should not be introduced into PB 5.20 final. Much better IMHO would be, to allow With with modules:

Code: Select all

Procedure func()
   Debug "main"
EndProcedure

DeclareModule lib1
   #test_const = 111
   
   Declare func(par)
EndDeclareModule

Module lib1
   Procedure func(par)
      Debug "lib1 func:" + par 
   EndProcedure
EndModule

DeclareModule lib2
   #test_const = 222
   
   Declare func(par)
EndDeclareModule

Module lib2
   Procedure func(par)
      Debug "lib2 func:" + par 
   EndProcedure
EndModule

;--- all the above code is identical to Luis' code ---

With lib1
   ::func(::#test_const)
EndWith

With lib2
   ::func(::#test_const)
EndWith

func()
Using With, we can also save some typing, and the code IMHO is much clearer and better readable than with using UseModule. And the concept and meaning of With is already familiar to all PB users with a certain level of experience.

See also this feature request.
User_Russian
Addict
Addict
Posts: 1519
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

Re: Modules and name clashing.

Post by User_Russian »

Little John, Then it will be not possible to connect multiple modules

Code: Select all

DeclareModule lib1
   #test_const = 111
   
   Declare func(par)
EndDeclareModule

Module lib1
   Procedure func(par)
      Debug "lib1 func:" + par 
   EndProcedure
EndModule

DeclareModule lib2
   #test_const_1 = 222
   
   Declare func1(par)
EndDeclareModule

Module lib2
   Procedure func1(par)
      Debug "lib2 func:" + par 
   EndProcedure
 EndModule
 
UseModule lib1
UseModule lib2

func(#test_const)
func1(#test_const_1)
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: Modules and name clashing.

Post by freak »

There is also a HideModule command which closes the module again. Then you can open another one.

Actually, if you have two modules with the same procedure in their declaration, I would strongly advice to always call the procedure with the fully qualified name. Otherwise your code will become very hard to read and manage because you never know which procedure you are calling without looking at the context. Even worse: By moving the call to a different place in the code you might end up calling a diffferent procedure!

The UseModule command is meant for the cases where there is no ambiguity and therefore taking the shortcut to remove the module prefix is not a problem. If there is possible cause for confusion, using the full names will make your life easier. :wink:
quidquid Latine dictum sit altum videtur
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Modules and name clashing.

Post by Little John »

freak wrote:There is also a HideModule command which closes the module again. Then you can open another one.

Actually, if you have two modules with the same procedure in their declaration, I would strongly advice to always call the procedure with the fully qualified name. Otherwise your code will become very hard to read and manage because you never know which procedure you are calling without looking at the context. Even worse: By moving the call to a different place in the code you might end up calling a diffferent procedure!

The UseModule command is meant for the cases where there is no ambiguity and therefore taking the shortcut to remove the module prefix is not a problem. If there is possible cause for confusion, using the full names will make your life easier. :wink:
As far as I can see, using With / EndWith would have the same advantages as UseModule / HideModule, but without its potential disadvantages, no? :-)
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: Modules and name clashing.

Post by freak »

Your "With" syntax would require to write the "::" prefix everywhere. I don't like that very much.

As I said, opening/closing modules frequently is not a good idea anyway. If you look around how people use modules in other languages you see the same as well: There is usually just a block of "using" (or similar) keywords at the top of the code that import the needed modules and then they are never closed again. Either a module is fully imported or it is just referenced with the module prefix. A mix is not a good idea imho.

This is why the keyword is called "UseModule" and not "OpenModule": Opening something implies that it needs to be closed after use. But that is not the common use case here. You can just "use" the module and never "unuse" it. If you really want to though you can do it. That is what HideModule is for.
quidquid Latine dictum sit altum videtur
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Modules and name clashing.

Post by luis »

freak wrote: Actually, if you have two modules with the same procedure in their declaration, I would strongly advice to always call the procedure with the fully qualified name.
I see what you mean... unfortunately that's a lot of typing, especially if not only procedures but constants too are involved... (see 1st post) but I think I agree, especially since my idea would indeed make the code more "context" dependent.
freak wrote: Otherwise your code will become very hard to read and manage because you never know which procedure you are calling without looking at the context. Even worse: By moving the call to a different place in the code you might end up calling a diffferent procedure!
Since this is something that can easily happen especially if your module is used by different people, what do you think about what I wrote above:
luis wrote:Just thinking out loud, and considering probably it's still a GOOD idea to use prefix like lib1_func() etc, even when using modules.
?

Probably better this than a situation like the one I showed in my first post. That's the point I would have liked to have some feedback about.

I'm oriented towards this kind of solution, and I would like to hear any reason stating this is overkill, if any. There is the fact I could simply use the full qualified name and so "move" the prefix to another place: instead of inside the name, before the "::".

I'm in doubt.


EDIT: I just saw the auto-complete does not honor the module name to filter the procedures names, so if if I write lib1::fun.... in reality it does match any fun*.*() anywhere.

This is another point in favor of using lib1_fun() as the name of procedures even if inside modules, to filter them easily and in a consistent way.
"Have you tried turning it off and on again ?"
A little PureBasic review
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Modules and name clashing.

Post by Fred »

You can also see the Modules like a way to a a new library in PureBasic: the functions you want to expose needs to be unique (even accross the whole PB commandset as you can't name a procedure the same than an internal command). To me it's better to remove the prefix and find function name which can works with UseModule, and if you import 2 modules with the same functions, then you need to prefix them. May be I will change the way UseModule checks the ambiguity: for now it raises an error if one function collide. But we could change that to raise the error when the ambigus function is called, so you have to choose the right one for this case. It should be more flexible.
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Modules and name clashing.

Post by luis »

Fred wrote:But we could change that to raise the error when the ambigus function is called, so you have to choose the right one for this case. It should be more flexible.
I think that would be nice, thanks.

Remains the fact autocomplete is not "module-aware" so for now I tend to be inclined to use a prefix in the name to solve this even if I would prefer to avoid it.

It's a lot useful to see only what it's pertinent to a specific library (module) and currently this doesn't seem possible not using a prefix.

Right ?
"Have you tried turning it off and on again ?"
A little PureBasic review
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: Modules and name clashing.

Post by BorisTheOld »

I can't see why people are having so much trouble with Modules -- they are a standard programming construct that everyone should know about.

A module is just a block of related code that is one level up from a procedure. A module contains one or more procedures, and some data, that can be considered as a "black box", in the same way that a class is a black box. And like a class, procedures and data in the module can be made visible to code outside the module.

Typically, modules are coded as Include files that are compiled right in the application, compared to a library which is precompiled for static or dynamic linking. And like libraries, it doesn't matter what names are used inside the modules, because nothing outside is aware of them.

Public names need to be uniquely identified, and this is done by prefixing the name with the module name:

ModuleName::ProcedureName
ModuleName::DataName

This is not rocket science.

And please, everyone, stop whining about having to type a few extra characters, or that the compiler should be able to read your mind.

Try to be professional.
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Modules and name clashing.

Post by luis »

@boristheold

I didn't learn anything from your post, since you are explaining something already understood, and I didn't get an answer to my question.

Did you try to understand the sense of the thread ?
Last edited by luis on Sun Jun 23, 2013 12:13 pm, edited 1 time in total.
"Have you tried turning it off and on again ?"
A little PureBasic review
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Modules and name clashing.

Post by Fred »

Autocomplete will be updated, but I don't see why you should code depending of your IDE features. What if you change your code editor, you will change you way of coding ?
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Modules and name clashing.

Post by luis »

Fred wrote:Autocomplete will be updated
Nice, thank you :wink:
Fred wrote:, but I don't see why you should code depending of your IDE features. What if you change your code editor, you will change you way of coding ?
Autocomplete for me it's so important (read: useful) it's just like a feature of the language. So if one editor give me an autocomplete "module-aware" and another one not, and I cannot use the first editor for some reason than YES, I would change the naming conventions to use the feature reduced autocomplete at the best of its possibilities, not losing the ability to filter only the procedures available in a specific module.

If autocomplete wouldn't be available in any form, then I wouldn't have to try to keep something I don't have.
Last edited by luis on Thu Mar 23, 2023 2:29 pm, edited 1 time in total.
"Have you tried turning it off and on again ?"
A little PureBasic review
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: Modules and name clashing.

Post by freak »

As Fred said, think of a module like a Library: As such, the public interface of a Module should be well designed with descriptive names and not export things that are not needed.

Example: If the Module is called "Animation", call the public function "CreateAnimation()" and not just "Create()". Yes, "Animation::Create()" tells you what you need to know, but on its own "Create()" could mean anything. And if you have two modules that create something you have a conflict. But if one module has a CreateAnimation() function and the other has a CreateGame() function then there is no conflict even if you use UseModule on both.

If you give the public function good names then the chance for an actual collision with the names is very low. Of course, if you export procedures like "proc()" and variables like "x" then you will run into conflicts very soon.

Of course this is just my opinion. You can as well use the module concept exactly so you can name the function Create() and not CreateAnimation(). But then in my opinion it is also better to use the fully qualified names rather than using UseModule. If the module name becomes part of the meaning of what the function does, then it should also be written on every call to make clear what the line is supposed to do.

Imho, these are the two styles that are useful with Modules
- give descriptive names that stand on their own, use UseModule and only write the full name to avoid (rare) conflicts
- give shorter names for simplicity inside the module and write the full name outside to keep the meaning of the call clear

Just my opinion of course.
quidquid Latine dictum sit altum videtur
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: Modules and name clashing.

Post by BorisTheOld »

freak wrote:Just my opinion of course.
Good suggestions.

Modules, like any other language features, are not a panacea for poor programming practices.

Sadly, many (most?) programmers don't understand the benefits of well designed, well structured, well documented, and well tested code.
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
Post Reply