Avoiding the 'dangling else' language problem with mandatory block markers
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;
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
else and always require '
Go takes this approach with explicit block
markers. In Go, an
if requires a delimited block, not a bare
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
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
ifs, and then you have to put
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,
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
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.