Reputation: 661
In JavaScript I can easily make a complex function give up execution in the middle and continue it later.
Example:
function* nested() {
for (let i = 0; i < 5; ++i) {
for (let j = 0; j < 5; ++j) {
for (let k = 0; k < 5; ++k) {
yield `${i},${j},${k}`;
}
}
}
}
const n = nested();
function runOneStepEachFrame() {
const {done, value} = n.next();
if (done) {
console.log('done');
} else {
console.log(value);
requestAnimationFrame(runOneStepEachFrame);
}
}
runOneStepEachFrame();
C#
using System;
using System.Collections.Generic;
public class Program
{
public static IEnumerable<string> Nested()
{
for (int i = 0; i < 5; ++i) {
for (int j = 0; j < 5; ++j) {
for (int k = 0; k < 5; ++k) {
yield return String.Format("{0},{1},{2}", i, j, k);
}
}
}
}
public static void Main()
{
foreach(string s in Nested())
{
Console.WriteLine(s);
}
}
}
Does Swift have a similar functionality? Of course I can refactor to keep my own state but my actual function is a fairly complex calculation and I'd like to "yield" in the middle of it (and not yield in the sense of suspending a thread, but in the sense of a generator as above)
Upvotes: 1
Views: 392
Reputation: 273223
AsyncStream
is very similar, in terms of syntax, to what you are looking for, which I believe is coroutines for sequences. Note that one big difference between AsyncStream
and iterator methods in C# (I don't know about JavaScript) is that AsyncStream
is asynchronous. One could say that it is more similar to IAsyncEnumerable<T>
:)
For example, the C# code can be rewritten like this:
let sequence = AsyncStream { continuation in
for i in 0..<5 {
for j in 0..<5 {
for k in 0..<5 {
continuation.yield("\(i) \(j) \(k)")
}
}
}
continuation.finish()
}
Task {
for await elem in sequence {
print(elem)
}
}
Here is a discussion on forums.swift.org about synchronous coroutines, and to quote one of the comments there:
Synchronous coroutines are, I believe, being planned for in a "whenever we can find the time for it" sort of way. If I remember correctly, that's why
_read
&_modify
useyield
to give up their storage. Sadly, I don't think there are any immediate plans to add them in.
Upvotes: 3