Code Conventions
The primary objective of code conventions is to produce code that is identical no matter who the author is. Code that follow such conventions are immediately recognizable by developers and easier to maintain in the long run. We could say that code conventions are nothing but codified common sense which is true in hindsight but may not be clear when all you have is an empty stack and no plan. In this chapter we will learn the most common code conventions in our community, and we’ll begin with how to name stuff.
How to name things
Names should always be descriptive and meaningful. LiveCode is a very verbose language and you should not be afraid of making your variables and handlers even more verbose if this saves your sanity six months from now. Other programming languages from old times had space and memory constraints that forced the developer to use the smallest names.
I had a computer that used BASIC and each variable name could have only up to two letters, so you went from variable a to variable zz (and cried a lot while maintaining any code).
Many developers that learned to code with similar constraints still name things with cryptic names such as curcont claiming that saving some characters in the variable name is good because they type variable names a lot and typing less will lead them to work faster. Naming the same variable with a name like tCurrentContact makes your code obvious even to people who have never seen it before and is doesn’t require much more typing while presenting many benefits in the long run. We should always name things clearly and avoid using contractions or abbreviations. Don’t be afraid to type more characters, the more descriptive something is, the less code commenting you will need to do later. Lets agree on some guidelines for naming things:
- Use meaningful names.
- Use full words and separate them with a capital letter such as
currentContact. - Avoid generic names such as
countand choose more specific ones such asnumberOfApplesInBasket. The rules above are great, but lets dive deeper and focus on how to name variables.
Naming variables
In the LiveCode community it is very common to use Hungarian Notation1 to name variables as explained in the Fourth World Scripting Style Guide. This method of naming variables advocates for the usage of prefixes and suffixes in the variable name to make the variable type and scope clear.
In LiveCode we have global, script local, and temporary variables. Constants are like variables, but they can’t be changed once assigned. Let us mark each scope with a prefix in the variable name:
-
g for global variable: such as
gApplicationVersion. -
s for script local variable: as in
sDatabaseConnectionID. -
t for temporary variable: like:
tCurrentContact. -
p for parameters: if the variable is passed as a parameter to a handler. Example:
pContactA. -
k for constant: sometimes we also use ALL CAPS and underscores as separators for constants:
kUPDATE_URL.
Another important caveat is that there is no way to tell if a variable is an array or not in LiveCode just by looking at the variable name, so we usually use a capital A suffix for array variable names as in this example: gAllContactsA which is a global array variable holding all contacts for an application.
Example:
1 global gAllContactsA
2 local sCurrentContactA
3
4 command sayHi pContactA
5 local tGreeting
6 put “Hello,” && pContactA[“name”] into tGreeting
7 return tGreeting
8 end sayHi
Naming handlers
Some people take a great care when naming their variables and then let all this care go down the drain when naming their handlers. If you think most of your code ends up as being variable names and handler names, you notice that using some wisdom when naming them will pay well in the long run. Some guidelines for handler names:
- Always place a verb in the handler’s name as in
placeFruitInBasketinstead offruitBasket. - Be descriptive, use names as long as they need to be.
I have a handler called checkApplicationVersionAndUpdateIfNeeded and I think it is a great name because it instantly tells me what that handler does.
Example:
1 function getContactDataAsJSON
2 // do something
3 end getContactDataAsJSON
4
5 command emailCurrentSelectedContact
6 // do something
7 end emailCurrentSelectedContact
We should not underestimate how useful a good name is. Select your verb well and if possible use it as the first word of the handler. As a mental exercise, consider the code below:
1 put contacts() into tContactsA
From that code there is not much we can infer about what contacts() does. Does it accept a parameter? Is it a function to set something or to retrieve something or both? Unless we have comments in the source code, we must read the implementation of that function to understand what it is doing. Better naming could solve this.
1 put getAllContacts() into tContactsA
Not only we know what it does since it uses the verb get but we know it retrieves all contacts and not just some selection. Another important naming convention for handlers is regarding their scope. In LiveCode we can have both public and private handlers. If you’re building code that will be shared, such as a library, then you’d create a public API that is documented and available for others, and a private API that is used only by you. Handlers should not call private handlers of other stacks. And yes, now that we have private and public keywords, there is no way to leak the implementation handlers anymore, but still naming them differently helps with maintenance.
Lets use an underscore character before the name of any private handler. So if you have a public command called saveContact and this command makes use of the private command writeContactToFile then you should name the private handler _writeContactToFile like in:
1 on saveContact pContactA
2 combine pContactA by cr and tab
3 _writeContactToFile pContactA
4 end saveContact
So just by looking at that source code we know that _writeContactToFile is a private command. Sometimes, naming something wisely is not enough to convey why something is happening in the source code. For these cases we have source code documentation.
How to document your code
There should be a book dedicated only to teaching how to document code. I suspect developers hate to write documentation because it causes them to think about the same problem twice, once when coding and again when documenting. There are some great tools to help you document your application such as screensteps but this section is not about documenting your application for your end user (one task that screensteps excels on) but to create comments alongside the source code to better explain what is going on.
The rule of thumb for code comments is not to explain what is happening but why it is happening. The developer can understand what is going on from reading the source code, but they may need some help to understand why it should work that way. For example, consider the poor case of commenting below:
1 function addTwo pNumber
2 // below we add two to a number
3 add 2 to pNumber
4 return pNumber
5 end addTwo
That comment is useless because it doesn’t help the developer at all. Now consider the following better example of commenting:
1 function movePlayerDown @pPlayerLongID
2 // We add 48 pixels to the value of
3 // top because our game tiles are 48 pixels
4 // tall, so adding this value moves
5 // the player one tile down.
6 add 48 to the top of pPlayerLongID
7 end movePlayerDown
If at anytime in your source code something is not clear why it should be that way, then it is a good time to write a comment explaining the reasons behind how that code needs to be the way it is. There is no such thing as excessive commenting if all your comments are excellent quality (mark this affirmation as my opinion as this is a controversial topic). The more code conventions and comments you use, the less you will need to remember when it is time for you to fix something in your app.
Tools that use comments for the greater good
There are some great tools out there that use source code comments to build amazing things.
There is lcTaskList that allows you to leave comments with markings such as TODO, FIXME and build reports on the notes you left for yourself. There is also NativeDoc which is a documentation generator for LiveCode that picks comments structured in a specific way and builds HTML documentation from it. I’ve also built RevDoc a little plugin similar to NativeDoc. You can check more in RevUp 64.
Summary
In this chapter we’ve learned:
- The importance of good names and conventions.
- That by using prefixes and suffixes in variable names we can convey scope and nature.
- That by being verbose and always using a verb in handlers names we can make our intention (and code) clearer.
- That source code commenting helps developers understand why something is happening and not just how.
The next chapter we’ll talk about MVC, a mindset and strategy that is very successful in shipping maintainable code.