-
Notifications
You must be signed in to change notification settings - Fork 205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Revise "Control Flow Collections" and add implementation plan. #127
Conversation
The main changes are: - Now that Set literals are on the way, incorporate them into this proposal. - Add a more detailed specification of const collections since we can't rely on imperative dynamic semantics for those. - Couple more clarifications and copy-edits.
* It is a compile-time error if the expression is not a constant | ||
expression. | ||
|
||
The expansion is the value of the expression. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With spread, presumably no longer just a single value. There's a bit of a chicken and egg here in that the two proposals interact - I think one of the two proposals should probably specify how they interact?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to combine the features.
If so, then a spread is not an expression element, it's a spread element.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lasse is right. Added a blurb about spreads now that those are a given. (This proposal was initially written before spreads were accepted.)
|
||
* The then element if the condition expression evaluates to `true`. | ||
|
||
* The else element if the condition is `false` and there is on. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/is on/is one/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
The expansion is: | ||
|
||
* The then element if the condition expression evaluates to `true`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May want to be clear that evaluation short circuits (as we are changing ?: to do). So constant evaluation of the then/else branch doesn't happen unless the condition evaluates to true/false (respectively).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree. The hack here is to say that both branches must be potentially constant expressions, and the one you evaluate must be constant (and hence evaluate to a value).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
### IntelliJ/Grok | ||
|
||
Update to use the latest analyzer with support for the feature. Likely no other | ||
changes explicitly needed. There a are a handful of usability features that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Intellij has its own parser which needs updating. Also github markdown.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. For the latter, I'm guessing you mean: https://github.com/dart-atom/dart, which is what drives Dart syntax highlighting on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure. @devoncarew?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The codemirror and atom grammars are largely regex based. My guess is that there won't be any changes required to support the control flow work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The codemirror and atom grammars are largely regex based. My guess is that there won't be any changes required to support the control flow work.
|
||
Fix: | ||
|
||
```dart |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Risky fix if before or after might have nulls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a note.
elements are allowed. | ||
|
||
* It is a `for` element with an `in` clause. The iterator expression must be | ||
a constant expression. In a constant list literal, the expression must |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It must be a potentially constant expression wrt. the loop variable (and any other "potentially constant variables" in scope, say from nested loops). You probably can't see constructor parameters even if the const collection expression occurs in an initializer list of a const constructor - they won't go past the const
prefix`.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, I think? I find the const stuff pretty confusing.
`for` elements cannot be used in const lists and maps. | ||
* It is an expression element and the expression is constant. | ||
|
||
* It is an `if` element and the condition expression is constant and both body |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Nitpick: or just one body element, in case there is no else
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
This restriction ensures that iterating over the iterable does not call | ||
user code. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(If we integrate spreads into this document, I assume you can spread the same collections that you can iterate).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The spread proposal covers that, yes. I'm not planning to directly merge the two proposal docs, but I'll try to make sure this one calls out to spread where appropriate.
I can merge them if you really want, but I think it will just add to confusion now and be a lot of busywork.
This restriction ensures that iterating over the iterable does not call | ||
user code. | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, the disallowed ones are for(;;)
and await for
(and anything non-constant).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup. Noted.
* It is an `if` element and the condition expression is constant and both body | ||
elements are allowed. | ||
|
||
* It is a `for` element with an `in` clause. The iterator expression must be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which expression is the "iterator" expression, and which is "the expression" (below).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
The expansion is: | ||
|
||
* The then element if the condition expression evaluates to `true`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree. The hack here is to say that both branches must be potentially constant expressions, and the one you evaluate must be constant (and hence evaluate to a value).
* It is a compile-time error if the for element is a C-style loop. We | ||
only allow const `for-in` loops. | ||
|
||
* It is a compile-time error if the iterator expression is not a constant |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"iterator expression" is confusing to me. I'd use "iterable expression" if anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
expression. In a constant list literal, the expression must evaluate to | ||
an object created by a constant list or set literal, as in: | ||
|
||
```dart |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Repeated from just above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, yeah. I reworked this halfway through and forgot to delete the first attempt. Fixed.
const list = [for (i in []) i]; // Error. | ||
``` | ||
|
||
* In the body element, the loop variable is considered a constant |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you should be mentioning "potentially constant expressions". The loop variable is not constant (you can't write [x]
because a list literal must be constant, not just potentially constant), but it is considered so in some cases.
We should clean that up before adding this. @eernstg
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tweaked things.
|
||
1. For each `object` in the iterated collection: | ||
|
||
1. Create a fresh constant and bind it to `object`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Again, not constant, but what we would say for parameters of a const constructor, we just need to generalize that.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
## Phase 1 (Foundation) | ||
|
||
### CFE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will plan to have constant evaluation in the CFE to support constant control-flow collections. We don't have that yet, so that is a prerequisite. CFE team will have to make that a very high priority.
Our implementation will involve a 'block expression' in Kernel which is new and first introduced for this purpose. So depending on how you look at it, the back ends will need to support both a constant pool in .dill files and block expressions.
I'll work on estimates for those tasks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, added a note.
I'm going to go ahead and land then and then send out further modifications as a separate PR.
|
||
Update the IntelliJ parser to support the new syntax. | ||
|
||
Update to use the latest analyzer with support for the feature. There a are a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There a are a
==> There are a
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, thanks.
The main changes are:
Allow
for
in const collections.Now that Set literals are on the way, incorporate them into this
proposal.
Add a more detailed specification of const collections since we can't
rely on imperative dynamic semantics for those.
Couple more clarifications and copy-edits.
I'm not entirely sold on allow
for
in consts. It's quite restricted, but also allows you to make giant constants if you really want to. I'm not sure if it's useful enough in practice to be worth adding. What do you think?