If there was one complaint I have with a lot of code today, it is the lack of easy readability. True, programming language code by its nature can’t always be easy to read. But shouldn’t it be the goal of programmers to write code which is more readable?
Something to Learn from BASIC
It is interesting that the name BASIC is an acronym for "Beginners All-purpose Symbolic Instruction Code". Consider one part of that acronym, "Beginners". Why for beginners ? The idea is that it would be easier for a novice to be able to code with it. How would that be accomplished ? The only way to make a programming language easier for a novice is to remove complexity and terseness. One term coined by some BASIC users is a more "natural" language or syntax. In essence it means, more readable or closer to natural languages we use. But isn’t better readability something that a professional programmer should strive for ? Absolutely ! Why ?
If a programmer writes code for a business and then he leaves the company, someone else will have to come along and read his/her code. If the code is easily readable, then the transition to a different programmer is much faster and more reliable. If it is not, then all sorts of nightmares occur for the next programmer, trying to make sense of someone else's code. And even more important than this, code readability determines how easy it will be to debug the software. Programmers often want to automate debugging, as if somehow the computer can figure out your code and find your mistakes for you. True a software debugger is useful, but often it works best in concert with the programmer, not by itself. Debugging often comes down to just reading the code back and examining it with a careful eye. Now the more readable the code is, the easier it is for the programmer to do this.
It is interesting that the very thing BASIC was designed to do, is often considered a negative by most main stream programmers. "Oh, BASIC is for beginners only", "Basic is hobby language and not for serious programmers" or "BASIC teaches all the wrong things" may be often be heard from main stream professional programmers. But yet, is not the idea of a more natural programming language a good thing and something for a professional to strive for ?
The BASIC language compilers of today have come a long way from the early BASIC interpreters of old. While maintaining much of the core simplicity of the original language, they have added more complex and powerful features. But the idea of a simpler and easier code syntax still remains.
Modular Design
Over the years, I have dealt with a good number of other programmers. My company designs tools for programmers, so I often see the code from many different programmers who use my companies tools. When doing research for development, I browse programming forums often trying to learn as much as possible from others' code. The one thing I notice often is the lack of modular design in code to make code more readable. Modular design is often used to break up the code into smaller workable pieces, but modular design often is not used for the sake of making code more readable. In the same way, a programming language can be designed for better code readability, so too can our own code accomplish this. Let me demonstrate. The WIN32 API function CreateFont
has 14 different parameters which need to be passed. The height of the font must be precalculated based on the calculation of:
nHeight = -MulDiv(PointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72)
The API returns a font handle, which needs to be stored in a variable to be used later, which requires even more code (i.e., Global variables when writing procedural style code). Personally, I found this a lot of code, when I often do the exact same thing when creating a font. The fonts I use are used on normal window DCs. Rarely if ever do I need a font using anything but pixels for logical coordinates. The fonts need to be defined using a standard point size, rather than pixels. Why would I want to use CreateFont
every time I need a new font ?
Since I was writing a GUI framework designed to make things easier, I used some of the same principles which make the BASIC language so easy to read. First, a trick I learned from old fashioned DOS basic was to create a font pool using an index system. In DOS basic, colors are handled this way. Each RGB color has an index. Index zero is Black, and then from there, the colors are Dark Blue (1), Dark Green (2) and so on. So why not use something similar with fonts ?
Windows provides some predefined system fonts using the GetStockObject
so I load those fonts into the beginning of the font pool (static internal array) for indexes 0 to 5. From index 6 on and can define custom fonts and the subroutine I wrote to create new fonts (which calls CreateFont
) has very simple parameters like this:
EZ_DefFont MyFontIndex, MyFontFace, MyFontPointSize , MyFontAttributes
MyFontIndex
is simple an integer number which defines the fonts index in the font pool. MyFontface
is a string
which defines the fonts name. MyFontPointSize
is an integer which defines the fonts point size. MyFontAttributes
is a simple string
which defines the general attributes (or properties) of the font using a single character for each attribute.
Now in use it is even easier. Let’s see some examples:
EZ_DefFont 7, "Arial", 10, "VIBQ"
This defines font number 7 as Arial, 10 point and with the attributes Variable pitch (V), Italic (I), Bold face (B) and Letter Quality (Q).
Now I can use this font anywhere in my program simply by referring to it by its index (number 7).
The subroutine EZ_DefFont
internally uses about 150 lines of code in it and it calls APIs like MulDiv
, CreateFont
, GetDeviceCaps
, GetMapMode
, GetDC
and ReleaseDC
. The GUI framework was designed as a state machine so this subroutine can define fonts for normal windows (controls), DC drawing, Drawing in the frameworks Canvas
control and even the Printer. By simply using the C
attribute, the subroutine defaults to the current Canvas
. By simply using the P
attribute, it defaults to the current printer. So the command is well rounded. It can add weight to the fonts in increments of 100 units with the + attribute and can even define rotated fonts using a macro string like "{90}"
in the attributes. By using a simple string
to pass the attributes and using a single character for each attribute, it makes it easier to code and easier to read. True, the execution speed is slower than if I simply called CreateFont
, but in most cases the ease of coding outweighs the extra overhead of the subroutine.
The Key is Simplicity
The point of all of this is simplicity. The less characters used in code, the easier it is to read. The simpler command statements are, the easier the code is to read. When one pre written modular subroutine can accomplish what would have taken dozens of lines of code, then code is easier to read. I found this technique decreases code size significantly and makes code readability significantly better. For example, when I first learned how to create a ToolBar control using the WIN32 API, it was a bit complex. So much code for such a simple control ! When writing a GUI framework, I had the goal making it as simple as possible. Here is an example of how the framework creates a complete toolbar control using one line of code:
EZ_Toolbar 50, "#LargeSTD", "BBBBBBBBBBBB", "ON32X32{4}VT"
The command defines a toolbar in this case, with an ID of 50, using the standard built in Large bitmap ("#LargeSTD"
) , defining 12 buttons (the BBB‘s) with the attributes of Open edge (O), No divider line (N), 32 x 32 pixel images (32X32), Vertical toolbar (V) and Tabstop (T).
The idea is code condensing. Accomplishing as much as possible with as little code as possible. The EZ_ToolBar
command in the GUI framework likely calls over 500 lines of code, maybe more. The subroutine has over 400 lines of code in it, but it calls a number of other routines in the GUI framework internally, so it is hard to calculate how many lines of code actually get used by this one routine in total.
The Benefits of Procedural Design
While Object Oriented Program is all the rage today, the techniques noted above about code simplification, in my opinion, work best with a more procedural style of coding. Whether you use Basic like me or use a language like C (rather than C++), procedural style coding lends itself to this kind of code minimalism. In my case, rather that use objects and classes, I use a state machine for handling a lot of the GUI features. Threading is only used for non-GUI tasks, so all the code will be executed in a linear fashion so a state machine works well in my case. Even with an event based GUI framework, this still works well (my GUI engine is event based). Procedural style code using a state machine can produce a much smaller (and with less code) application than its OOP counterpart.
Here is application example you can download: Windows 8 Compatibility Test App
This app I created for testing my GUI framework and its features to make sure it worked on Windows 8 and that the WIN32 still supported the features. Make sure your PC has the proper OpenGL drivers for the 3D part (only requires OpenGL 2.0 or less).
The executable is only 169 Kilobytes in size, which is small for what it does. Most of the work is being done by the GUI framework which are DLLs (dynamic link libraries). This means the code that created the EXE was minimal, compared to if I wrote it entirely using the WIN32 API. The GUI framework only calls the WIN32 API and thing else, so no other frameworks are being used (no MFC, no ATL, no .NET). Let me show you a little of the source code for this demo app.
If you select the CustomDraw
option from the list of features, you will see a Listview
control which is drawn using customdraw
. It is a standard WIN32 Listview
control, but you will notice that the columns use different colors and different fonts to produce a very nice effect which makes the control more meaningful to the end user. Using the WIN32 API, it requires a bit of code, using a GUI framework designed for minimalism the code used in this app is this:
SUB DMAIN_CDLISTVIEW_Events( MyID&, CMsg&, CVal&, Cancel&)
SELECT CASE CMsg&
CASE %EZ_Selected
CASE %EZ_NoCustomDraw
Cancel&=1 ‘ force custom draw
CASE %EZ_CustomDraw
LOCAL I&, SI&, T$
I&=EZ_GetCDrawItem(CVal&, SI&)
SELECT CASE SI&
CASE 0
EZ_SetCDrawItem CVal&, 90, 0,15
CASE 1
EZ_SetCDrawItem CVal&, 91, 2,26
CASE 2
T$=EZ_GetLVItemText("DMain", MyID&, I&,SI&)
IF T$="In Stock" THEN
EZ_SetCDrawItem CVal&, 92, 1,15
ELSE
EZ_SetCDrawItem CVal&, 93, 4,28
END IF
CASE ELSE
EZ_SetCDrawItem CVal&, 90, 0,-1
END SELECT
CASE ELSE
END SELECT
END SUB
The command EZ_SetCDrawItem
in the framework can define the foreground, background colors and the font for each individual item in the listview
control. The control will look like this:
It is not the framework that is important, but the idea of code minimalism. The less code you use to define a task, the more readable it is and the easier it is to code and debug. One of the reasons I use this technique (code minimalism) is that rather than use a lot of "canned" objects, I need to be able to have an almost endless set of choices for customization. To do this using objects and classes would increase the code base, rather than decrease it. Using a more procedural style of coding with a state machine, it allows me to provide more choices with less code.
To Sum It Up
The idea discussed in this article is about code minimalism, using as little code as possible to accomplish a task. If programmers today did not have the benefit of a visual environment for designing their applications and a code editor with intellisense, they likely would appreciate how much work was really involved in coding an application. When I designed a GUI framework, while I did build a drag and drop Visual Designer/Code Generator for it, it was also designed so it could be used to hand code an entire application using a simple code editor (no designer/no intellisense). There are actually a number of programmers who use this GUI framework this way, with just a code editor. This could not be done without the benefit of code minimalism. Even when using a higher level visual design environment, code minimalism makes the life of the visual designer much easier and it makes tracking code flow of generated code much easier to follow. So maybe this is something we can learn from BASIC ! If code was easier to code and easier to read and it required much less code to accomplish tasks (aka. code minimalism), wouldn’t that make our life as programmers much easier? Wouldn’t it make it easier to debug our applications?