GOTO Hell Part 2: Hell by Any Other Name
Most people — a large majority — believe the GOTO construct should never be used. Some of us (and we know who I am) think it can be used judiciously but agree that it's easy to see how one could fall of the wagon and land back in a labyrinth. So, shall we agree to stipulate that using GOTO is (almost) always a bad idea? And can we go that step further and agree that internal GOSUB structures are hardly better? This means that we might all be agreeing that the best approach to software development — in our platform as well as in most others — is to create reusable, standalone functions and subroutines. That's how much of the world does it — can we all just get along on this?
Great. Now that you've transformed your code from spaghetti into kugels , you have a new problem. How do you keep track of all those separate noodley blobs? How do you find the one thing that does that thing you want to do — while spending less effort than it would take to write the darn thing all over again? Or worse yet, and probably more common, stumbling into it after you've already written it again.
The solution lies in how you name your glutenous little babies. You need a convention. A naming convention . And no, that doesn't mean you need to call together hundreds of your peers for a meeting with food and entertainment. Minus the food and entertainment, the solution has been crowd-sourced for you by hundreds — maybe thousands — already, in innumerable books and blogs.
Whichever approach you take, you want a published standard within the wider organization. It doesn't have to be exactly like anyone else's — but the more standard your standard is, the better. Most important is that it is meaningful to you and you can use it. Make it as rock solid in its formula as possible, to support the highest likelihood of always arriving at the same name for the same function. Okay, you're right. That is a lofty, but worthy goal.
Furthermore, these days, many companies have separate development for the front-end of our applications, while the back-end remains in mature, reliable MultiValue. By adopting standard names that are familiar across platforms, we avoid frustrating the front-end developers and overloading the MultiValue programmers who must always step in to tie-up the connection. Imagine a library of easily searchable back-end MultiValue subroutine/functions that the front-end developer can find and use? (Elephant enters room, eyes author balefully. But look, with our focus on the best solutions for the business and the future, MultiValue programmers will be busy refactoring for a while, then having proven the value and usability, can combat 'let's rewrite the whole thing' naysayers and continue writing new functionality in this fast, flexible language that we all know and love.)
Here are some naming tips that can help. These were gathered from various resources in book and blog (attributions / further reading, listed below.) Use them all, use others — but use something.
- First and foremost , whatever rules you decide upon, please decide that the time spent on naming a thing is worthwhile. Slow down and think. You will spend much more time reading than writing programs, and even more time trying to find them.
- Include an action word. Programs, functions, subroutines, I-descriptors, procs and paragraphs all do something. They find something, get something, write something, end-of-month-process something.
- Decide the order - passive or active voice. Naming something — using words — is writing. Rules of grammar that are already established can help and are already known. Whether you prefer a passive voice or a more exciting active voice (see the prejudice in that phrasing?) deciding how you'll do it and sticking to it can stop limitless multiple stabs at the name. Will it be UPDATE.CUSTOMERS (active) or CUSTOMER.UPDATE (passive)? Verb/action word first? Or noun first and action after? It doesn't matter which, but consistency does.
- Think about abstraction level. Be as general, and yet as specific, as it makes sense to be. The function converts kilometers to miles? Name it KM_TO_MILES? (no verb, very specific) or perhaps CONVERT.UM (leads with the verb but unit-of-measure is a short abbreviation and units of measure is very general.) CONVERT.DISTANCE.UNITS? (Verb first, clear relatively specific noun.) You see how this can go, but if you know what your policy is, what you would usually do, and do that again, you'll stumble into that thing you already wrote.
- Careful with abbreviations - avoid ambiguity. A friend recently showed me his new naming conventions for a library of functions that he is creating. Awesome idea. He went with very long unabbreviated sentences. That's cool - will leave little doubt as to their purpose when listing them, a bit annoying to type them. If you are going to abbreviate, this is a pretty critical sub-subject to standardize. Make the meaning of abbreviations clear and unambiguous. Is INC the short for include? Increment? A corporate entity? INCL, INCR, INC. one more character makes a big difference, in this case.
Avoid nonsense and redundancy
Examples of nonsensical program names: FOOFIGHT. YANCY. SLAP-HAPPY.
Examples of redundant/ambiguous program names: VALIDATION.CHECK, FILE.WRITE.UPDATE, PRICE.CHANGE.UPDATE.
- Use synonyms consistently. Decide upon one name for a concept, and use it consistently across the entire application. Do you like to Add or to append? Remove or delete? Refresh or Reload? Require or Mandate?
- Use intention revealing names. It should be quickly possible to understand what a function does, its purpose, by its name.
Be standard - but not too standard
Using a name that is too generic can bump you in to a reserved word or a system command. When working with outside programs, we have to be aware of more of these.
Avoid over-used words like fun, function, procedure, and verbs like run, execute, do and go.
- ERRMSG, a variable used throughout an application, recently bumped into its reserved-word status in C#. Can you predict them all? No. But a little forethought and research goes a long way.
- EQ, used frequently in MultiValue is redundant and unclear. An equal sign (=) is more universal.
- Controversial topics:
- Versioning - does it belong in the name of a program?
No, of course not. The only exception being if you have something that had to be refactored to work on a certain overall version, so you retain the name of the original thing and include the version. For example if the COMMON changed for your overall software release you may have a branching subroutine that calls RESET.COMMON or RESET.COMMON.VER9. It's not about the version of the RESET.COMMON program, but rather a program to support an overall version of the software.
Upper case, lower case, camel case, pascal case, snake case. Look them up. Pick one. Stick to it. (Author pines for the simplicity of SHOUTING.)
Keep in mind that you can rename something at any time when you realize you got it wrong. Yes, you must find whatever calls it, but it's not that hard. Take that minute - it could save hours and jobs.
Sources, recommended reading:
Clean Code: A Handbook of Agile Software Craftsmanship" - by Robert C. Martin.
Stackoverflow.com/search - by the whole world
Coding like Shakespeare - a frequently referenced blog by Dmitri Pavlutin.