-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Make yield an expression, not a statement, and let the iterator provide the next value. #32831
Comments
This is possible, and even without being breaking. We could change abstract class CoIterable<E, V> extends Iterable<E> {
Coroutine<E, V> get iterator;
}
abstract class Coroutine<E, V> implements Iterator<E> {
bool moveNext([V value]);
} Then you could do: Coiterable<int, int> sequencer([int start = 0]) sync* {
int counter = start;
while (true) {
counter = ((yield counter) ?? counter) + 1;
}
}
main() {
var c = sequencer(10).iterator;
c.moveNext();
print(c.current); // 10
c.moveNext();
print(c.current); // 11
c.moveNext(20);
print(c.current); // 21
c.moveNext();
print(c.current); // 21
} As a counter-point, it shows a very different usage pattern than what we normally do with iterators in Dart. In practice, Dart programs never actually use iterators directly, they are either iterated using coroutine int sequencer([int input]) {
int counter = input;
while (true) {
counter = (yield counter) ?? counter + 1;
}
}
main() {
int Function([int]) c = new sequencer;
print(c(10)); // 10;
print(c()); // 11
print(c(20)); // 20
print(c()); // 21
} |
Thanks comment. As a programmer who write callee side of coroutine, I am accustomed with redux-saga's saga definition, following code looks no strange (just example). Similarity to redux-saga is rather preferable. Iterable<Effect> rootSaga([msg]) sync* {
yield ForkEffect(saga2);
while (true) {
yield WaitEffect(3);
}
}
Iterable<Effect> saga2([msg]) sync* {
yield ForkEffect(saga3);
while (true) {
yield WaitEffect(3);
yield PutEffect(new Action("ACTION_TYPE1", null));
}
}
Iterable<Effect> saga3([Msg]) sync* {
while (true) {
var action = yield TakeEffect(new Action("ACTION_TYPE1", null));
:
}
}
main() {
var effectManager = new EffectManager();
effectManager.startSaga(rootSaga);
} |
I'm also interested a co-routine based approach for structured concurrency similar to redux-saga. In order to implement this, there would need to be more than just a This is done in JavaScript with the:
It would really be awesome if Dart could do this as it would make implementing structured concurrency much more practical to implement. |
Any progress on this? It would be a killer feature. |
dart --version
)Dart VM version: 2.0.0-dev.32.0 (Thu Mar 1 18:39:53 2018 +0100) on "macos_x64"
Problem
In dart language, generator's yield language construct is a statement and cannot gain any value.
Although in Python and JavaScript (ES 2015), yield is a expression and can get value like:
Where the return value of yield is expected to be given from iterator side, for example:
To get value from yield is extremely valuable when use generator to implement coroutine,
moreover actually it is necessarily.
I hope we can use "yield expression" in future Dart release.
References:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield
rv Returns the optional value passed to the generator's next() method to resume its execution.
https://stackoverflow.com/questions/12637768/python-3-send-method-of-generators
The text was updated successfully, but these errors were encountered: