Well chosen variable names are crucial for understanding what a program is doing. I plan to write about naming well but for now, it’s more fun to criticize bad variable names.
1. Nondescript Loop Counters
move 0 to #i
while #i < 50
show ‘Hello World’
add 1 to #i
Sometimes we just want to do something fifty times. The loop counter has no purpose beyond controlling the loop. More often, we do something else with the loop counter. It might index an array, or control an evaluate command, or contribute to a formula in a let command.
If we use it beyond the while test, it must have some meaning, and so it should have a name that reflects that meaning. Even if it is just a loop counter, it should have a distinctive name. Someday, the loop may contain a procedure call, and that procedure may contain a loop. If we’re not careful, we’ll use the same global variable for both loops, and it won’t be pretty.
2. TLA (Three Letter Acronyms)
Obvious, isn’t it, that $ccn is the variable containing the customer contact name? What’s the variable name for credit card number?
3. My Fingers Are Too Tired For Long Names
I once programmed with a version of BASIC in which variables could be a single letter or a single letter followed by a single digit. Some programmers, perhaps hunt-and-peck typists, still use the shortest possible variable names. That’s not much worse than acronyms, but after a page full of $a1, #b2, $a2, $d5, you’ll be begging for acronyms.
4. I’m Paid By The Byte
The opposite problem is variable names that are too long.
let #sick_leave_accrual_rate_for_union_members_in_hours_per_month = 7
OK, that is self-documenting code. It also risks bugs from typos and it elongates any command that uses it:
let #current_sick_leave_balance_in_hours = #sick_leave_carryover_from_previous_year + #current_month_of_this_year * #sick_leave_acrual_rate_for_union_members_in_hours_per_month - #sick_hours_taken_year_to_date
Did you notice the typo?
5. It Is A Value, Isn’t It?
There are variable names that are like the generic canned goods that enjoyed brief popularity a few decades ago. A can of peas would be wrapped in white paper with no photo and no brand name. The word “Peas” and a barcode would appear in black. Or was that just an Andy Warhol painting? I don’t remember.
The variable equivalents are like $string, $date, #value, #number, #total. We can assume that #total is the sum of a group of numbers. Perhaps there’s only one possible meaning for “total,” in a report of employees’ annual salary … until someone adds a column for year end bonuses.
6. The Variable Is The Value
let #one = 1
let $one = 'one'
If #one equals one, we could use the literal instead of the variable. If #one does not equal one, it’s confusing. What application is interested in one as a mathematical concept or a Platonic ideal? We’re interested in headcount or expenses or coordinates on a page. Did you notice the number of bad variable names I promised in the title (#ten)? Look down, and you’ll see that #ten = 12.
7. Is That A Dash Or A Minus?
The first version of SQR did not have the let command nor expressions in if and while commands. The only way to subtract was with the subtract command. It allowed dashes (which look like minus signs) in variable names.
The SQR compiler will warn you of variables like #age-1. I avoid dashes unless I have a situation like one where the variable that contains a person’s age as of a year ago. In that case, I might write:
put #weight #height into annual_checkup(#age)
let #age-1 = #age – 1
! put command doesn’t allow the array index to be an expression
put #prev_weight #prev_height into annual_checkup(#age-1)
let #weight_change = annual_checkup.weight(#age) – annual_checkup.weight(#age - 1)
8. Have I Met You Before?
Without disciplined naming conventions, it’s easy to forget what we called something. We might start the program with variables like this:
- #num_emp (number of employees)
- #vac_hrs (vacation hours)
- $start_date (first day of a period of time)
After a week of programming, we may be writing with variables like this:
- #nbr_emps (number of employees, but with a different abbreviation for “number” and a different policy about plurals)
- #vac.hours (vacation hours, but with a different word separator and abbreviating “vacation” but not “hours.”)
- $begin_dt (first day of a period of time, but with a different synonym for first and an abbreviation for date.)
We only want one variable to hold the number of employees, but we’re counting them in one place and printing them with a variable that was never changed from zero.
9. Recycled Variables
I’d be surprised to find someone reusing a variable name for something completely different. For example, $start_date containing “01-JAN-2009” in one part of the program and “California” in another part of the program. It’s probably less unusual to find $name containing an employee’s name in one procedure and a dependent’s name in another. It’s probably most common to find variables containing different date formats at different times:
input $as_of_date ‘Enter date (mm/dd/yyyy)’
… (50 lines of code, including five procedure calls) …
let $as_of_date = datetostr(strtodate($as_of_date, ‘mm/dd/yyyy’), ‘dd-mon-yyyy’)
where effdt <= $as_of_date
Here, $as_of_date has the same meaning throughout, but it is formatted differently at different times (American date format versus Oracle DBMS date format). When you see this variable scattered through the source code, do you know what it contains? Is it suitable to print on a report? Is it suitable to use in a SQL statement?
10. What’s The Difference?
Sometimes variables are closely related. It may be tempting to give them long, similar names:
- #dept_subtotal_overtime_hrs (hours that earn time-and-a-half)
- #dept_subtotal_overtime2_hrs (hours that earn double time)
- #dept_subtotal_overtime_amt (the dollars paid for overtime)
Most of the characters in the variable name repeat what the variables have in common (dept_subtotal_overtime). If these variables are embedded in dense code, it’s hard to tell them apart. It may be worthwhile to highlight the differences in the variables.
11. OK, you knew this was wrong
I can’t remember whether I’ve actually seen these variables, or just dreamt them in a nightmare. (What, you don’t dream about SQR programming?)
let #xxxxxxx = 3.141592653
let #xxxxxxxx = 2.718281828
12. I heard you the first time
It’s not that these are bad variable names. They’re just an excess of unnecessary variables. Redundancy reduces clarity. Repetition lessens understanding. Multiple statements of the same information leads to confusion. Creating several versions of the same variable makes code harder to read. Expressing an idea over and over will annoy your reader. (Enough?)
let $emplid = &EMPLID
This programmer may not know that SQR will automatically put the value of EMPLID from the database into a column variable called &EMPLID. The option of naming the column variable is for cases where:
- We want to call it something other than the name of the column in the database, or
- We want to perform an operation on the database column (max(), to_char(), etc.) and we want to put the result of that operation in a column variable, or
- We a selecting the column with a dynamic variable (see next week), and SQR doesn’t know which column it will be at the time of compilation.
Also, we can use the column variable (&EMPLID) throughout the program. We don’t need to copy the value to a string variable ($emplid) unless:
- We need to alter the value later, or
- We are calling a procedure from multiple places in our program, using employee IDs that came from multiple sources, and the subroutine needs to work with the employee IDs from those multiple sources.
Request For Information
Nominate more variable name bad practices. How about bad procedure names (do process)?
The SQR language allows us to embed commands of SQL. The two languages communicate in many ways. Obviously SQL sends data to SQR through the column variables, but it also sends status information through the SQR reserved variables. SQR sends data and commands to SQL through variables, dynamic variables, and compile-time substitution variables.
Next week, we’ll look at three ways SQR embeds varying values in the SQL statements it sends to the database.
A palindrome is a word or phrase which is the same forward and backward: It may be possible to reverse every letter, as in civic, rotor, level, racecar, or “Madam, I’m Adam.” Or, we can reverse the order of words, while leaving each word intact, as in “Fall leaves after leaves fall.” (For my non-English readers, “Autumn ends after every leaf drops from its tree.”)
This game is both easier and harder in a programming language like SQR. Easier, because variables can be anything that follows a #, $, or &. Harder, because there are fewer keywords and fewer valid sequences of keywords.
What is the longest VALID command you can form that is also a palindrome, disregarding spaces and special characters? Let me start:
“add #ot to #dda”
“clear-array name = emanyarra-raelc”
Let’s also count beginnings of commands, like “create-array name = emanyarra-etaerc” and word-invariant commands like “show #show.”