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;
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.
Comments on this page:
|
|