dart-lang / dart-lang/language
Method-to-function conversion
- Dominant language
- TeX
- Stars
- 2.9k
- Forks
- 239
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 14
Description
Discussions in #357 strongly suggest that we will support a primary expression of the form `'.' ` (e.g., `.foo`). The semantics of such terms will most likely be determined by the context type.
This issue is a proposal that we should generalize the semantics of this syntax to cover an additional case: If `.foo` is used in a context where an expression of type `R Function(T)` is expected then it is implicitly transformed into `(T x) => x.foo`. Similar conversions are applied when a chain of selectors are present, e.g., `.foo(1)?.whereType()[4]` would become `(T x) => x.foo(1)?.whereType()[4]`. For example:
```dart
void main() {
// Proposed form.
var xs1 = [1, 2, 3].map(.toString());
// Same thing, written without this feature.
var xs2 = [1, 2, 3].map((int x) => x.toString());
}
```
This feature will only enable a small amount of abbreviation, but it is likely to be convenient to have in a large number of invocations of `map` and `forEach` on collections, as well as many other situations involving callback arguments, and this would justify having the feature even though it doesn't do a lot each time it is used.
# Proposal
## Syntax
The grammar is adjusted as follows:
```ebnf
::= // Add one alternative at the end.
: ...
| '.'
```
*Several other proposals are expected to introduce this new kind of expression. If and when we get any of those proposed features then this grammar change is not needed.*
## Static analysis
Assume that `e` is an expression of the form `.id s1 .. sk` where `id` is an identifier and `sj` is derived from ``, for `j` in `1 .. k`, and `e` is not a subexpression of an expression of the form `.id s1 .. sk .. sn` where `sj` is derived from `` for `j` in `1 .. n` *(that is, `e` already contains all the selectors)*.
If the context type of `e` is of the form `R Function(T)` for some types `R` and `T` then `e` is implicitly transformed into `((T x) => x.e s1 .. sk)`, where `x` is a fresh name.
*If the resulting function literal is or contains a compile-time error then it should be reported in terms of a failure to perform the method-to-function conversion, plus information about the error that arises after the conversion. For example, `.foo` may be an error in the context of `R Function(T)` because `T` isn't an interface type that declares a member named `foo`, and there is no extension method named `foo` which is applicable to a receiver of type `T`; or `x.foo` is an expression that has no errors when `x` has type `T`, but that type is not a subtype of `R`, and hence the function literal as a whole isn't assignable to `R Function(T)`.*
Contributor guide
Research direction
Start with this proposal and the discussions in issue #357, then review the proposed grammar and static-analysis rules for `.identifier` expressions. Done means the method-to-function conversion proposal has a decided specification and its behavior, including selector chains and conversion errors, is covered by the language implementation and validation work.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- dart
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100