January 31, 2017 Re: Yield from function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Tuesday, 31 January 2017 at 06:32:02 UTC, Ali Çehreli wrote:
> On 01/30/2017 08:12 PM, Profile Anaysis wrote:
>>
>> import std.stdio, std.concurrency, core.thread;
>>
>> class Search : Fiber
>> {
>> this() { super(&start); }
>> int res = 0;
>> void start()
>> {
>> Fiber.yield();
>> res = 1;
>> }
>> }
>>
>> void main()
>> {
>>
>> auto search = new Search();
>>
>> search.call(); writeln(search.res);
>> search.call(); writeln(search.res);
>> search.call(); writeln(search.res); // crashes after 3rd call(first
>> two work fine)
>> }
>
> That's because the fiber is not in a callable state. (You can check with search.state.) Here is one where the fiber function lives (too) long:
>
> import std.stdio, std.concurrency, core.thread;
>
> class Search : Fiber
> {
> this() { super(&start); }
> int res = 0;
> void start() {
> while (true) {
> Fiber.yield();
> ++res;
> }
> }
> }
>
> void main()
> {
> auto search = new Search();
>
> foreach (i; 0 .. 5) {
> search.call();
> writeln(search.res);
> }
> }
>
> Ali
Just curious, how can I use start() recursively?
I would like to iterate over a recursive structure and yield for each "solution". I could use a stack to store the values but the whole point of the fiber was to avoid that.
void start() {
while (true) {
Fiber.yield();
++res;
}
}
Seems I can't create start with a parameter and non-void return type. This seems to make it about useless to use a fiber recursively because no pushing and popping on the stack occur.
class Search : Fiber
{
this() { super(&start); }
bool End = false;
int res = 0;
void start() {
while (!End)
{
int Foo(int x)
{
Fiber.yield();
if (x < 10)
{
res = Foo(x++);
return res;
}
else
return x;
}
}
}
void main()
{
auto search = new Search();
foreach (i; 0 .. 5)
{
search.call();
writeln(search.res);
}
search.End = true;
}
My goal is simple, to yield a solution at each step in the recursive process.
Maybe I can use another fiber using the lambda syntax?
|
January 31, 2017 Re: Yield from function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Profile Anaysis | On 01/31/2017 03:00 AM, Profile Anaysis wrote: > Just curious, how can I use start() recursively? [...] > Seems I can't create start with a parameter and non-void return type. Options: - The class can maintain state - You can start the fiber with a delegate; int local; double state; () => foo(local, state) Other than the entry point, there is no requirement in what you can do. The following code yields inside a recursive function: import std.stdio, std.concurrency, core.thread; class Search : Fiber { int state; this(int state) { this.state = state; super(&start); } int res = 0; void start() { recursive(state); } void recursive(int s) { if (s == 0) { return; } res = s; Fiber.yield(); recursive(s - 1); } } void main() { auto search = new Search(42); foreach (i; 0 .. 5) { search.call(); writeln(search.res); } } Ali |
January 31, 2017 Re: Yield from function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Tuesday, 31 January 2017 at 11:31:28 UTC, Ali Çehreli wrote:
> On 01/31/2017 03:00 AM, Profile Anaysis wrote:
>
> > [...]
> [...]
> > [...]
> return type.
>
> Options:
>
> [...]
Thanks again!
|
January 31, 2017 Re: Yield from function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Profile Anaysis | On Monday, 30 January 2017 at 11:03:52 UTC, Profile Anaysis wrote: > I need to yield from a complex recursive function too allow visualizing what it is doing. > > e.g., if it is a tree searching algorithm, I'd like to yield for each node so that the current state can be shown visually. > > I realize that there are several ways to do this but D a yield version without additional threads would be optimal. I don't need concurrency or speed, just simple. Sounds like opApply (external iteration) may well be the way to go. It is a great tool to separate (possibly complex) iteration logic from (possibly complex) instance processing logic. Here is a random recipe: https://www.sociomantic.com/blog/2010/06/opapply-recipe An example: ----- import std.stdio; class Node { int value; Node left, right; this (int value_) {value = value_;} } struct InOrderViewer { Node root; int opApply (int delegate (Node) process) { void recur (Node cur) { if (cur is null) return; recur (cur.left); process (cur); // use return value here to allow break in foreach recur (cur.right); } recur (root); return 0; } } void main () { auto v1 = new Node (1); auto v2 = new Node (2); auto v3 = new Node (3); auto v4 = new Node (4); auto v5 = new Node (5); v2.left = v1; v2.right = v5; v5.left = v3; v3.right = v4; foreach (node; InOrderViewer (v2)) { writeln (node.value ^^ 2); // 1 4 9 16 25 } } ----- Ivan Kazmenko. |
Copyright © 1999-2021 by the D Language Foundation