Page 1 of 1

DeclareModule only, without a mandatory Module body.

Posted: Tue Feb 23, 2016 12:04 pm
by sys64802
I was playing with modules.

I find the fact we can't access a global constant from inside a module through a scope operator a silly idea.

But the requests to change this have been put down so I suppose asking for it again will not change it.

In case you change your mind, that's where my vote is really going and what follows will not be strictly required because it could simply be avoided.

In the meantime: if I want to configure a module at compile time, for example through conditional compilation to include or exclude different part of its code to customize it for various reasons, I have to declare a configuration module and reference it from inside my module (creating an external dependence anyway, so what's the point of preventing the access to the global constant, but let's forget about this).

If my module is called foo I could create a foo_config, something like this:

Code: Select all

DeclareModule foo_config
#magic_conf_option = 1
EndDeclareModule

Module foo
EndModule
The purpose of this is to let the user of the module (another programmer) to configure the module's internals at compile time without editing the module code, obviously.


Would you at least consider to remove the need to declare the empty module part and not raise an error like PB currently does and implicitly consider the definition of an empty module if missing ?

Code: Select all

DeclareModule foo_config
#magic_conf_option = 1
EndDeclareModule
This would make less ugly to define these modules configuration options, because the current full form hurt my eyes and my stomach, probably because it's a constant reminder of why I have to do this.

I don't want to use a (again ugly) macro to generate the empty module part to implement this for just myself locally or to have to distribute them if I want to share a module. Not even sure if it's possible since the macro may be not visible while it's trying to generate the code from inside the declaration it's building.
Anyway I would like this just to work natively. If I only need the declaration part, there is no reason to define the module part too.

Re: DeclareModule only, without a mandatory Module body.

Posted: Tue Feb 23, 2016 3:12 pm
by Justin
I agree not being able to access the global scope is a very bad design choice, i can not imagine why they did this. I you have some includes with helper functions or whatever you often use you can't not use it inside a module, the constants issue to configure the module is something i have always missed too.
But what is the point of preventing this? It only forces you to declare a common module and use it inside the other, it wouldn't be better to just access the global scope with some operator like it was suggested? and forget this mess? You can access PB functions and constants, why not access your own functions and constants?
Basically if you start with modules ALL your code or functions need to be in a module because you never know if you will need it inside another module.
Another thing i really miss is sharing private stuff between modules like it was also requested, so you can build modules one on top of the other, extending them.
Don't know what they were thinking not implementing this, really.

Re: DeclareModule only, without a mandatory Module body.

Posted: Tue Feb 23, 2016 3:28 pm
by wilbert
I don't see the scope problem.

Code: Select all

; foo_config module

DeclareModule foo_config
  #magic_conf_option = 1
EndDeclareModule

Module foo_config : EndModule


; foo module

DeclareModule foo
  Declare foo()
EndDeclareModule

Module foo
  
  CompilerSelect foo_config::#magic_conf_option
    CompilerCase 1
      Procedure foo()
        MessageRequester("Message", "Compiled with option 1")
      EndProcedure
    CompilerDefault
      Procedure foo()
        MessageRequester("Message", "Compiled with option other than 1")
      EndProcedure
  CompilerEndSelect  
  
EndModule


foo::foo()
If you change the config option, a different procedure is compiled in the foo module.

Re: DeclareModule only, without a mandatory Module body.

Posted: Tue Feb 23, 2016 3:38 pm
by sys64802
@wilbert, the request is to avoid the declaration of the empty module when you only need DeclareModule.

Code: Select all

Module foo_config : EndModule
It does not have a real use. It's ugly to see. Why is it there ? It does nothing.


About the scope problem. It should be not required to declare another module for nothing.
Again it serves no purpose.

Code: Select all

#foo_conf_option = 1


; foo module

DeclareModule foo
  Declare foo()
EndDeclareModule

Module foo
 
  CompilerSelect ::#foo_conf_option
    CompilerCase 1
      Procedure foo()
        MessageRequester("Message", "Compiled with option 1")
      EndProcedure
    CompilerDefault
      Procedure foo()
        MessageRequester("Message", "Compiled with option other than 1")
      EndProcedure
  CompilerEndSelect 
 
EndModule


foo::foo()

I would expect to configure my module with:

Code: Select all

#foo_conf_option = 1
instead of

Code: Select all

DeclareModule foo_config
  #foo_conf_option = 1
EndDeclareModule

Module foo_config : EndModule
The net effect is the same, one is just longer and uglier.

This is just one of the problems caused by the missing :: operator anyway.

Re: DeclareModule only, without a mandatory Module body.

Posted: Tue Feb 23, 2016 3:58 pm
by wilbert
I see your point now.
I can see both advantages and disadvantages.
One thing I like about modules is that they make it easier to share code because there are no conflicts.
The scope proposal could result in conflicts when the module is used by others.
Let's assume I find two string related modules on the forum I could use and both rely on a global constant #case_insensitive.
That way I can't configure them independently.

As for the real request in this thread, it would be nice if PB would only generate a warning message instead of an error message if no module part is added and still be able to compile the source.

Re: DeclareModule only, without a mandatory Module body.

Posted: Tue Feb 23, 2016 4:14 pm
by sys64802
wilbert wrote: Let's assume I find two string related modules on the forum I could use and both rely on a global constant #case_insensitive.
That way I can't configure them independently.
That's true.
But suppose the two configuration modules are both called "config" because both authors called them with the same name.
You still have a conflict and you have to edit one of the sources.
You may say it's a stupid name, and they should have used for example: "wilbert_string_lib_config" and "sys64802_string_lib_config" for the configuration modules names.
True.
At the same time, I can say #case_insensitive is a stupid name to be used to configure a module.
Using the global :: operator, they could use #wilbert_string_lib_case_insensitive and #sys64802_string_lib_case_insensitive for their global configuration constants.

So the problem does not go away just by using a common module, and it does not present itself by just using a global scope operator.

It just depends on good habits, and with the :: operator the code is shorter and less ugly.

wilbert wrote: As for the real request in this thread, it would be nice if PB would only generate a warning message instead of an error message if no module part is added and still be able to compile the source.
Not if the warning is a popup window like currently it is and if I can't disable it through a compiler directive, like has been already mentioned somewhere else in the forum.
If both are addressed then sure, ok.

Even if I don't really understand the need for a warning. A warning should mean "are you sure about what's happening here ?", but I don't see anything in need to be double checked in this case.
If you forgot to include the body of the module and some part of your code use something defined there, the compiler raise an error and you realize the body of the module is missing.
Isn't that enough ?

Re: DeclareModule only, without a mandatory Module body.

Posted: Wed Feb 24, 2016 9:10 am
by Fred
That's true, empty module body could avoided by the compiler.

Re: DeclareModule only, without a mandatory Module body.

Posted: Fri Jan 25, 2019 1:44 pm
by luis
Yes please.
After all it just requires to NOT give an error message.
Thanks ?

Re: DeclareModule only, without a mandatory Module body.

Posted: Fri Jan 25, 2019 2:02 pm
by #NULL
Even DeclareModule should be equally optional since you don't necessarily need a public interface if you just do 'static' initialization.

Code: Select all

DeclareModule m
EndDeclareModule

Module m
  
  Debug "do stuff"
  
  Procedure p()
    Debug "do other stuff"
  EndProcedure
  
  p()
  
EndModule


Re: DeclareModule only, without a mandatory Module body.

Posted: Fri Jan 25, 2019 2:57 pm
by Dude
sys64802 wrote:I find the fact we can't access a global constant from inside a module through a scope operator a silly idea.
Why? Isn't the whole idea of modules such that you can drop in someone else's module in your code, and thus any global variable in their module that is named exactly the same as a global variable in your code, won't clash? That's fantastic, IMO.

Re: DeclareModule only, without a mandatory Module body.

Posted: Sat Jan 26, 2019 12:03 am
by Mistrel
Dude wrote:
sys64802 wrote:I find the fact we can't access a global constant from inside a module through a scope operator a silly idea.
Why? Isn't the whole idea of modules such that you can drop in someone else's module in your code, and thus any global variable in their module that is named exactly the same as a global variable in your code, won't clash? That's fantastic, IMO.
See here for a thorough analysis of module scope in PureBasic as well as a proposal to address it.

viewtopic.php?p=524913

Here is a demonstration:

Code: Select all

; Global scope Item
Structure Item
EndStructure

DeclareModule ModuleA
  ; ModuleA Item
  Structure Item
  EndStructure
EndDeclareModule

DeclareModule ModuleB
  UseModule ModuleA
  
  ; ModuleB Item
  Structure Item
  EndStructure
  
  Define a.Item ; <- ModuleB Item
  Define a.ModuleA::Item ; <- ModuleA Item (explicit because of conflict)
  Define a.::Item ; <- Global scope Item (explicit because of conflict)
EndDeclareModule
I am a strong supporter or improving modules. They have a lot of potential if their problems can be address.

Re: DeclareModule only, without a mandatory Module body.

Posted: Thu Feb 28, 2019 12:13 pm
by luis
#NULL wrote:Even DeclareModule should be equally optional
True.
I tend to require DeclareModule/EndDeclareModule without Module/EndModule but having both optional would be nice.

Re: DeclareModule only, without a mandatory Module body.

Posted: Fri Oct 08, 2021 10:05 pm
by luis
Just writing again empty module / endmodule pairs while typing this.
Any hope to see this implemented please ? It's a small thing but it's so silly to see in my source.

Code: Select all

; can't compile 

DeclareModule x
#foo = 1
EndDeclareModule

Debug x::#foo    
Instead of saying "Module 'x' has been only declared (Module/EndModule part missing)." you just have to add the empty missing module automagically.

Code: Select all

Module x 
EndModule
at the end.


Right now I just write

Code: Select all

 Module x
 ; https://www.purebasic.fr/english/viewtopic.php?p=575664#p575664
 EndModule
eh eh eh

Re: DeclareModule only, without a mandatory Module body.

Posted: Sat Oct 09, 2021 3:45 am
by Rinzwind
Modules.. please take a look at how Pascal implemented it ages ago.
If PB functions are accessible from within module, so should your own functions and constants.
IDE support is needed too. Sync declare/implementation. Don't know why they choose for separate declare/implements section anyway instead of using public (default) and private keywords for procedures etc. It's all a bit meh.
Hopefully structures get support for functions so we get at least an alternative that also can store state. But don't hold your breath. Guess that asm backend is too hard and complex wired to add language features. Hope they don't choose to not add syntax to the c backend because of the asm backend.