d language concurrency with recursion

470 views Asked by At

I have been trying to implement a factorial function using the actor model with the d language. My objective is to use to create actor to calculate each part alone e spawn a new actor to make the next. I am just a beginner with D, so I'm just learning how to use the language. My objective is to expand the factorial implementation to much more. This is just a test.

Here is my problem: I'm trying to implement the factorial using recursion; the fact function will create a new fact thread for next number in line, unless it has reached the base condition.

My code:

void fact(Tid tid)
{

        int fact = 1;
        receive
        (
        (int i)
        {
            if(i == 0)
            {
                writeln("End of recursion");
            }
            else
            {
                fact *= i;
                send(thisTid, i-1);
            }
        }
    );
    send(tid, fact);
}

void main()
{

        auto tid = spawn(&fact, thisTid);
        int x = 3;
        send(tid, x);
        auto fact = receiveOnly!(int);
        writeln(fact);
}

I don't even know if that's possible, in any case it does not work. If I try to add a spwn in fact function it returns the following error:

src/main.d(62): Error: template std.concurrency.spawn does not match any function template declaration
/usr/include/x86_64-linux-gnu/dmd/phobos/std/concurrency.d(399): Error: template std.concurrency.spawn(T...) cannot deduce template function from argument types !()(int*,Tid)
src/main.d(63): Error: template std.concurrency.send does not match any function template declaration
/usr/include/x86_64-linux-gnu/dmd/phobos/std/concurrency.d(463): Error: template std.concurrency.send(T...) cannot deduce template function from argument types !()(_error_,int)

So, is it possible to do what I am trying to do? How? If not, is there any plans to make some thing like that possible?

Please, help.

2

There are 2 answers

0
Tim On BEST ANSWER

I could be way off base here, but from that error message it looks to me like dmd is not using the fact that you think it is using, in your call to spawn. You have several integers named fact, and although in this (obviously cut down, since it's not 400 lines) example none of them would conflict, in the full code my guess is one of them does (because &fact would be an int* if fact was an int).

Try renaming the function to factorial or some such, and changing the spawn call where appropriate. Make sure not to change the integers.

3
Peter Alexander On

Works fine for me. What DMD version are you using? Perhaps try upgrading to 2.059 if you aren't already on it.

(Note: I say it works in that it compiles and runs. It doesn't give the write answer because fact will only receive one number before it returns, so it just returns three. You'll need to have the receive in a loop)

admin@poita ~% cat test.d
import std.stdio;
import std.concurrency;

void fact(Tid tid)
{
    int fact = 1;
    receive
    (
        (int i)
        {
            if(i == 0)
            {
                writeln("End of recursion");
            }
            else
            {
                fact *= i;
                send(thisTid, i-1);
            }
        }
    );
    send(tid, fact);
}

void main()
{
    auto tid = spawn(&fact, thisTid);
    int x = 3;
    send(tid, x);
    auto fact = receiveOnly!(int);
    writeln(fact);
}

admin@poita ~% dmd test.d
admin@poita ~% ./test
3
admin@poita ~%