There is a famous parsing ambiguity in many programming languages known as the dangling else , where it's ambiguous which '
if
' statement an '
else
' is associated with. In C, for example, you can write:
if (a) if (b) res = 10; else res = 20;
Which
if
the
else
is associated with is somewhat ambiguous; is it the first or the second? (C provides an answer, as any language that allows this must.)
It's recently struck me that one way to avoid this in language design is to require some form of explicit block markers for the statements inside an
if
(and an
else
). In C terms, to disallow bare statements after
if
and
else
and always require '
{
' and '
}
'.
Go takes this approach with explicit block markers. In Go, an
if
requires a delimited block, not a bare statement , and
else
is similarly unambiguous. A lot of things in Go require blocks, in fact. Python also does this through its implicit blocks that are created through indentation; which
if
an
else
is associated with is both visually and syntactically unambiguous.
(Python allows writing simple '
if
' clauses on one line, but not ones that involve nested
if
s, and then you have to put the
else
on the next line.)
Another Unix language that avoids this ambiguity is the Bourne shell. Although we don't necessarily think about it all that often, the '
then
' and '
fi
' in Bourne shell
if
expressions are block markers, and they're mandatory:
if [ -x /usr/bin/something ]; then ... fi
Although you can write this all on a single line, you can't leave out the markers. This is actually a somewhat tricky case, because '
else
' is a peer with these two markers; however, the result isn't ambiguous:
if [ -x /something ]; then if [ -x /otherthing ]; then ... else .... fi fi
Since we haven't seen a '
fi
', the '
else
' has to be associated with the second '
if
' instead of the first.