This looks fun! It's probably best to bring this to loom-dev. In its
archives you'll find several discussions about generators as several
people have been interested in that topic. Even when thread confined,
the main concern has been that exotic control flow yields leads to
surprising behavior with many of the existing constructs, e.g. in your
example think about behavior with finally blocks, try-with-resources,
locks, ... when the iterator is not fully consumed.
-Alan
On 28/08/2023 09:43, Daniel Schmid wrote:
Hi,
After seeing the JVM Language Summit talk on Continuations
(https://www.youtube.com/watch?v=6nRS6UiN7X0), I thought about it
being possible to implement something like "yield return" in languages
like C# (or "yield" in Python) based on Continuations.
Kotlin has implemented a similar feature as well:
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.sequences/-sequence-scope/yield.html
Now that Continuations are in the JDK, I feel like it can be used as a
good primitive and now is a good time to start about thinking about
adding something like this as a Java feature or the libraries.
After my experiments and some discussion with another developer named
Peter Eastham (https://github.com/Crain-32), I was able to come up
with an implementation/proof-of-concept allowing something like the
following:
public static void main(String[] args) {
System.out.println("main thread: " + Thread.currentThread());
for (String s : Yielder.create(YieldReturnTest::someMethod)) {
System.out.println("Text: " + s);
}
}
private static void someMethod(Yielder<String> y) {
y.yield("Hello - " + Thread.currentThread());
System.out.println("between yields");
y.yield("World - " + Thread.currentThread());
for (String s : Yielder.create(YieldReturnTest::otherMethod)) {
y.yield("nested: " + s);
}
y.yield("bye - " + Thread.currentThread());
}
private static void otherMethod(Yielder<String> y) {
y.yield("it can");
y.yield("also be");
y.yield("nested");
}
output:
main thread: Thread[#1,main,5,main]
Text: Hello - Thread[#1,main,5,main]
between yields
Text: World - Thread[#1,main,5,main]
Text: nested: it can
Text: nested: also be
Text: nested: nested
Text: bye - Thread[#1,main,5,main]
In this example, the method reference passed to the Yielder.create
method would be run in a Continuation while y.yield would yield the
Continuation and make the value available to the iterator (next()
calls Continuation#run).
You can find a simple proof-of-concept of that here:
https://github.com/danthe1st/ContinuationYieldReturn
Would it be possible to add something like this to the JDK libraries?
I feel like it might be a useful addition to the JDK libraries as it
simplifies creating sequences a lot.
Originally, I thought about whether it might be a good idea to add
syntax for this but after building that proof-of-concept, it looks
like it would be sufficient to add this to the libraries and using
methods like this seems pretty natural.
One thing I am concerned with this approach (opposed to an approach
that involves changing syntax) is that it would be possible that the
method suddenly runs in a different thread if the
hasNext()/next()-calls of the Iterator chang the thread they are used
in at some point. While Continuations allow this behaviour, it might
seem a weird to developers who don't know how Continuations work.
But aside from that issue with iterations switching threads, this
approach seems pretty natural to me.
Yours,
Daniel