Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(381)

Side by Side Diff: docs/language/informal/optional-const.md

Issue 3005833002: Adjusted the optional-const/new specs. (Closed)
Patch Set: Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Optional const 1 # Optional const
2 2
3 Author: eernst@. 3 Author: eernst@.
4 4
5 Version: 0.1 (2017-08-10) 5 Version: 0.2 (2017-08-30)
6 6
7 Status: Under discussion 7 Status: Under implementation.
8 8
9 **This document** is an informal specification of the *optional const* feature. 9 **This document** is an informal specification of the *optional const* feature.
10 **The feature** adds support for omitting the reserved word `const` in list and 10 **The feature** adds support for omitting the reserved word `const` in list and
11 map literals and constant object expressions, in locations where `const` is 11 map literals and constant object expressions, in locations where `const` is
12 currently required. 12 currently required.
13 13
14 This informal specification is built on a 14 This informal specification is built on a
15 [combined proposal](https://github.com/dart-lang/sdk/blob/master/docs/language/i nformal/optional-new-const.md) 15 [combined proposal](https://github.com/dart-lang/sdk/blob/master/docs/language/i nformal/optional-new-const.md)
16 which presents optional const and several other features. 16 which presents optional const and several other features.
17 17
18 ## Motivation 18 ## Motivation
19 19
20 In Dart without optional const, complex constant expressions often contain many 20 In Dart without optional const, complex constant expressions often contain many
21 occurrences of `const` on list and map literals, and on constant object 21 occurrences of `const` on list and map literals, and on constant object
22 expressions. Subexpressions of constant expressions are themselves required to 22 expressions. Subexpressions of constant expressions are themselves required to
23 be constant expressions, and this means that `const` on a nested list or map 23 be constant expressions, and this means that `const` on a nested list or map
24 literal provides no extra information: It is a compile-time error if that 24 literal provides no extra information: It is a compile-time error if that
25 `const` is omitted. Similarly, it is a compile-time error if a nested constant 25 `const` is omitted. Similarly, it is a compile-time error if a nested constant
26 object expression is modified to use `new` rather than `const`. In that 26 object expression is modified to use `new` rather than `const`. In that
27 situation it carries no extra information whether `new` or `const` is used, and 27 situation it carries no extra information whether `new` or `const` is used, and
28 it is even possible to omit the reserved word entirely. It is also required for 28 it is even possible to omit the reserved word entirely. It is also required for
29 certain other expressions to be constant, e.g., default values on formal 29 certain other expressions to be constant, e.g., initializing expressions for
30 parameters and initializing expressions for constant variables. 30 constant variables.
31 31
32 In all these cases the presence of `const` is required, and hence such a 32 In all these cases the presence of `const` is required, and hence such a
33 `const` may be inferred by compilers and similar tools if it is omitted. 33 `const` may be inferred by compilers and similar tools if it is omitted.
34 34
35 Developers reading the source code are likely to find it easy to understand 35 Developers reading the source code are likely to find it easy to understand
36 that a required `const` was omitted and is implied, because the reason for 36 that a required `const` was omitted and is implied, because the reason for
37 the requirement is visible in the enclosing syntax: The expression where 37 the requirement is visible in the enclosing syntax: The expression where
38 `const` is inferred is a subexpression of an expression with `const`, it is 38 `const` is inferred is a subexpression of an expression with `const` or it
39 used to initialize a constant variable, or it is a default value for a formal 39 is used in another situation where a constant value is required, e.g., to
40 parameter. 40 initialize a constant variable.
41 41
42 In summary, tools do not need the required occurrences of `const`, and they 42 In summary, tools do not need the required occurrences of `const`, and they
43 are also unimportant for developers. Conversely, omitting required occurrences 43 are also unimportant for developers. Conversely, omitting required occurrences
44 of `const` will sometimes make large expressions substantially more concise 44 of `const` will sometimes make large expressions substantially more concise
45 and readable, and also more convenient to write. Here is an example: 45 and readable, and also more convenient to write. Here is an example:
46 46
47 ```dart 47 ```dart
48 const myMap = const { 48 const myMap = const {
49 "a": const [const C("able"), const C("apple"), const C("axis")], 49 "a": const [const C("able"), const C("apple"), const C("axis")],
50 "b": const [const C("banana"), const C("bold"), const C("burglary")], 50 "b": const [const C("banana"), const C("bold"), const C("burglary")],
(...skipping 22 matching lines...) Expand all
73 In order to support the optional const feature, the Dart grammar is modified as 73 In order to support the optional const feature, the Dart grammar is modified as
74 follows. 74 follows.
75 75
76 ``` 76 ```
77 postfixExpression ::= 77 postfixExpression ::=
78 assignableExpression postfixOperator | 78 assignableExpression postfixOperator |
79 constructorInvocation | // NEW 79 constructorInvocation | // NEW
80 primary selector* 80 primary selector*
81 constructorInvocation ::= // NEW 81 constructorInvocation ::= // NEW
82 typeName typeArguments '.' identifier arguments 82 typeName typeArguments '.' identifier arguments
83 assignableExpression ::=
84 SUPER unconditionalAssignableSelector |
85 typeName typeArguments '.' identifier arguments
86 (arguments* assignableSelector)+ | // NEW
87 identifier |
88 primary (arguments* assignableSelector)+
89 ``` 83 ```
90 84
91 *A complete grammar which includes these changes is available
92 [here](https://gist.github.com/eernstg/024a997f4f8c7ef885d459c3703a35f6).*
93
94 *Note that the alternative which is added in the rule for `assignableExpression`
95 is required in order to allow expressions which are obtained by constructing a
96 constant object expression in Dart without optional const and removing the
97 `const`. That particular case will not match any of the cases where the `const`
98 is required (because `assignableExpression` is only used in contexts which
99 cannot be constant expressions). However, this approach yields syntactic support
100 for omitting `const` in every `constantObjectExpression`, and it also allows for
101 omitting `new` from every `newExpression`, which is useful for the
102 associated
103 [optional new feature](https://gist.github.com/eernstg/7e819b44acd8dd9d71f0cc510 b618a3d).*
104
105 *The grammar only needs to be adjusted for one case, namely invocations of named 85 *The grammar only needs to be adjusted for one case, namely invocations of named
106 constructors for generic classes. In this case we can derive expressions like 86 constructors for generic classes. In this case we can derive expressions like
107 `const Foo<int>.bar()`, and the corresponding `Foo<int>.bar()` is not derivable 87 `const Foo<int>.bar()`, and the corresponding `Foo<int>.bar()` is not derivable
108 in the same situations where the variant with `const` can be derived. In other 88 in the same situations where the variant with `const` can be derived. In other
109 words, we must add support for constructs like `Foo<int>.bar()` as part of a 89 words, we must add support for constructs like `Foo<int>.bar()` as part of a
110 `postfixExpression` and as part of an `assignableExpression`. For all other 90 `postfixExpression` and as part of an `assignableExpression`. For all other
eernst 2017/08/30 16:51:51 Oops, adjusted the text here to avoid talking abou
111 situations, the variant with `const` becomes a construct which is already 91 situations, the variant with `const` becomes a construct which is already
112 syntactically correct Dart when the `const` is removed. For instance `const 92 syntactically correct Dart when the `const` is removed. For instance `const
113 C(42)` becomes `C(42)` which could already be a function invocation and is hence 93 C(42)` becomes `C(42)` which could already be a function invocation and is hence
114 already allowed syntactically.* 94 already allowed syntactically.*
115 95
116 ## Static analysis 96 ## Static analysis
117 97
118 We specify a type directed source code transformation which eliminates the 98 We specify a type directed source code transformation which eliminates the
119 feature. The static analysis proceeds to work on the transformed program. 99 feature. The static analysis proceeds to work on the transformed program.
120 100
121 *This means that the feature is "sugar", but because of the need to refer 101 *This means that the feature is "sugar", but because of the need to refer
122 to types it could be described as static semantic sugar rather than 102 to types it could be described as static semantic sugar rather than
123 syntactic sugar. We do not specify the dynamic semantics for this feature, 103 syntactic sugar. We do not specify the dynamic semantics for this feature,
124 because the feature is eliminated in this transformation step.* 104 because the feature is eliminated in this transformation step.*
125 105
106 We need to treat expressions differently in different locations, hence the
107 following definition: An expression _e_ is said to *occur in a constant
108 context*,
109
110 - if _e_ is an immediate subexpression of a constant list literal or a
111 constant map literal.
112 - if _e_ is an immediate subexpression of a constant object expression.
113 - if _e_ is the initializing expression of a constant variable declaration.
114 - if _e_ is an immediate subexpression of an expression which occurs in a
115 constant context.
116
117 *Note that the default value of an optional formal parameter is not a
118 constant context. This choice reserves some freedom to modify the
119 semantics of default values.*
120
121 For the purposes of describing the transformation we need the following
122 syntactic entity:
123
124 ```
125 assignableExpressionTail ::=
Lasse Reichstein Nielsen 2017/08/30 09:29:49 Is it referenced from anywhere?
eernst 2017/08/30 16:51:51 It used to be referenced from the rewrite rules be
126 arguments assignableSelector (arguments* assignableSelector)*
127 ```
128
126 An expression on one of the following forms must be modified to be or 129 An expression on one of the following forms must be modified to be or
127 contain a `constantObjectExpression` as described: 130 contain a `constantObjectExpression` as described:
128 131
129 With a `postfixExpression` _e_, 132 With a `postfixExpression` _e_ occurring in a constant context,
130 133
131 - if _e_ is on the form `constructorInvocation`, i.e., 134 - if _e_ is on the form `constructorInvocation` then replace _e_ by
132 `typeName typeArguments '.' identifier arguments` then replace _e_ by 135 `const` _e_.
133 `'const' typeName typeArguments '.' identifier arguments`.
134 - if _e_ is on the form 136 - if _e_ is on the form
135 `typeIdentifier arguments` where `typeIdentifier` denotes a class then 137 `typeIdentifier arguments` where `typeIdentifier` denotes a class then
136 replace _e_ by 138 replace _e_ by `const` _e_.
137 `'const' typeIdentifier arguments`.
138 - if _e_ is on the form 139 - if _e_ is on the form
139 `identifier1 '.' identifier2 arguments` where `identifier1` denotes 140 `identifier1 '.' identifier2 arguments` where `identifier1` denotes
140 a class and `identifier2` is the name of a named constructor in that class, 141 a class and `identifier2` is the name of a named constructor in that
141 or `identifier1` denotes a prefix for a library _L_ and `identifier2` denotes 142 class, or `identifier1` denotes a prefix for a library _L_ and
142 a class exported by _L_, replace _e_ by 143 `identifier2` denotes a class exported by _L_, replace _e_ by
143 `'const' identifier1 '.' identifier2 arguments`. 144 `const` _e_.
144 - if _e_ is on the form 145 - if _e_ is on the form
145 `identifier1 '.' typeIdentifier '.' identifier2 arguments` where 146 `identifier1 '.' typeIdentifier '.' identifier2 arguments` where
146 `identifier1` denotes a library prefix for a library _L_, `typeIdentifier` 147 `identifier1` denotes a library prefix for a library _L_,
147 denotes a class _C_ exported by _L_, and `identifier2` is the name of a named 148 `typeIdentifier` denotes a class _C_ exported by _L_, and `identifier2`
148 constructor in _C_, replace _e_ by 149 is the name of a named constructor in _C_, replace _e_ by
149 `'const' identifier1 '.' typeIdentifier '.' identifier2 arguments`. 150 `const` _e_.
151
152 For a list literal _e_ occurring in a constant context, replace _e_ by
153 `const` _e_. For a map literal _e_ occurring in a constant context,
154 replace _e_ by `const` _e_.
150 155
151 *In short, in these specific situations: "just add `const`". It is easy to 156 *In short, in these specific situations: "just add `const`". It is easy to
152 verify that each of the replacements can be derived from 157 verify that each of the replacements can be derived from
153 `constObjectExpression`, which can be derived from `postfixExpression` via 158 `constObjectExpression`, which can be derived from `postfixExpression` via
154 `primary selector*`; hence the transformation preserves syntactic correctness.* 159 `primary selector*`. Hence, the transformation preserves syntactic
160 correctness.*
155 161
156 The remaining static analysis proceeds to work on the transformed program. 162 The remaining static analysis proceeds to work on the transformed program.
157 163
158 *It is possible that this transformation will create 164 *It is possible that this transformation will create
159 `constObjectExpressions` which violate the constraints on constant object 165 `constObjectExpressions` which violate the constraints on constant object
160 expressions. It is recommended that the error messages emitted by tools in 166 expressions, e.g., when `const [[new A()]]` is transformed to
161 response to such violations include information about the transformative 167 `const [const [new A()]]` where the inner list is an error that was created
162 step that added this `const` to the given construct and informs developers 168 by the transformation (so the error was moved from the outer to the inner
163 that they may add `new` explicitly if that matches the intention.* 169 list). It is recommended that the error messages emitted by tools in response
170 to such violations include information about the transformation.*
164 171
165 ## Dynamic Semantics 172 ## Dynamic Semantics
166 173
167 There is no dynamic semantics to specify for this feature because it is 174 There is no dynamic semantics to specify for this feature because it is
168 eliminated by code transformation. 175 eliminated by code transformation.
169 176
170 177
171 ## Revisions 178 ## Revisions
172 179
173 - 0.1 (2017-08-10) Stand-alone proposal for optional const created, using 180 - 0.2 (2017-08-30) Updated the document to specify the previously missing
174 version 0.8 of the combined proposal 181 transformations for composite literals (lists and maps), and to specify a
182 no-magic approach (where no `const` is introduced except when forced by
183 the syntactic context).
184
185 - 0.1 (2017-08-10) Stand-alone informal specification for optional const
186 created, using version 0.8 of the combined proposal
175 [optional-new-const.md](https://github.com/dart-lang/sdk/blob/master/docs/lang uage/informal/optional-new-const.md) 187 [optional-new-const.md](https://github.com/dart-lang/sdk/blob/master/docs/lang uage/informal/optional-new-const.md)
176 as the starting point. 188 as the starting point.
OLDNEW
« no previous file with comments | « no previous file | docs/language/informal/optional-new.md » ('j') | docs/language/informal/optional-new.md » ('J')

Powered by Google App Engine
This is Rietveld 408576698