dart-lang / dart-lang/language
Introduce additional primitive members
- Dominant language
- TeX
- Stars
- 2.9k
- Forks
- 239
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 14
Description
Cf. https://github.com/dart-lang/language/issues/1296#issuecomment-1109428611, https://github.com/dart-lang/language/issues/1296#issuecomment-1110075607. Issue #1296 contains several other comments that are relevant to this discussion, but the topic is separate from that of #1296, so here is an issue where the addition of primitive members is the main topic.
This topic covers a number of requests for specific enhancements of the expressive power of constant expressions. In particular, the ability to perform sanity checks (in an `assert`) on constructor arguments in a constant constructor has been requested many times.
The language specification currently specifies what it means to have a _primitive_ operator `==`. Essentially, this means that the implementation is guaranteed to be provided by the system, which again makes it possible to guarantee that the corresponding behavior can also be provided during constant expression evaluation at compile time.
We could introduce the corresponding notion of being primitive for any member whose implementation is guaranteed to be system provided, thus extending the set of constant expressions with things like `myList.length`, `mySet.isNotEmpty`, etc. Note that even a member like `Set.contains` could be handled, in spite of the fact that it is not a getter, because the semantics of an invocation is known and can be performed during constant expression evaluation.
Here is a table showing the rather large number of cases where we could do this (based on a table in [this comment by @lrhn](https://github.com/dart-lang/language/issues/1296#issuecomment-1110075607)):
| Member | Receiver static types | Receiver |
| ----------- | --------------------------- | ------------------------------ |
| `length`, `isEmpty`, `isNotEmpty` | `Iterable`, `Map` | value of constant collection literal |
| `contains`, `first`, `last`, `single` | `Iterable` | value of constant collection literal |
| `operator []` | `List` | value of constant list literal |
| `containsKey`, `containsValue`,
`operator []` | `Map` | value of constant map literal |
| `isNaN`, `isFinite`, `sign`, `ceil`, `floor`, `round`,
`ceilToDouble`, `floorToDouble`, `roundToDouble` | `num` | `double`, `int` |
| `substring`, `charCodeAt`, `contains`,
`startsWith`, `endsWith` | `String` | `String` |
We would need a number of extra constraints, including:
- `Pattern` arguments to `String` operations must be strings.
- For `contains` on iterables and `containsValue` on maps, the argument must have primitive equality.
Of course, we could do this to a tiny extent (e.g., just add `length` for lists), or we could do all of it, and we could do it incrementally over time.
Contributor guide
Research direction
Read issue #1296 and the two linked comments first, then compare the proposed primitive members and constraints in this issue's table. The scope is not yet selected: completion would require agreeing which members and restrictions to support and updating the relevant Dart language specification accordingly.
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
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100