| Index: docs/language/informal/optional-new.md
|
| diff --git a/docs/language/informal/optional-new.md b/docs/language/informal/optional-new.md
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..0eddb49bdba6b95836320cf730cff2c5141a5978
|
| --- /dev/null
|
| +++ b/docs/language/informal/optional-new.md
|
| @@ -0,0 +1,153 @@
|
| +# Optional new
|
| +
|
| +Author: eernst@.
|
| +
|
| +Version: 0.1 (2017-08-15)
|
| +
|
| +Status: Under discussion
|
| +
|
| +**This document** is an informal specification of the *optional new* feature.
|
| +**The feature** adds support for omitting the reserved word `new` in instance
|
| +creation expressions.
|
| +
|
| +This feature relies on
|
| +[optional const](https://gist.github.com/eernstg/4f498836e73d5f003928e8bbe1683d68),
|
| +and it is assumed that the reader knows the optional const feature. Otherwise,
|
| +this informal specification is derived from a
|
| +[combined proposal](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/optional-new-const.md)
|
| +which presents optional new and several other features.
|
| +
|
| +## Motivation
|
| +
|
| +In Dart without optional new, the reserved word `new` is present in every
|
| +expression whose evaluation invokes a constructor (except constant
|
| +expressions). These expressions are known as *instance creation expressions*. If
|
| +`new` is removed from such an instance creation expression, the remaining phrase
|
| +is still syntactically correct in almost all cases, and the required grammar
|
| +update that makes them all syntactically correct is exactly the one that is
|
| +specified for
|
| +[optional const](https://gist.github.com/eernstg/4f498836e73d5f003928e8bbe1683d68).
|
| +
|
| +Assuming the grammar update in
|
| +[optional const](https://gist.github.com/eernstg/4f498836e73d5f003928e8bbe1683d68),
|
| +all instance creation expressions can technically omit the `new` because tools
|
| +(compilers, analyzers) are able to parse these expressions, and they are able
|
| +to recognize that they denote instance creations (rather than, say, static
|
| +function invocations), because the part before the left parenthesis is
|
| +statically known to denote a constructor.
|
| +
|
| +For instance, `p.C.foo` may resolve statically to a constructor named `foo` in
|
| +a class `C` imported with prefix `p`. Similarly, `D` may resolve to a class, in
|
| +which case `D(42)` is statically known to be a constructor invocation because
|
| +the other interpretation is statically known to be incorrect (that is, cf.
|
| +section '16.14.3 Unqualified Invocation' in the language specification,
|
| +evaluating `(D)(42)`: `(D)` is an instance of `Type` which is not a function
|
| +type and does not have a method named `call`).
|
| +
|
| +For human readers, it may be helpful to document that a particular expression
|
| +is guaranteed to yield a fresh instance, and this is the most common argument
|
| +why `new` should *not* be omitted. However, Dart already allows instance
|
| +creation expressions to invoke a factory constructor, so Dart developers never
|
| +had any local guarantees that any particular expression would yield a fresh
|
| +object.
|
| +
|
| +Developers may thus prefer to omit `new` in order to obtain more concise code,
|
| +and possibly also in order to achieve greater uniformity among invocations of
|
| +constructors and other invocations, e.g., of static or global functions.
|
| +
|
| +With that in mind, this proposal allows instance creation expressions to omit
|
| +the `new` in all cases, but also preserves the permission to include `new` in
|
| +all cases. It is a matter of style to use `new` in a manner that developers
|
| +find helpful.
|
| +
|
| +## Syntax
|
| +
|
| +The syntax changes associated with this feature are the following:
|
| +
|
| +```
|
| +postfixExpression ::=
|
| + assignableExpression postfixOperator |
|
| + constructorInvocation | // NEW
|
| + primary selector*
|
| +constructorInvocation ::= // NEW
|
| + typeName typeArguments '.' identifier arguments
|
| +assignableExpression ::=
|
| + SUPER unconditionalAssignableSelector |
|
| + typeName typeArguments '.' identifier arguments
|
| + (arguments* assignableSelector)+ | // NEW
|
| + identifier |
|
| + primary (arguments* assignableSelector)+
|
| +```
|
| +
|
| +This grammar update is identical to the grammar update for optional const.
|
| +For more information including a complete grammar, please consult
|
| +[that specification](https://gist.github.com/eernstg/4f498836e73d5f003928e8bbe1683d68).
|
| +
|
| +## Static analysis
|
| +
|
| +We specify a type directed source code transformation which eliminates the
|
| +feature. The static analysis proceeds to work on the transformed program.
|
| +
|
| +*Similarly to optional const, this means that the feature is "static semantic
|
| +sugar". We do not specify the dynamic semantics for this feature, because the
|
| +feature is eliminated in this transformation step.*
|
| +
|
| +We need to treat expressions differently in different locations, hence the
|
| +following definition: An expression _e_ is said to *occur in a constant
|
| +context*,
|
| +
|
| +- if _e_ is an immediate subexpression of a constant list literal or a constant
|
| + map literal.
|
| +- if _e_ is an immediate subexpression of a constant object expression.
|
| +- if _e_ is the initializing expression of a constant variable declaration.
|
| +- if _e_ is the default value of a formal parameter. **[This case is under discussion and may be removed]**
|
| +- if _e_ is an immediate subexpression of an expression which occurs in a
|
| + constant context.
|
| +
|
| +We define *new/const insertion* as the following transformation:
|
| +
|
| +- if _e_ occurs in a constant context, replace `e` by `const e`.
|
| +- otherwise, replace `e` by `new e`
|
| +
|
| +An expression on one of the following forms must be modified to be or
|
| +contain a `constantObjectExpression` or `newExpression` as described:
|
| +
|
| +With a `postfixExpression` _e_,
|
| +
|
| +- if _e_ is on the form `constructorInvocation`, i.e.,
|
| + `typeName typeArguments '.' identifier arguments` then perform
|
| + new/const insertion on _e_.
|
| +- if _e_ is on the form
|
| + `typeIdentifier arguments` where `typeIdentifier` denotes a class then
|
| + perform new/const insertion on _e_.
|
| +- if _e_ is on the form
|
| + `identifier1 '.' identifier2 arguments` where `identifier1` denotes
|
| + a class and `identifier2` is the name of a named constructor in that class,
|
| + or `identifier1` denotes a prefix for a library _L_ and `identifier2` denotes
|
| + a class exported by _L_, perform new/const insertion on _e_.
|
| +- if _e_ is on the form
|
| + `identifier1 '.' typeIdentifier '.' identifier2 arguments` where
|
| + `identifier1` denotes a library prefix for a library _L_, `typeIdentifier`
|
| + denotes a class _C_ exported by _L_, and `identifier2` is the name of a named
|
| + constructor in _C_, perform new/const insertion on _e_.
|
| +
|
| +## Dynamic Semantics
|
| +
|
| +There is no dynamic semantics to specify for this feature because it is
|
| +eliminated by code transformation.
|
| +
|
| +## Interplay with optional const
|
| +
|
| +The optional new and optional const feature can easily be introduced at the same
|
| +time: Just update the grammar as specified for optional const (and mentioned
|
| +again here) and use the program transformation specified in this document. The
|
| +program transformation in this document subsumes the program transformation
|
| +specified for optional const, and hence this will provide support for both
|
| +features.
|
| +
|
| +## Revisions
|
| +
|
| +- 0.1 (2017-08-15) Stand-alone proposal for optional new created, using version
|
| + 0.8 of the combined proposal
|
| + [optional-new-const.md](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/optional-new-const.md)
|
| + as the starting point.
|
|
|