False cognates and syntax
There is a common refrain spoken even by otherwise intelligent and informed people: “syntax doesn’t matter”. What they mean, of course, is that it is the semantics of a programming language that define its capabilities and use cases, not the specifics of expressing them.
To a degree they are right. Syntax is horribly over-rated by people and, indeed, fixation on Syntax Über Alles™ is responsible for the blight of curly braces that infects the computing landscape and holds back adoption of more advanced techniques more suited to various problem domains of computing.
But I still disagree with them.
Why syntax is important
Syntax is, in my opinion, very important. I come to this conclusion from the direction of a (natural) language teacher, however, and not a mathematician or computer scientist so I suspect I’m bringing something to the equation that mathematicians et al are simply not usually familiar with: the false cognate.
I agree that the specifics of syntax are unimportant and that people who won’t adopt a language because it uses begin … end instead of { … } cannot truly call themselves software developers (or computer scientists). This is simply the dumbest conceivable reason for not learning a language, roughly equivalent to saying of natural languages “I’m not going to learn Korean because they use funny-looking squiggles instead of the Latin alphabet.” Learning the syntax of a language in a familiar domain or paradigm is a trivial thing. It shouldn’t take much more than two weeks to get productive and a month to be decently good at it. What is important, however, is that the syntax of another language—especially one in another paradigm—is sufficiently different that you avoid false cognates.
False cognates
So what is a false cognate? Well consider your reaction if I held something out to you and said, “Gift?” Would you thank me or politely demur? Would your reaction change if you knew I was speaking German? (For those not in on the joke, “gift” in English is a synonym for “present” while in German “Gift” is “poison”.) The confusion of poison for present is an example of a false cognate. In natural language, especially in related languages, false cognates abound.
In programming languages false cognates also abound when syntax is too similar. Consider, for example, the humble if statement. In imperative languages the succeeding branch is mandatory but the alternative branch—the else—is usually optional. In functional languages, however, where everything is an expression that has a value, the else block (or its equivalent) is mandatory. You simply cannot have an empty or missing else block. (Further, in languages with strict type systems, the else block has to have the same type as the if block, typically.)
The way if statements/expressions work differs across paradigms and having them be syntactically identical is a bad design. A C programmer, for example, writing in a hypothetical functional programming language with a C-like syntax will be constantly frustrated as they code statements like this, only to have the compiler vomit at them:
if (my_condition)
{
calculate_some_stuff();
}
In cases like this, I submit having conditionals look alien helps remind the programmer that the semantics are alien. I submit, in other words, that, say, Prolog’s conditionals are superior for their purpose:
( Condition -> evaluate_some_stuff()
; evaluate_some_other_stuff_instead()).
The very different syntax is a very strong reminder that very different semantics underlie the code.
A few more examples
Still don’t believe me? Well, here are two almost perfect cases of false cognates causing problems:
- Haskell’s
returnfunction, part of the monad definition, confuses the ever-loving Hell out of people who come from pretty much any other language in the world. (After all these years, I still have no idea how putting something into a monad is a return!) Selecting that as the name was a poor design choice that has caused monads to be even more of a stumbling block than they already are because of the false cognate with whatreturnmeans in practically any other language anywhere. - Erlang’s
ifexpression is probably the single worst-named keyword this side of joke languages like INTERCAL or Brainfuck. Experienced, knowledgeable Erlang programmers will often opine thatifstatements should be avoided almost, but not quite, at all costs because they cause confusion and are semantically difficult. I submit that the “semantic difficulty” and confusion is almost purely a result of the false cognate with the keyword. After all the same developers have no difficulties with guard expressions on function heads or in case expressions. Perhaps if a keyword likeguardwere used instead?...
Reddit flamebait
Now I know already that I’m going to get emails from people who will explain things like, “If you squint right and rotate your head 47° to the left while covering your left eye, the use of return in Haskell is very similar to the use of it in other languages.” To this I say, “Poppycock!” If you have to do bizarre intellectual gyrations to justify a cognate, it’s not a cognate. Use a different, more descriptive name. Stop making things more difficult in the long term just because some whiners are unwilling to learn the trivialities of a new syntax in the short.