Skip to content

Instantly share code, notes, and snippets.

@eernstg
Last active August 29, 2016 08:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eernstg/50a327addd96035d5393a507c0ea2d9a to your computer and use it in GitHub Desktop.
Save eernstg/50a327addd96035d5393a507c0ea2d9a to your computer and use it in GitHub Desktop.
Informal specification of assert statements with general expressions.

Feature: General expressions in assert

The language specification (Aug 19, 2015) states that an assert statement contains a parenthesized conditionalExpression. This feature changes assert to use a plain expression instead.

The motivation for having a conditionalExpression rather than a general expression in this syntactic location is not discussed in the specification, but it is likely to be a kind of safety device: A conditionalExpression covers only a subset of all expressions, and in particular it does not include assignments. An example which is often mentioned is that assert(x = 1) will be prevented syntactically, and the programmer may then note the error and change it to the more likely assert(x == 1).

However, the language specification takes different approaches in other, similar situations: An if statement, while statement, and do .. while statement all accept a general expression as the condition, whereas an argument to logical operators such as && and || must be an equalityExpression, and the argument to the negation operator ! must be a unaryExpression. The choices for logical operators are strongly motivated by the encoding of precedence rules in the grammar, but the choices for statements could as well have been conditionalExpression, had the intention been to avoid those well-known mistakes at the syntactic level.

It should be noted that when assert(x = e) is a mistake, it is relatively rarely the case that the type checks succeed: For x = e to be either of type bool or a function type taking no arguments and returning bool, e would have to have that type as well. This means that the problem is quite likely to be detected by the type checker, even if the grammar allows for a general expression. It should also be noted that no syntactic category can prevent side-effects in Dart, so the strict approach to assert which is taken in the specification does not help avoiding expressions with side-effects, it only prevents one example of side-effects. Finally, the work-around of using assert((x = e)) rather than assert(x = e) will be available if anyone insists on using such a construct.

Currently, the Dart tools treat assert(e) inconsistently: dart2js and the virtual machine parse e as an expression, and the analyzer parses e as a conditionalExpression.

The language team discussed several possible responses to this situation:

  • The language specification could be enforced everywhere, i.e., all tools should then require a conditionalExpression in assert statements, and no changes would be made to the treatment of conditions in if, while, and do .. while statements.
  • The language specification could be changed such that assert statements would accept a general **expression. Again, the syntax for if, while, and do .. while statements would remain unchanged.
  • The language specification could be changed to require a conditionalExpression in assert statements and in if, while, and do .. while statements.

We have chosen the second option, i.e., allowing an expression in assert statements.

The argument against the first option is that the reasons for having the more strict conditionalExpression in assert is weak in its own right, and no such strictness is enforced in other, similar situations. The argument against the third option is that it would be a major breaking change to use a different syntactic category in if, while, and do .. while statements, and the result would not be a strong protection against mistakes anyway. In contrast, the second option brings consistency, and the protection against mistakes is covered in a meaningful manner by the type system already.

Syntax

Only one grammar rule is affected:

assertStatement: assert ‘(’ conditionalExpression ‘)’ ‘;’

is changed to

assertStatement: assert ‘(’ expression ‘)’ ‘;’

Semantics

The description in the language specification (17.17, p125) starting 'The conditional expression e ..' and continuing to the end of the paragraph remains unchanged, except that the word 'conditional' is deleted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment