Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 30, 2017 Yield from function? | ||||
---|---|---|---|---|
| ||||
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. |
January 30, 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. You may be able to use Generator in std.concurrency for this: https://dlang.org/phobos/std_concurrency.html#.Generator You could also rephrase your algorithm as a range, which would not involve concurrency but may be unintuitive to implement. In this case you would likely have to use a stack or queue rather than a recursive function. Is it an option to just accumulate the information regarding your algorithm in a separate data structure and then analyze it after the algorithm is complete, or has recorded some number of entries? |
January 30, 2017 Re: Yield from function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Profile Anaysis | On 01/30/2017 03:03 AM, 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 used tree iteration as a Generator example here: http://ddili.org/ders/d.en/fibers.html It's in the code where the function 'byNode' appears. (The example builds on an earlier tree iteration code in the same chapter.) Ali |
January 30, 2017 Re: Yield from function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Monday, 30 January 2017 at 18:48:10 UTC, Ali Çehreli wrote:
> On 01/30/2017 03:03 AM, 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 used tree iteration as a Generator example here:
>
> http://ddili.org/ders/d.en/fibers.html
>
> It's in the code where the function 'byNode' appears. (The example builds on an earlier tree iteration code in the same chapter.)
>
> Ali
BTW the alias to avoid a name conflic on "Generator" isn't necessary anymore with the last version of phobos (as shipped with DMDv2.073.0). However it's still conflicting with the latest version of LDC available on my system (1.0.0, based on DMDv2.070.2) so maybe letting it be in the example a bit longer is appropriate. Otherwise I believe you'll agree that removing it would make it easier for the beginners.
|
January 30, 2017 Re: Yield from function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to cym13 | On 01/30/2017 02:04 PM, cym13 wrote: > On Monday, 30 January 2017 at 18:48:10 UTC, Ali Çehreli wrote: >> http://ddili.org/ders/d.en/fibers.html > BTW the alias to avoid a name conflic on "Generator" isn't necessary > anymore [...] Otherwise I believe you'll agree > that removing it would make it easier for the beginners. Thanks for letting me know. I can't update the book to 2.073 for other reasons like some changes made to ddoc anyway. :-/ (And 'scope' function parameter, etc.) Ali |
January 30, 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.
If you don't want to use fibers then an alternative to yeilds is to use callbacks during iteration.
Example:
struct Tree(T)
{
T value;
Tree!(T)[] children;
}
void iterDepth(T)(Tree!(T) tree, void delegate(Tree!T) cb)
{
cb(tree);
foreach(child; tree.children)
{
iterDepth(child, cb);
}
}
unittest
{
auto tree = ... //Make the tree somehow
iterDepth(tree, (node)
{
writeln(node.value);
});
}
Callbacks have their set of problems but it's one of the simpler ways to do this.
|
January 31, 2017 Re: Yield from function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to TheFlyingFiddle | On Monday, 30 January 2017 at 22:34:11 UTC, TheFlyingFiddle wrote:
> 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.
>
> If you don't want to use fibers then an alternative to yeilds is to use callbacks during iteration.
>
> Example:
> struct Tree(T)
> {
> T value;
> Tree!(T)[] children;
> }
>
> void iterDepth(T)(Tree!(T) tree, void delegate(Tree!T) cb)
> {
> cb(tree);
> foreach(child; tree.children)
> {
> iterDepth(child, cb);
> }
> }
>
> unittest
> {
> auto tree = ... //Make the tree somehow
> iterDepth(tree, (node)
> {
> writeln(node.value);
> });
> }
>
> Callbacks have their set of problems but it's one of the simpler ways to do this.
This can't be easily because it requires the callback to contain the main program(if it depends on the results). Since I am already in a multi-threaded environment it would not be easy to marshal the data around.
If I run it in it's own thread then it won't block but seems like a lot of work for a simple thing.
|
January 31, 2017 Re: Yield from function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Monday, 30 January 2017 at 18:48:10 UTC, Ali Çehreli wrote:
> On 01/30/2017 03:03 AM, 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 used tree iteration as a Generator example here:
>
> http://ddili.org/ders/d.en/fibers.html
>
> It's in the code where the function 'byNode' appears. (The example builds on an earlier tree iteration code in the same chapter.)
>
> Ali
I tried your lambda based fib example and it works as expected(using a function)
But when I try the class version it crashes without a call stack or any info(somewhere in the fiber module and an access violation).
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)
}
Any ideas what why it is crashing like this?
|
January 30, 2017 Re: Yield from function? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Profile Anaysis | 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
|
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:
>> [...]
>
> 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
Thanks.
|
Copyright © 1999-2021 by the D Language Foundation