A Rose By Any Other Name
For some reason, language developers seem to love to reuse words or punctuation or operators. For example, left and right parentheses are used to specify order of operation and grouping in mathematical statements, as well as marking the parameter list for functions, and also for identifying the desired resulting type for a Type Cast operation. In some languages, they are also used to specify the element in an array.
The asterisk (“*”) is used in mathematical statements to specify multiplication but is also used in c-type languages to represent pointers to a value or a function. The plus sign is used in math statements to specify addition but is also used to specify concatenation of non-numeric values, to specify an increment (“++”) operation, and to specify a value to add to a variable in a “+=” statement. And finally, in the Objective-C language, the plus sign is put at the beginning of method declaration line to specify that the method is a class method (instead of the “-” that specifies that it is an instance method).
In most of the programming languages in common use these days, Foo and foo represent different objects. But foo and foo() also represent different objects. In some languages, Foo and Foo can represent different objects, depending on which header file is imported into the current text file.
In some languages, redundant use of words seems to have been become a sought after goal, so you’ll see statements like Manager:manager, Goal:goal, Result:result. While it does prevent polluting the namespace with additional names, when reading some of these statements outloud, one starts to sound like a raving lunatic.
The net result of all these language-specific naming rules is that developers have to correctly interpret the usage of a word to correctly understand what the statement is doing. To paraphrase Shakespeare, “A rose by the exact same name could smell completely different.” All of these naming rules require interpretation which leads to slowed comprehension and unnecessary mistakes.
Every programming language has a list of Reserved words that can only be used is specific ways. For example, the word “for” in c-based languages can only be used as part of a looping statement, such as “for (i=0; i<10; i++)”. Accidental misuse of one of the Reserved words normally just causes a compiler error message, but it can also prevent one from being able to create natural-sounding code statements.
Every programming language has rules for properly naming variables. Most require that the variable name begin with an alphabetic character, but some will allow you to begin a variable name with one or more underscores. Some will allow only alphabetic characters in the name, most will allow alpha and numeric characters in the name, some will allow hyphens and underscores in addition to alphanumeric characters but most will not allow other punctuation in variable names, such as “@” or “%” or “(“. The list of rules goes on and on.
In c-based language the increment and decrement operations can be performed either before the variable is evaluated or after it is evaluated. Pre- or Post- is specified by placing the increment or decrement operator either to the left or to the right of the variable name.
Complexity Is the Enemy of Reliability
Reliability Engineers spend a lot of time thinking about how to reduce the complexity in the system that they are working on. Reducing the number of parts in a system is a common way to improve reliability.
Simplifying the code in a computer program is a great way to improve it’s reliability because it becomes more obvious where problems may exist. Simplifying code can also make it easier to understand what is supposed to happen in the code.
The problem with programming languages is that they can never be made absolutely simple because there are too many special cases, too many special rules, too many uses and reuses of words and punctuation and operators, to be able to write simple uncomplicated code. Instead, the rules and special uses keep piling on like interest on a credit card, making it more and more “expensive” to understand and modify a piece of code. No wonder our limited brains get bogged down when trying to translate a complicated (and sometimes not fully understood) algorithm into code.
I know that many are thinking that my criticisms just require that developers be properly trained, but that’s not really a satisfactory answer. In aircraft system design and user interface design, training is the last choice. Their goal is to make something as simple and intuitive as possible, such as showing pilots an outline of a plane and the line of the horizon to show if the plane is banking instead of giving them a positive or negative number to indicate the degree of bank. Sure, they could be trained to interpret the numbers correctly, but the limitations of the human brain guarantee that now and then they’ll miss the minus sign and bank the plane the wrong direction, sometimes with catastrophic results.
It is unlikely that programming languages will ever be able to provide a simple and intuitive way of developing computer programs, where all the developer has to think about is correctly implementing the algorithm. Instead, programming languages will likely doom us to counting parentheses, measuring indents, and trying to correctly interpret punctuation.