Or should that be natural <> simple?
Since the introduction of the first programming languages that didn’t map directly to machine instructions, the debate continues over how closely programming languages should mimic other human languages, especially English. COBOL was the first language (AFAIK) that attempted to allow programmers to write code as semi-English statements. For example:
SUBTRACT AR-TOTAL-BALANCE FROM AR-CREDIT-LIMIT GIVING AR-REMAINING-CREDIT.
Very English – or rather American (including the shouting). As opposed to the much more concise, mathematical, yet somewhat less self-documenting Fortran equivalent:
Z = X – Y
Note how the COBOL statement ends with a period, just like an English sentence – while the Fortran statement mimics a mathematical formula (though it isn’t — it’s an implied LET) by having no terminal punctuation. Because COBOL statements tend to be very wordy, the period actually comes in handy. It allows you to continue a statement over more than one line, because the period clearly marks the end of a statement. But it’s also a curse. It’s easy to forget, because the casual reader can usually tell by context where the end of a statement should be. So it becomes a Simon Says rule – one that punishes the programmer more than it helps.
Back when I used COBOL, if you forgot a period on a COBOL statement every statement in the rest of the program would generate a compilation error. At the end of a college semester, after waiting days to get back the printout from a job you submitted to the queue, you’d often find that your 1345 compilation errors were all due to one missing dot. Then you’d resubmit the corrected version, and wait two more days to find where the next one was missing. I once remarked to a female CS student, “Life is like a COBOL program – miss a period and you’ve had it.”
But without the period, the problem remains of how to continue a statement over more than one line. Fortran and other languages (Synergy/DE and VB included) have resorted to the unnatural practice of placing a continuation character in a specific place. In VB, it’s an underscore at the end of the first line. In Synergy/DE (DIBOL), it’s an ampersand as the first non-whitespace character on the second line. Languages in the Algol tradition (including Pascal, C, Java, C#, etc.) require a terminating semi-colon to delimit statements. This not only allows for ease of continuation, but it also enables having more than one statement on a single source line. Lisp requires matching parentheses, which has the same benefits. Unfortunately, all of these punctuation marks are just as easy to omit as the COBOL period.
Unfortunately, as in other human languages “I know what you meant” doesn’t guarantee that you actually do know what I meant. Consider the following Ruby example:
1: def big(frack,n,deal)
2: n * ((frack - 1) / deal * 2.2345) + (deal * 12) - (frack / 3) + (frack - deal) + 1
5: print big(6,2,0.25)
This prints 97.13, given those parameters to the function “big”. Now, being the good command-line-oriented programmer that I am, I’d like to continue line 2 so it doesn’t exceed the 80th column:
1: def big(frack,n,deal)
2: n * ((frack - 1) / deal * 2.2345) + (deal * 12) - (frack / 3) + (frack - deal)
3: + 1
6: print big(6,2,0.25)
Now the result is 1. What the frack? Both line 2 and line 3 are syntactically valid in Ruby, because any complete expression can function as a statement. Because they can both be interpreted as independent statements, Ruby does. And since Ruby functions return the last expression evaluated, we get “+ 1”. Adding a semi-colon after the “+ 1” doesn’t help, because Ruby infers one at the end of line 2 if it can. You have to break the line at a different point, such as immediately following an operator, to make the end of the line an invalid end of statement. (I tried enclosing the entire statement in parentheses, and I still get 1! Go figure.)
This wouldn’t be such a big frack’n deal except for the fact that instead of getting an error you just get an unexpected result. That’s a lot more insidious than 1345 COBOL compilation errors, and it underscores the need for near complete code coverage in your tests for applications written in these languages.