Page 1 of 3

Modules

Posted: Tue Jun 25, 2013 11:23 pm
by spacebuddy
Can someone explain to me what this new features is Modules?

I looked at the samples but don't really understand what I would use them for? :(

Thanks :D

Re: Modules

Posted: Wed Jun 26, 2013 5:16 pm
by WilliamL
This is something new. I suppose the Help file will explain some of it. I'd like a simple explanation too...

Some hints here but I'm still not sure what it means...

http://www.purebasic.fr/english/viewtop ... 13&t=55071

Re: Modules

Posted: Wed Jun 26, 2013 5:23 pm
by ts-soft

Re: Modules

Posted: Wed Jun 26, 2013 5:32 pm
by WilliamL
(wikipedia) wow, can it be explained any more obtusely!?

Sounds like a Procedure but there must be more to it.. so we'll see as examples appear.

An explanation of the command set will help also.. when the 'Help' file is updated.

Re: Modules

Posted: Thu Jun 27, 2013 1:05 am
by spacebuddy
Now I am even more confused :shock:

Re: Modules

Posted: Fri Jun 28, 2013 1:30 am
by fsw
I'm in the similar boat :?

The problem I have is to visualize how to use this facility.
The provided examples in this forum do not really help because the usage of the module in these examples are theoretical in nature and can't be projected (or made beneficial to use) in a real life situation. (well at least I can't see it - maybe you can...)

If the Modules could be used as types (hello go[lang] :P ) then it would make sense:

Code: Select all

; pretend Vehicle is the name of the module...
Global test.Vehicle
 test::NewAuto(77)
 test::NewBoat()
Why do we have two colons?
Wouldn't one suffice?
Or why not allow the backslash?

Anyhow, what's also missing is the possibility for an alias, this way collisions could be easily avoided:

Code: Select all

ImportModule hisMath "libs\ts-soft\super-cool-math" 
ImportModule myMath "libs\my-stuff\crappy-way-of-doing-things"

define his.hisMath
define my.myMath

;....
debug his:Py()
debug my:Py()
For now the module implementation adds only more typing :mrgreen:
Really hope that someone explains this module stuff better, with real life examples that show the benefit.

Re: Modules

Posted: Fri Jun 28, 2013 6:43 am
by eesau
fsw wrote:Why do we have two colons?
Wouldn't one suffice?
It's because a single colon denotes a statement separator.

Re: Modules

Posted: Fri Jun 28, 2013 7:06 am
by fsw
eesau wrote:
fsw wrote:Why do we have two colons?
Wouldn't one suffice?
It's because a single colon denotes a statement separator.
Oh yeah, that's right - I never use it though :oops:
(it's a BASIC thing...)

Actually professional programmers are discouraged to place 2 statements on one line.
(the programming language doesn't matter)
Especially when several programmers need to share code.
They are encouraged to use the free space for additional documentation :P

Re: Modules

Posted: Fri Jun 28, 2013 5:25 pm
by freak
Simply put: Modules allow the separation of the code into parts that are isolated from each other. There is no risk of things like global variables or procedure names conflicting with other code parts. Only the code of a module defined in the "DeclareModule" block is accessible from the outside. This allows to break down a project into smaller/simpler parts that each can be coded separately without them interfering with each other.

Example:
Lets say the program has two major areas: To do thing A and to do thing B. The program could be split like this:

ThingA.pb:

Code: Select all

DeclareModule ThingA

  ; This is the only procedure callable from the outside
  Declare DoThingA(foo, bar)

EndDeclareModule


Module ThingA

  ; Here we can use simple names without fear of a name collision with another
  ; module. Without Modules, these would have to be called "ThingA_x" to separate
  ; them similar names in the ThingB code.
  Global x = 1, y = 2

  ; This procedure is only visible in here, so again, we can use any name we want
  ; without a collision with other code
  Procedure Calculate()
    ProcedureReturn 42
  EndProcedure 

  ; this can be called from the outside
  Procedure DoThingA(foo, bar)    
    x = Calculate() + y
    Debug x
  EndProcedure
  

EndModule
ThingB.pb:

Code: Select all

DeclareModule ThingB

  ; visible from the outside
  Declare DoThingB()
 
EndDeclareModule

Module ThingB

  ; here, the same names are used as in the ThingA module, but no problem.
  ; The global variable here is not the same as the one in ThingA.
  Global y
  
  Procedure Calculate()
    ProcedureReturn 21
  EndProcedure 
  
  Procedure DoThingB()
    y = Calculate()
    Debug y
  EndProcedure  
  
EndModule
Main file:

Code: Select all

XIncludeFile "ThingA.pb"
XIncludeFile "ThingB.pb"

; open the needed modules
UseModule ThingA
UseModule ThingB

; somewhere in the main code, call the modules
; ...
DoThingA(1, 2)

;.. and later...
DoThingB()
Whether you want to access the public parts of the modules using the full names i.e. "ThingA::DoThingA()" and "ThingB::DoThingB()" or open the modules as I did above is just a matter of style. The important benefit of the modules is inside the code for each: They are totally separated from each other. Each can be written without having to look at the other one to avoid conflicts.

Now lets say there is code that they should share. Simple: Put that in its own module that both can access:



Common.pb:

Code: Select all

DeclareModule Common
  
  ; some shared constants
  #SomeConstant = 1
  #OtherConstant = 25
  
  ; some shared code
  Declare ReadConfiguration()

EndDeclareModule

Module Common

  ; the shared procedure
  Procedure ReadConfiguration()
  EndProcedure

EndModule
ThingA.pb:

Code: Select all

DeclareModule ThingA

  ; This is the only procedure callable from the outside
  Declare DoThingA(foo, bar)

EndDeclareModule


Module ThingA

  UseModule Common


  Procedure DoThingA(foo, bar)    
    
    ReadConfiguration()
    Debug #SomeConstant    
    
  EndProcedure
  

EndModule
ThingB.pb:

Code: Select all

DeclareModule ThingB

  Declare DoThingB()
 
EndDeclareModule

Module ThingB

  UseModule Common


  Procedure DoThingB()  
    ReadConfiguration()
    ; ...
  EndProcedure  
  
EndModule
This is the essence of modules: Each code part is separated, and interaction only happens at the boundaries defined in the DeclareModule block. You have to explicitly access another module either with the "UseModule" command or by using the full name like "Common::#SomeConstant".

This separation also helps to reuse code better. If i decide i want ThingA also in another program, i can just include the ThingA.pb with a minimal risk for name collisions: Only the module name itself and the DoThingA() procedure are accessible from the outside. So a module with a well written public interface (good names without much risk for collisions) can be easily reused in other programs even if the actual module code contains names that would otherwise collide with the names in the new program.

Re: Modules

Posted: Fri Jun 28, 2013 6:29 pm
by Little John
I appreciate this new Module feature very much, and I am really thankful that it is not specific to Mac OSX. :D

Re: Modules

Posted: Fri Jun 28, 2013 6:32 pm
by skywalk
Like many, I am encouraged with the new Module possibilities, but would the implementation have been far simpler if the compiler could make multiple passes?
What is the desire/requirement to remain a single pass anyway when modern processors are so fast?
I see too many declares required and I already employ a prefix naming to my includefiles(xxx_constants/xxx_strucs/xxx_procedures) so there are no conflicts.
I also like the module aliases to help reduce typing and readability.

Re: Modules

Posted: Fri Jun 28, 2013 6:41 pm
by freak
What does that have to do with anything?

The reason to have a module declaration block was a design decision, not one dictated by the compiler implementation.

Re: Modules

Posted: Fri Jun 28, 2013 7:01 pm
by Fred
I can confirm than the single pass compiler has nothing to do with the current module implementation.

Re: Modules

Posted: Fri Jun 28, 2013 7:14 pm
by skywalk
My gripe is the necessity to manage declarations that could be caught by the compiler.
I have (X)IncludeFile.
I expected IncludeModule.
And within a module, I could define Public and Private elements.
As it is now, I have lots more typing if I choose to use Modules instead of IncludeFiles with 'xxx_' prefixes.

Re: Modules

Posted: Fri Jun 28, 2013 7:19 pm
by Fred
I don't think it's much more typing, and you have a clear overview of what is public, which is definitely a strong point (basically only public produre needs to be declared twice (variables, array, list etc. doesn't need to be declared again in the module body). Indeed, nobody forces you to use the modules, everyone has to find its best interest.