OLD | NEW |
(Empty) | |
| 1 # Optional new |
| 2 |
| 3 Author: eernst@. |
| 4 |
| 5 Version: 0.1 (2017-08-15) |
| 6 |
| 7 Status: Under discussion |
| 8 |
| 9 **This document** is an informal specification of the *optional new* feature. |
| 10 **The feature** adds support for omitting the reserved word `new` in instance |
| 11 creation expressions. |
| 12 |
| 13 This feature relies on |
| 14 [optional const](https://gist.github.com/eernstg/4f498836e73d5f003928e8bbe1683d6
8), |
| 15 and it is assumed that the reader knows the optional const feature. Otherwise, |
| 16 this informal specification is derived from a |
| 17 [combined proposal](https://github.com/dart-lang/sdk/blob/master/docs/language/i
nformal/optional-new-const.md) |
| 18 which presents optional new and several other features. |
| 19 |
| 20 ## Motivation |
| 21 |
| 22 In Dart without optional new, the reserved word `new` is present in every |
| 23 expression whose evaluation invokes a constructor (except constant |
| 24 expressions). These expressions are known as *instance creation expressions*. If |
| 25 `new` is removed from such an instance creation expression, the remaining phrase |
| 26 is still syntactically correct in almost all cases, and the required grammar |
| 27 update that makes them all syntactically correct is exactly the one that is |
| 28 specified for |
| 29 [optional const](https://gist.github.com/eernstg/4f498836e73d5f003928e8bbe1683d6
8). |
| 30 |
| 31 Assuming the grammar update in |
| 32 [optional const](https://gist.github.com/eernstg/4f498836e73d5f003928e8bbe1683d6
8), |
| 33 all instance creation expressions can technically omit the `new` because tools |
| 34 (compilers, analyzers) are able to parse these expressions, and they are able |
| 35 to recognize that they denote instance creations (rather than, say, static |
| 36 function invocations), because the part before the left parenthesis is |
| 37 statically known to denote a constructor. |
| 38 |
| 39 For instance, `p.C.foo` may resolve statically to a constructor named `foo` in |
| 40 a class `C` imported with prefix `p`. Similarly, `D` may resolve to a class, in |
| 41 which case `D(42)` is statically known to be a constructor invocation because |
| 42 the other interpretation is statically known to be incorrect (that is, cf. |
| 43 section '16.14.3 Unqualified Invocation' in the language specification, |
| 44 evaluating `(D)(42)`: `(D)` is an instance of `Type` which is not a function |
| 45 type and does not have a method named `call`). |
| 46 |
| 47 For human readers, it may be helpful to document that a particular expression |
| 48 is guaranteed to yield a fresh instance, and this is the most common argument |
| 49 why `new` should *not* be omitted. However, Dart already allows instance |
| 50 creation expressions to invoke a factory constructor, so Dart developers never |
| 51 had any local guarantees that any particular expression would yield a fresh |
| 52 object. |
| 53 |
| 54 Developers may thus prefer to omit `new` in order to obtain more concise code, |
| 55 and possibly also in order to achieve greater uniformity among invocations of |
| 56 constructors and other invocations, e.g., of static or global functions. |
| 57 |
| 58 With that in mind, this proposal allows instance creation expressions to omit |
| 59 the `new` in all cases, but also preserves the permission to include `new` in |
| 60 all cases. It is a matter of style to use `new` in a manner that developers |
| 61 find helpful. |
| 62 |
| 63 ## Syntax |
| 64 |
| 65 The syntax changes associated with this feature are the following: |
| 66 |
| 67 ``` |
| 68 postfixExpression ::= |
| 69 assignableExpression postfixOperator | |
| 70 constructorInvocation | // NEW |
| 71 primary selector* |
| 72 constructorInvocation ::= // NEW |
| 73 typeName typeArguments '.' identifier arguments |
| 74 assignableExpression ::= |
| 75 SUPER unconditionalAssignableSelector | |
| 76 typeName typeArguments '.' identifier arguments |
| 77 (arguments* assignableSelector)+ | // NEW |
| 78 identifier | |
| 79 primary (arguments* assignableSelector)+ |
| 80 ``` |
| 81 |
| 82 This grammar update is identical to the grammar update for optional const. |
| 83 For more information including a complete grammar, please consult |
| 84 [that specification](https://gist.github.com/eernstg/4f498836e73d5f003928e8bbe16
83d68). |
| 85 |
| 86 ## Static analysis |
| 87 |
| 88 We specify a type directed source code transformation which eliminates the |
| 89 feature. The static analysis proceeds to work on the transformed program. |
| 90 |
| 91 *Similarly to optional const, this means that the feature is "static semantic |
| 92 sugar". We do not specify the dynamic semantics for this feature, because the |
| 93 feature is eliminated in this transformation step.* |
| 94 |
| 95 We need to treat expressions differently in different locations, hence the |
| 96 following definition: An expression _e_ is said to *occur in a constant |
| 97 context*, |
| 98 |
| 99 - if _e_ is an immediate subexpression of a constant list literal or a constant |
| 100 map literal. |
| 101 - if _e_ is an immediate subexpression of a constant object expression. |
| 102 - if _e_ is the initializing expression of a constant variable declaration. |
| 103 - if _e_ is the default value of a formal parameter. **[This case is under discu
ssion and may be removed]** |
| 104 - if _e_ is an immediate subexpression of an expression which occurs in a |
| 105 constant context. |
| 106 |
| 107 We define *new/const insertion* as the following transformation: |
| 108 |
| 109 - if _e_ occurs in a constant context, replace `e` by `const e`. |
| 110 - otherwise, replace `e` by `new e` |
| 111 |
| 112 An expression on one of the following forms must be modified to be or |
| 113 contain a `constantObjectExpression` or `newExpression` as described: |
| 114 |
| 115 With a `postfixExpression` _e_, |
| 116 |
| 117 - if _e_ is on the form `constructorInvocation`, i.e., |
| 118 `typeName typeArguments '.' identifier arguments` then perform |
| 119 new/const insertion on _e_. |
| 120 - if _e_ is on the form |
| 121 `typeIdentifier arguments` where `typeIdentifier` denotes a class then |
| 122 perform new/const insertion on _e_. |
| 123 - if _e_ is on the form |
| 124 `identifier1 '.' identifier2 arguments` where `identifier1` denotes |
| 125 a class and `identifier2` is the name of a named constructor in that class, |
| 126 or `identifier1` denotes a prefix for a library _L_ and `identifier2` denotes |
| 127 a class exported by _L_, perform new/const insertion on _e_. |
| 128 - if _e_ is on the form |
| 129 `identifier1 '.' typeIdentifier '.' identifier2 arguments` where |
| 130 `identifier1` denotes a library prefix for a library _L_, `typeIdentifier` |
| 131 denotes a class _C_ exported by _L_, and `identifier2` is the name of a named |
| 132 constructor in _C_, perform new/const insertion on _e_. |
| 133 |
| 134 ## Dynamic Semantics |
| 135 |
| 136 There is no dynamic semantics to specify for this feature because it is |
| 137 eliminated by code transformation. |
| 138 |
| 139 ## Interplay with optional const |
| 140 |
| 141 The optional new and optional const feature can easily be introduced at the same |
| 142 time: Just update the grammar as specified for optional const (and mentioned |
| 143 again here) and use the program transformation specified in this document. The |
| 144 program transformation in this document subsumes the program transformation |
| 145 specified for optional const, and hence this will provide support for both |
| 146 features. |
| 147 |
| 148 ## Revisions |
| 149 |
| 150 - 0.1 (2017-08-15) Stand-alone proposal for optional new created, using version |
| 151 0.8 of the combined proposal |
| 152 [optional-new-const.md](https://github.com/dart-lang/sdk/blob/master/docs/lang
uage/informal/optional-new-const.md) |
| 153 as the starting point. |
OLD | NEW |