www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - taskPool.reduce vs algorithm.reduce

reply Dorian Haglund <dorian.haglund gmail.com> writes:
Hi.

I'm trying to use taskPool.reduce with a delegate, for example:

import std.parallelism;

int main(string[] args)
{
   int f(int a, int b)
   {
     if (args.length > 1)
       return a+b;
     else
       return a-b;
   }

   auto res = taskPool.reduce!f([1, 2, 3]);

   return 0;
}

But it fails to compile (with gdc 8.1.0, dmd v2.081) complaining 
that

template instance reduce!(f) cannot use local 'f' as parameter to 
non-global template reduce(functions...)

The snippet above compiles with the reduce function from 
std.algorithm.

Is there a way to make the code compile with taskPool.reduce ?
(I don't want to write two functions and choosing one depending 
on args.length)

Why the interface difference between std.algorithm's reduce and 
taskPool.reduce ?

Best regards,

Dorian
Jul 11 2018
next sibling parent Paul Backus <snarwin gmail.com> writes:
On Wednesday, 11 July 2018 at 08:31:30 UTC, Dorian Haglund wrote:
 But it fails to compile (with gdc 8.1.0, dmd v2.081) 
 complaining that

 template instance reduce!(f) cannot use local 'f' as parameter 
 to non-global template reduce(functions...)
Congratulations! You've just run into issue 5710 [1], one of D's most annoying known bugs. [1]: https://issues.dlang.org/show_bug.cgi?id=5710
 The snippet above compiles with the reduce function from 
 std.algorithm.

 [...]

 Why the interface difference between std.algorithm's reduce and 
 taskPool.reduce ?
std.algorithm.reduce is a free function, so it can accept delegates as template parameters. taskPool.reduce is a member function, so it can't.
Jul 11 2018
prev sibling parent reply Timoses <timosesu gmail.com> writes:
On Wednesday, 11 July 2018 at 08:31:30 UTC, Dorian Haglund wrote:
 Hi.

 I'm trying to use taskPool.reduce with a delegate, for example:

 import std.parallelism;

 int main(string[] args)
 {
   int f(int a, int b)
   {
     if (args.length > 1)
       return a+b;
     else
       return a-b;
   }

   auto res = taskPool.reduce!f([1, 2, 3]);

   return 0;
 }

 But it fails to compile (with gdc 8.1.0, dmd v2.081) 
 complaining that

 template instance reduce!(f) cannot use local 'f' as parameter 
 to non-global template reduce(functions...)

 The snippet above compiles with the reduce function from 
 std.algorithm.

 Is there a way to make the code compile with taskPool.reduce ?
 (I don't want to write two functions and choosing one depending 
 on args.length)

 Why the interface difference between std.algorithm's reduce and 
 taskPool.reduce ?

 Best regards,

 Dorian
As the error message says taskPool.reduce is a non-global template. It's embedded in a taskPool struct. I can't say what the reason is that a delegate cannot be used with such a template. I'd be interested in hearing what the reason is. (See Paul's reply). I'm trying to trick around it, but can't get this to work... https://run.dlang.io/is/EGbtuq import std.parallelism; int main(string[] args) { static int f(bool cond)(int a, int b) { static if (cond) return a+b; else return a-b; } template getF(alias func) { auto getF(T)(T arg) { if (args.length > 1) return func!(f!true)(arg); // line 18 else return func!(f!false)(arg); // line 20 } } auto res = getF!(taskPool.reduce)([1,2,3]); return 0; } onlineapp.d(18): Error: need this for reduce of type system int(int[] _param_0) onlineapp.d(20): Error: need this for reduce of type system int(int[] _param_0)
Jul 11 2018
parent Malte <no valid.mail> writes:
On Wednesday, 11 July 2018 at 10:07:33 UTC, Timoses wrote:
 On Wednesday, 11 July 2018 at 08:31:30 UTC, Dorian Haglund 
 wrote:
 [...]
As the error message says taskPool.reduce is a non-global template. It's embedded in a taskPool struct. I can't say what the reason is that a delegate cannot be used with such a template. I'd be interested in hearing what the reason is. (See Paul's reply). I'm trying to trick around it, but can't get this to work... https://run.dlang.io/is/EGbtuq
You can make it all global: https://run.dlang.io/is/Kf8CLC From my own experience: Use only parallel foreach and save yourself a lot of hassle. That just works.
Jul 19 2018