Natural languages are
full of redundancy, which makes them easier to understand because we can do more accurate error correction. For example, the phonotactics of a language define which sounds may appear in conjunction with which other sounds; if someone says something that appears to contradict these rules, whether because they mispronounced it or because you misheard it, you have more ability to infer what they meant than if the error were a valid-but-different utterance.
It works the same for programming languages—when designing a notation, you need to consider how you’re going to produce useful error messages when people make common errors, and the simplest way to do that is to add a bit of redundancy so you can infer the programmer’s intent.
For example, I’m working on a dataflow-type language where the syntax for introducing local variables is evocative of a labelled edge in a graph; the original syntax to introduce three variables was this:
-> x y z;
But the problem was that people would forget the semicolon, so this notation would “run away” and continue to gobble up any following identifiers:
// Whoops, accidentally declared 6 variables
-> x y z
foo bar baz
{ … }
The solution? Add commas between the identifiers:
-> x, y, z;
Now if someone forgets a semicolon:
-> x, y, z
foo bar baz
{ … }
The compiler can say “I expected a comma or a semicolon, not this identifier ‘foo’” and additionally use the newline as a hint to offer “I suggest putting a semicolon after ‘z’”.
Likewise, in C-style languages you have to “redundantly” specify the number of arguments to each function at each call site using commas:
foo(1, 2, 3)
In Haskell, for example, that would be written like so:
foo 1 2 3
I find this prettier—it’s less redundant and confers other advantages. But it also suffers from the drawback that now the compiler has to figure out when you have an argument-count mismatch using the
types rather than the
syntax, making it harder to produce good error messages. The commas are an extra hint to the compiler about how many arguments you
intended to pass.