Why use Modules in ZBasic

Discussion about the ZBasic language including the System Library. If you're not sure where to post your message, do it here. However, do not make test posts here; that's the purpose of the Sandbox.
Post Reply
mikep
Posts: 796
Joined: 24 September 2005, 15:54 PM

Why use Modules in ZBasic

Post by mikep »

From another thread:
Maybe its just me, but having a program split into many small files is irritating and difficult to use. I then have to try to remember which file the code is in too. I often look back at previous routines to see what it does. That is the main reason I hate programming in C, all of the many files that are used make it very difficult to find where a constant is defined or where a function is located. Its probably just me, but if the whole program is in one file, I can find everything easily.
Imagine if your program was 10,000 lines of code (or more). That single file would be very hard to manage. The best practice in software engineering is to divide your code into modules which is why you will find most experienced programmers on this forum supporting the idea.

Some languages term modules classes or whatever but the concept is the same - functionality is encapsulated into one place which can be reused. A module usually has a well-defined and documented public interface and that is all you need to remember - the internals are hidden and not exposed. This means that you actually have to remember a lot less and there are usually less defects introduced into the code

If you read my ZBasic application notes on interfacing to various devices, you will find that the functionality is divided into a main tester routine and then one and sometimes more modules that implement a specific function. I did this to promote reuse.

So for example let's say you were building a fire-fighting robot. First take the ultrasonic module (SRF05.bas) from AN-215, thermal sensor module (TPA81.bas) from AN-212, LCD module (LCD03.bas) from AN-214, and the remote control modules (IR.bas, SonyIRCodes.bas) from AN-204. Then write your own motor control module (e.g. Motor.bas) using PWM and add a main routine in Robot.bas. More than 50% of the code has already been written and tested for you and you just need to add a bit more to have a fully-functioning robot.

Even if you were starting from scratch, it is still a good practice to separate out your code. This provides a divide and conquer approach to solving the problem as you build up the solution, module by module.

If you want to compare this idea to hardware, you can think of each module as a separate chip. Each chip has a well-defined interface (the datasheet) and an implementation that is hidden (the silicon) which almost all people don't care about. If you look at the ZX-24ae device for example, you can think of that as a "super-module" that has been tested and is ready to use.
Mike Perks
twesthoff
Posts: 247
Joined: 17 March 2006, 6:45 AM
Location: Fredericksburg, VA

Why use Modules in ZBasic

Post by twesthoff »

...
Imagine if your program was 10,000 lines of code (or more). That single file would be very hard to manage. The best practice in software engineering is to divide your code into modules which is why you will find most experienced programmers on this forum supporting the idea.

I have always thought the concepts were good, but making it work seemed like more work than it was worth.

Some languages term modules classes or whatever but the concept is the same - functionality is encapsulated into one place which can be reused. A module usually has a well-defined and documented public interface and that is all you need to remember - the internals are hidden and not exposed. This means that you actually have to remember a lot less and there are usually less defects introduced into the code.

Maybe you could write an app note showing how all of the modules work together an how variable names that are the same don't interfere with each other etc. Do it in a simple way for beginners, and explain how it is done.

...
spamiam
Posts: 739
Joined: 13 November 2005, 6:39 AM

Post by spamiam »

Probably you should look for some books on structured programming. It is much too broad a subject for a simple AppNote.

Unfortunately, it is also somewhat language-dependent. For instance Plain C and ZBasic do not use classes, but as has been mentioned, an individual file (aka "module") offers some degree of insulation, similar to a class.

One of the most important issues, as you point out is the concept (and use of) "scope". I think that if you read about "scope" and public vs. private in the ZBasic language reference, many of your questions will be answered.

For most programs that I write, separation into modules is purely for convenience. ("where is that darned subroutine!!!!") Usually I divide the modules into logical pieces, i.e. RTC, I/O, 1-wire, LCD, number crunching.

I usually use TOO MANY global variables, more than a "good" structured should have, but this is mostly a matter of convenience for me. It is my opinion that compared to a PC, a MICROcontroller is a module all by itself, so it is less heretical to use proportionally more global variables and public functions.

-Tony
mikep
Posts: 796
Joined: 24 September 2005, 15:54 PM

Post by mikep »

spamiam wrote:Probably you should look for some books on structured programming. It is much too broad a subject for a simple AppNote.
Actually I think it is possible to do in an app note. Finding the time with all the other priorities is a whole other issue.
spamiam wrote:One of the most important issues, as you point out is the concept (and use of) "scope". I think that if you read about "scope" and public vs. private in the ZBasic language reference, many of your questions will be answered.
Actually the scope thing came from me. Tom didn't insert the quote tagging quite right.
spamiam wrote:For most programs that I write, separation into modules is purely for convenience. ("where is that darned subroutine!!!!") Usually I divide the modules into logical pieces, i.e. RTC, I/O, 1-wire, LCD, number crunching.
That is similar to the examples I gave. The interesting part is where you hide information using private variables and simplify the user interface - that is where a good example in an application note will help.
spamiam wrote:I usually use TOO MANY global variables, more than a "good" structured should have, but this is mostly a matter of convenience for me. It is my opinion that compared to a PC, a MICROcontroller is a module all by itself, so it is less heretical to use proportionally more global variables and public functions.
We disagree here Tony. Size has nothing to do with using good programming practices. Claiming that this is just a hobby or it doesn't matter is not an excuse. One of the main reasons for using modules is information hiding and encapsulation. These ideas are so powerful and when put into practice correctly will eliminate 50% of the potential defects in your code. One of the major problems is spaghetti code. Not the use of gotos but something more insidious - variables modified all over the code in an haphazard manner. You know this whenever you have tried to debug a problem where something gets changed and you cannot figure out where and why. You can spend days chasing this type of problem. There are some really good articles and books on this stuff that could be "translated" into ZBasic and explained in an app note.
Mike Perks
twesthoff
Posts: 247
Joined: 17 March 2006, 6:45 AM
Location: Fredericksburg, VA

Why use Modules in ZBasic

Post by twesthoff »

What I was thinking of is a simple example with maybe three modules, some global variables, and some variables that are the same name in each module, but not global. Something that shows the mechanics of how to do it.

I have written a lot of VB code(Not .net), that used 5-6 modules and I understand the concept of scope. Again I find it easier to keep track of everything if it is in one file. I have done it both ways on large programs.
stevech
Posts: 715
Joined: 22 February 2006, 20:56 PM

Post by stevech »

I recently had to use a BASIC compiler for an ARM7 that had no automatics or local variables; everything had to be global. I faked it by using the function/subroutine's name as a prefix to the variable, like subroutineA_var1 so I knew what the intended scope was. A later incarnation of that compiler added local variables, but the storage was not on the stack - but rather in general RAM, so inactive local variables consumed RAM. Mickey-mouse. Fortunately, that project milestone has passed - I built 12 copies of that ARM7 wireless (802.15.4) device for a field test that was successful. It can be a mess! Not so with ZBasic.
spamiam
Posts: 739
Joined: 13 November 2005, 6:39 AM

Post by spamiam »

mikep wrote:We disagree here Tony. Size has nothing to do with using good programming practices. Claiming that this is just a hobby or it doesn't matter is not an excuse. One of the main reasons for using modules is information hiding and encapsulation. These ideas are so powerful and when put into practice correctly will eliminate 50% of the potential defects in your code. One of the major problems is spaghetti code. Not the use of gotos but something more insidious - variables modified all over the code in an haphazard manner. You know this whenever you have tried to debug a problem where something gets changed and you cannot figure out where and why. You can spend days chasing this type of problem. There are some really good articles and books on this stuff that could be "translated" into ZBasic and explained in an app note.
Well, I hope we don't disagree here. I actually do espouse the good programming techniques you outline here. As for ME being good enough and disciplined enough to do it this way all the time, well.....no.

When I did a major re-write of a big C program running on an M128, it was mostly at the behest of another programmer. One of the things that was the HARDEST to do was to restrict myself to accessor functions to provate data, and have virtually NO global data at all.

The initial program sort-of grew organically as I added progressively more code. While it was not spaghetti code, and the code was modularized, most of the actual data was global. This was due to the fact that so many parts were fundamentally inter-related. It was rather inconvenient to limit access to the data.

Eventually it all worked properly, but it was disappointing to see code that had formerly worked well develop all sorts of bugs due unexpected consequences of the improvements. It works well now. It is probably easier to maintain, and it is probably easier to sort out faults when they occur.

The changes were more than stylistic. There was a change in the fundamental program flow. It went from external interrupt driven to cooperative multitasking with polling of most inputs that were formerly interrupts. This included LCD display. Therefore almost every line of code was changed, and the accessor functions were almost incidental in the effort. Nevertheless it was hard to turn away from the Dark Side of global variables.

-Tony
Post Reply