Skip to content
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

Merged
merged 2 commits into from
Dec 13, 2018

Conversation

munificent
Copy link
Member

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?

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.
Copy link
Member

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?

Copy link
Member

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.

Copy link
Member Author

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.
Copy link
Member

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/

Copy link
Member Author

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`.
Copy link
Member

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).

Copy link
Member

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).

Copy link
Member Author

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
Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure. @devoncarew?

Copy link
Member

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.

Copy link
Member

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
Copy link
Member

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.

Copy link
Member Author

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
Copy link
Member

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`.

Copy link
Member Author

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
Copy link
Member

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)

Copy link
Member Author

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.

Copy link
Member

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).

Copy link
Member Author

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.


Copy link
Member

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).

Copy link
Member Author

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
Copy link
Member

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).

Copy link
Member Author

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`.
Copy link
Member

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
Copy link
Member

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.

Copy link
Member Author

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repeated from just above?

Copy link
Member Author

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
Copy link
Member

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

Copy link
Member Author

@munificent munificent Dec 13, 2018

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`.
Copy link
Member

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.)

Copy link
Member Author

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
Copy link
Contributor

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.

Copy link
Member Author

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.
@munificent munificent merged commit 598368e into master Dec 13, 2018
@munificent munificent deleted the revise-control-flow-collections branch December 13, 2018 21:06

Update the IntelliJ parser to support the new syntax.

Update to use the latest analyzer with support for the feature. There a are a
Copy link
Member

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

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants