www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Passing function(whose parameter would be dynamic and the type is

reply vino.B <bheeman.vino hotmail.com> writes:
Hi All,

  Request you help, in the below code we pass the function 
"Testfun" as a parameter to another function "process" in order 
for the function "process" to work we have to specify the type of 
the parameter that is passed to the function "(T function(string, 
int) coRoutine, string Test, int Size) ", so now how do we pass a 
function whose parameter would be dynamic and the type is unknown.

void process(T)(T function(string, int) coRoutine, string Test, 
int Size) {
alias scRType = typeof(coRoutine(string.init, int.init));

Eg:

Run1 : process(&Testfun, Test, Size);
void process(T ...)(T function(string, int) coRoutine, string 
Test) {
alias scRType = typeof(coRoutine(string.init, int.init));


Run2 : process(&Testfun, Test, Size, Str1);
void process(T)(T function(string, int, string) coRoutine, string 
Test, int Size, string Str1) {
alias scRType = typeof(coRoutine(string.init, int.init, 
string.int));


Run3 : process(&Testfun, Test);
void process(T)(T function(string, string) coRoutine, string 
Test, int Size) {
alias scRType = typeof(coRoutine(string.init));
PFresult.get = coRoutine(args);

Some what like this

auto Testfun (string FFs, int Size) { return tuple(FFs, Size); }

void process(T ...)(T function(T args) coRoutine, T args) {
alias scRType = typeof(coRoutine(T.init));
PFresult.get = coRoutine(T);

void main() {
string Test ="C:\\Temp\\BACKUP1"; int Size = 1;
process(&Testfun, Test, Size);
}


Code : Working
import std.stdio: writeln;
import std.container.array;
import std.typecons: tuple;
import std.parallelism: taskPool;

auto Testfun (string FFs, int Size) { return tuple(FFs, Size); }

void process(T)(T function(string, int) coRoutine, string Test, 
int Size) {
alias scRType = typeof(coRoutine(string.init, int.init));
auto PFresult = taskPool.workerLocalStorage!scRType();
PFresult.get = coRoutine(Test, Size);
foreach(i; PFresult.toRange) { writeln(i[][]); }
}

void main() {
string Test ="C:\\Temp\\BACKUP1"; int Size = 1;
process(&Testfun, Test, Size);
}

From,
Vino.B
Jul 08 2018
next sibling parent reply Alex <sascha.orlov gmail.com> writes:
On Sunday, 8 July 2018 at 18:46:31 UTC, vino.B wrote:
  Request you help, in the below code we pass the function 
 "Testfun" as a parameter to another function "process" in order 
 for the function "process" to work we have to specify the type 
 of the parameter that is passed to the function "(T 
 function(string, int) coRoutine, string Test, int Size) ", so 
 now how do we pass a function whose parameter would be dynamic 
 and the type is unknown.
What do you mean with a "function with dynamic parameters" and "unknown type"? But how about ´´´ void main() { process!fun(); } void process(alias coRoutine, T...)(T params) { coRoutine(params); } auto fun(T...)(T params) { } ´´´
Jul 08 2018
parent reply vino.B <bheeman.vino hotmail.com> writes:
On Sunday, 8 July 2018 at 19:10:24 UTC, Alex wrote:
 On Sunday, 8 July 2018 at 18:46:31 UTC, vino.B wrote:
  Request you help, in the below code we pass the function 
 "Testfun" as a parameter to another function "process" in 
 order for the function "process" to work we have to specify 
 the type of the parameter that is passed to the function "(T 
 function(string, int) coRoutine, string Test, int Size) ", so 
 now how do we pass a function whose parameter would be dynamic 
 and the type is unknown.
What do you mean with a "function with dynamic parameters" and "unknown type"? But how about ´´´ void main() { process!fun(); } void process(alias coRoutine, T...)(T params) { coRoutine(params); } auto fun(T...)(T params) { } ´´´
HI Alex, I tried you method, but it not working as expected, the process!fun1(Test1) works but the process!fun2(Test1, Size ) does not work, instead of displaying the value (Test, 1) it output's the parameter "Test1". Output: Test Test1 If I comment process!fun1(Test1); then the output is same Output : Test1 import std.stdio: writeln; void main() { string Test1 = "Test"; int Size = 1; process!fun1(Test1); process!fun2(Test1, Size ); } void process(alias coRoutine, T...)(T params) { coRoutine(params); } auto fun1(T...)(T params) { writeln(params); } auto fun2(T...)(T params) { writeln(params); } From, Vino.B
Jul 09 2018
parent reply Alex <sascha.orlov gmail.com> writes:
On Monday, 9 July 2018 at 15:40:53 UTC, vino.B wrote:
 On Sunday, 8 July 2018 at 19:10:24 UTC, Alex wrote:
 On Sunday, 8 July 2018 at 18:46:31 UTC, vino.B wrote:
  Request you help, in the below code we pass the function 
 "Testfun" as a parameter to another function "process" in 
 order for the function "process" to work we have to specify 
 the type of the parameter that is passed to the function "(T 
 function(string, int) coRoutine, string Test, int Size) ", so 
 now how do we pass a function whose parameter would be 
 dynamic and the type is unknown.
What do you mean with a "function with dynamic parameters" and "unknown type"? But how about ´´´ void main() { process!fun(); } void process(alias coRoutine, T...)(T params) { coRoutine(params); } auto fun(T...)(T params) { } ´´´
HI Alex, I tried you method, but it not working as expected, the process!fun1(Test1) works but the process!fun2(Test1, Size ) does not work, instead of displaying the value (Test, 1) it output's the parameter "Test1". Output: Test Test1 If I comment process!fun1(Test1); then the output is same Output : Test1 import std.stdio: writeln; void main() { string Test1 = "Test"; int Size = 1; process!fun1(Test1); process!fun2(Test1, Size ); } void process(alias coRoutine, T...)(T params) { coRoutine(params); } auto fun1(T...)(T params) { writeln(params); } auto fun2(T...)(T params) { writeln(params); } From, Vino.B
As I can see, this is the expected output. The "1" after "Test" is the value of parameter "Size"...
Jul 09 2018
parent reply vino.B <bheeman.vino hotmail.com> writes:
On Monday, 9 July 2018 at 15:49:50 UTC, Alex wrote:
 On Monday, 9 July 2018 at 15:40:53 UTC, vino.B wrote:
 On Sunday, 8 July 2018 at 19:10:24 UTC, Alex wrote:
 On Sunday, 8 July 2018 at 18:46:31 UTC, vino.B wrote:
  Request you help, in the below code we pass the function 
 "Testfun" as a parameter to another function "process" in 
 order for the function "process" to work we have to specify 
 the type of the parameter that is passed to the function "(T 
 function(string, int) coRoutine, string Test, int Size) ", 
 so now how do we pass a function whose parameter would be 
 dynamic and the type is unknown.
What do you mean with a "function with dynamic parameters" and "unknown type"? But how about ´´´ void main() { process!fun(); } void process(alias coRoutine, T...)(T params) { coRoutine(params); } auto fun(T...)(T params) { } ´´´
HI Alex, I tried you method, but it not working as expected, the process!fun1(Test1) works but the process!fun2(Test1, Size ) does not work, instead of displaying the value (Test, 1) it output's the parameter "Test1". Output: Test Test1 If I comment process!fun1(Test1); then the output is same Output : Test1 import std.stdio: writeln; void main() { string Test1 = "Test"; int Size = 1; process!fun1(Test1); process!fun2(Test1, Size ); } void process(alias coRoutine, T...)(T params) { coRoutine(params); } auto fun1(T...)(T params) { writeln(params); } auto fun2(T...)(T params) { writeln(params); } From, Vino.B
As I can see, this is the expected output. The "1" after "Test" is the value of parameter "Size"...
Hi Alex, Thank you a lot, i was able to improvise using your logic, and i need more help, the below code is working as expected using your logic, now how do i get the return type of the function Request Help: void process(alias coRoutine, T...)(Array!string Dirlst, T params) { ReturnType!coRoutine rData; ///// This line is not working alias scRType = typeof(coRoutine(string.init, T.init)); auto PFresult = taskPool.workerLocalStorage!scRType(); foreach (string FFs; parallel(Dirlst[],1)) { PFresult.get ~= coRoutine(FFs, params); } foreach(i; PFresult.toRange) { rData ~= i[][]; } } Error: test.d(206): Error: template instance `std.traits.ReturnType!(coAgedDirClean)` does not match template declaration ReturnType(func...) if (func.length == 1 && isCallable!func) Working Code: auto coAgedDirClean(T...)(string FFs, T params) { auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(FFs, SpanMode.shallow).filter!(a => a.isFile && a.size > params[0]).map!(a => tuple(a.name, a.timeLastModified))); return dFiles; } auto coAgedDirDelete(T...)(string FFs, T params) { auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(FFs, SpanMode.shallow).filter!(a => a.isFile && a.size > params[0]).map!(a => tuple(a.name, a.timeLastModified))); if (params[1] == "run" && !dFiles.empty) { foreach(d; parallel(dFiles[], 1)) { remove(d[0]); }} return dFiles; } void process(alias coRoutine, T...)(Array!string Dirlst, T params) { alias scRType = typeof(coRoutine(string.init, T.init)); auto PFresult = taskPool.workerLocalStorage!scRType(); foreach (string FFs; parallel(Dirlst[],1)) { PFresult.get ~= coRoutine(FFs, params); } foreach(i; PFresult.toRange) { writeln(i[][]); } } void main() { Array!string AgedDir, DeleteDir; AgedDir.insert("C:\\Temp\\TEAM1"); DeleteDir.insert("C:\\Temp\\BACKUP1"); ulong Size = 102; string Step = "run"; process!coAgedDirClean(AgedDir, Size ); process!coAgedDirDelete(DeleteDir, Size, Step); } From, Vino.B
Jul 09 2018
parent reply Alex <sascha.orlov gmail.com> writes:
On Monday, 9 July 2018 at 17:26:30 UTC, vino.B wrote:
 Request Help:
 void process(alias coRoutine, T...)(Array!string Dirlst, T 
 params)
 {
       ReturnType!coRoutine rData;   ///// This line is not 
 working
       alias scRType = typeof(coRoutine(string.init, T.init));
       auto PFresult = taskPool.workerLocalStorage!scRType();
       foreach (string FFs; parallel(Dirlst[],1)) { PFresult.get 
 ~= coRoutine(FFs, params); }
       foreach(i; PFresult.toRange) { rData ~= i[][]; }
 }

 Error:
 test.d(206): Error: template instance 
 `std.traits.ReturnType!(coAgedDirClean)` does not match 
 template declaration ReturnType(func...) if (func.length == 1 
 && isCallable!func)
Yeah... for ReturnType to work, you need a function, but you have only a template. The easy solution is to execute the template and to ask the result for its type: ´´´ void main() { process!fun(); } void process(alias coRoutine, T...)(T params) { auto res = coRoutine(params); pragma(msg, typeof(res)); } auto fun(T...)(T params) { return 42; } ´´´ If you need it in advance... It is a little bit longer. There was a place, where I used this once... See https://run.dlang.io/is/Xy6Xf4 However, I wonder why you need this, especially as your process is void. Why not just using auto for results of the coroutines?
Jul 09 2018
parent reply vino.B <bheeman.vino hotmail.com> writes:
On Monday, 9 July 2018 at 18:07:49 UTC, Alex wrote:
 On Monday, 9 July 2018 at 17:26:30 UTC, vino.B wrote:
 Request Help:
 void process(alias coRoutine, T...)(Array!string Dirlst, T 
 params)
 {
       ReturnType!coRoutine rData;   ///// This line is not 
 working
       alias scRType = typeof(coRoutine(string.init, T.init));
       auto PFresult = taskPool.workerLocalStorage!scRType();
       foreach (string FFs; parallel(Dirlst[],1)) { 
 PFresult.get ~= coRoutine(FFs, params); }
       foreach(i; PFresult.toRange) { rData ~= i[][]; }
 }

 Error:
 test.d(206): Error: template instance 
 `std.traits.ReturnType!(coAgedDirClean)` does not match 
 template declaration ReturnType(func...) if (func.length == 1 
 && isCallable!func)
Yeah... for ReturnType to work, you need a function, but you have only a template. The easy solution is to execute the template and to ask the result for its type: ´´´ void main() { process!fun(); } void process(alias coRoutine, T...)(T params) { auto res = coRoutine(params); pragma(msg, typeof(res)); } auto fun(T...)(T params) { return 42; } ´´´ If you need it in advance... It is a little bit longer. There was a place, where I used this once... See https://run.dlang.io/is/Xy6Xf4 However, I wonder why you need this, especially as your process is void. Why not just using auto for results of the coroutines?
Hi Alex, The reason the I am storing the output of "PFresult.toRange" to another array "rData" is that the output of the PFresult.toRange is different each time we execute the code.(Data is correct) but the way the it output is different. Is there any way to get the result in a single array - Whole Data. Single array - Whole Data ["C:\\Temp\\TEAM1\\Test Result-Team1.docx", 2018-Jun-28 17:37:45.9376229, "C:\\Temp\\TEAM2\\Test Result-Team2.docx", 2018-Jun-28 17:37:45.9376229, "C:\\Temp\\SAPNAS3\\TEAM3\\Test Result-Team3.docx", 2018-Jun-28 17:37:45.9376229 ] One array - For Each Data [ C:\\Temp\\TEAM1\\Test Result-Team1.docx", 2018-Jun-28 17:37:45.9376229] - arr1 [ C:\\Temp\\TEAM2\\Test Result-Team2.docx", 2018-Jun-28 17:37:45.9376229] - arr2 [ C:\\Temp\\TEAM3\\Test Result-Team3.docx", 2018-Jun-28 17:37:45.9376229] - arr3 The code in the program. foreach(i; PFresult.toRange) { rData ~= i[][]; } if (!rData[].empty) { rData[].sort!((a,b) => a[1] < b[1]).each!(e => logF.writefln!"%-83s %.20s"(e[0].replace(`\\?\`, ""), e[1].to!string)); } From, Vino.B
Jul 10 2018
parent reply Alex <sascha.orlov gmail.com> writes:
On Tuesday, 10 July 2018 at 14:38:03 UTC, vino.B wrote:
 Hi Alex,

   The reason the I am storing the output of "PFresult.toRange" 
 to another array "rData" is that the output of the  
 PFresult.toRange is different each time we execute the 
 code.(Data is correct) but the way the it output is different. 
 Is there any way to get the result in a single array - Whole 
 Data.

 Single array - Whole Data
 ["C:\\Temp\\TEAM1\\Test Result-Team1.docx", 2018-Jun-28 
 17:37:45.9376229,
 "C:\\Temp\\TEAM2\\Test Result-Team2.docx", 2018-Jun-28 
 17:37:45.9376229,
 "C:\\Temp\\SAPNAS3\\TEAM3\\Test Result-Team3.docx", 2018-Jun-28 
 17:37:45.9376229
 ]

 One array - For Each Data
 [ C:\\Temp\\TEAM1\\Test Result-Team1.docx", 2018-Jun-28 
 17:37:45.9376229] - arr1
 [ C:\\Temp\\TEAM2\\Test Result-Team2.docx", 2018-Jun-28 
 17:37:45.9376229] - arr2
 [ C:\\Temp\\TEAM3\\Test Result-Team3.docx", 2018-Jun-28 
 17:37:45.9376229] - arr3

 The code in the program.

  foreach(i; PFresult.toRange) { rData ~= i[][]; }
  if (!rData[].empty) { rData[].sort!((a,b) => a[1] < 
 b[1]).each!(e => logF.writefln!"%-83s 
 %.20s"(e[0].replace(`\\?\`, ""), e[1].to!string)); }

 From,
 Vino.B
Not sure, if I get your point, but are you aware of tuples? https://dlang.org/phobos/std_typecons.html#tuple
Jul 10 2018
parent reply vino.B <bheeman.vino hotmail.com> writes:
On Tuesday, 10 July 2018 at 14:50:53 UTC, Alex wrote:
 On Tuesday, 10 July 2018 at 14:38:03 UTC, vino.B wrote:
 Hi Alex,

   The reason the I am storing the output of "PFresult.toRange" 
 to another array "rData" is that the output of the  
 PFresult.toRange is different each time we execute the 
 code.(Data is correct) but the way the it output is different. 
 Is there any way to get the result in a single array - Whole 
 Data.

 Single array - Whole Data
 ["C:\\Temp\\TEAM1\\Test Result-Team1.docx", 2018-Jun-28 
 17:37:45.9376229,
 "C:\\Temp\\TEAM2\\Test Result-Team2.docx", 2018-Jun-28 
 17:37:45.9376229,
 "C:\\Temp\\SAPNAS3\\TEAM3\\Test Result-Team3.docx", 
 2018-Jun-28 17:37:45.9376229
 ]

 One array - For Each Data
 [ C:\\Temp\\TEAM1\\Test Result-Team1.docx", 2018-Jun-28 
 17:37:45.9376229] - arr1
 [ C:\\Temp\\TEAM2\\Test Result-Team2.docx", 2018-Jun-28 
 17:37:45.9376229] - arr2
 [ C:\\Temp\\TEAM3\\Test Result-Team3.docx", 2018-Jun-28 
 17:37:45.9376229] - arr3

 The code in the program.

  foreach(i; PFresult.toRange) { rData ~= i[][]; }
  if (!rData[].empty) { rData[].sort!((a,b) => a[1] < 
 b[1]).each!(e => logF.writefln!"%-83s 
 %.20s"(e[0].replace(`\\?\`, ""), e[1].to!string)); }

 From,
 Vino.B
Not sure, if I get your point, but are you aware of tuples? https://dlang.org/phobos/std_typecons.html#tuple
Hi Alex, I am getting the output as tuples of multiple arrays, but the requirement is to get the all the tuple in a single array like the below so that we can perform sorting and printing the output is easy. [ "C:\\Temp\\TEAM1\\Test Result-Team1.docx", 2018-Jun-28 17:37:45.9376229, "C:\\Temp\\TEAM2\\Test Result-Team2.docx", 2018-Jun-28 17:37:45.9376229, "C:\\Temp\\SAPNAS3\\TEAM3\\Test Result-Team3.docx", 2018-Jun-28 17:37:45.9376229 ] if (!rData[].empty) { rData[].sort!((a,b) => a[1] < b[1]).each!(e => logF.writefln!"%-83s %.20s"(e[0], e[1].to!string)); } From, Vino.B
Jul 10 2018
parent Timoses <timosesu gmail.com> writes:
On Tuesday, 10 July 2018 at 14:58:42 UTC, vino.B wrote:

 Hi Alex,

  I am getting the output as tuples of multiple arrays, but the 
 requirement is to get the all the tuple in a single array like 
 the below so that we can perform sorting and printing the 
 output is easy.
Something along the way unittest { import std.typecons : Tuple, tuple; alias pair = Tuple!(string, int); pair[] values; values ~= tuple("du", 7); values ~= tuple("Vino", 3); values ~= tuple(",", 4); values ~= tuple("hur", 5); values ~= tuple("Hej", 2); values ~= tuple("?", 8); values ~= tuple("mår", 6); import std.algorithm : sort, each; import std.stdio : write; values.sort!((p1, p2) => p1[1] < p2[1]) .each!(p => write(p[0] ~ " ")); } ?
Jul 10 2018
prev sibling parent reply Timoses <timosesu gmail.com> writes:
On Sunday, 8 July 2018 at 18:46:31 UTC, vino.B wrote:
 Hi All,

  Request you help, in the below code we pass the function 
 "Testfun" as a parameter to another function "process" in order 
 for the function "process" to work we have to specify the type 
 of the parameter that is passed to the function "(T 
 function(string, int) coRoutine, string Test, int Size) ", so 
 now how do we pass a function whose parameter would be dynamic 
 and the type is unknown.

 void process(T)(T function(string, int) coRoutine, string Test, 
 int Size) {
This would templetize the return type of the coRoutine, thus within that function you could do T returnedValue = coRoutine(string.init, int.init);
 alias scRType = typeof(coRoutine(string.init, int.init));

 Eg:

 Run1 : process(&Testfun, Test, Size);
 void process(T ...)(T function(string, int) coRoutine, string 
 Test) {
 alias scRType = typeof(coRoutine(string.init, int.init));


 Run2 : process(&Testfun, Test, Size, Str1);
 void process(T)(T function(string, int, string) coRoutine, 
 string Test, int Size, string Str1) {
 alias scRType = typeof(coRoutine(string.init, int.init, 
 string.int));


 Run3 : process(&Testfun, Test);
 void process(T)(T function(string, string) coRoutine, string 
 Test, int Size) {
 alias scRType = typeof(coRoutine(string.init));
 PFresult.get = coRoutine(args);

 Some what like this

 auto Testfun (string FFs, int Size) { return tuple(FFs, Size); }

 void process(T ...)(T function(T args) coRoutine, T args) {
This would mean that if you pass a function that returns for example an int, it must also - take an int as argument - and process has to accept another int e.g. process((int i) => i+1, 3); if T would be (int, string) you would have to pass something like process((int i, string s) { return AliasSeq!(int, string); }, // error: not even sure how to express this 3, "hello"); where I'm not sure how to express the return type of (int, string)... Does anybody know this? Would the Tuple Dip make this possible? (https://forum.dlang.org/post/p3bdp1$2b4e$1 digitalmars.com)
 alias scRType = typeof(coRoutine(T.init));
 PFresult.get = coRoutine(T);

 void main() {
 string Test ="C:\\Temp\\BACKUP1"; int Size = 1;
 process(&Testfun, Test, Size);
 }


 Code : Working
 import std.stdio: writeln;
 import std.container.array;
 import std.typecons: tuple;
 import std.parallelism: taskPool;

 auto Testfun (string FFs, int Size) { return tuple(FFs, Size); }

 void process(T)(T function(string, int) coRoutine, string Test, 
 int Size) {
 alias scRType = typeof(coRoutine(string.init, int.init));
 auto PFresult = taskPool.workerLocalStorage!scRType();
 PFresult.get = coRoutine(Test, Size);
 foreach(i; PFresult.toRange) { writeln(i[][]); }
 }

 void main() {
 string Test ="C:\\Temp\\BACKUP1"; int Size = 1;
 process(&Testfun, Test, Size);
 }

 From,
 Vino.B
I suggest taking a look at https://dlang.org/phobos/std_traits.html . E.g. ReturnType and Parameters: int func() { return 3; } assert(is(ReturnType!func == int)); void gunc(int i, double j) {} import std.meta : AliasSeq; assert(is(Parameters!gunc == AliasSeq!(int, double))); Perhaps you could tell us what your goal is. People here might come up with a nice solution. Why do you feel like having to use templated functions in the first place? That is, what is the generic goal of the functions you are trying to define?
Jul 08 2018
parent reply vino.B <bheeman.vino hotmail.com> writes:
On Sunday, 8 July 2018 at 19:22:32 UTC, Timoses wrote:
 On Sunday, 8 July 2018 at 18:46:31 UTC, vino.B wrote:
 Hi All,

  Request you help, in the below code we pass the function 
 "Testfun" as a parameter to another function "process" in 
 order for the function "process" to work we have to specify 
 the type of the parameter that is passed to the function "(T 
 function(string, int) coRoutine, string Test, int Size) ", so 
 now how do we pass a function whose parameter would be dynamic 
 and the type is unknown.

 void process(T)(T function(string, int) coRoutine, string 
 Test, int Size) {
This would templetize the return type of the coRoutine, thus within that function you could do T returnedValue = coRoutine(string.init, int.init);
 alias scRType = typeof(coRoutine(string.init, int.init));

 Eg:

 Run1 : process(&Testfun, Test, Size);
 void process(T ...)(T function(string, int) coRoutine, string 
 Test) {
 alias scRType = typeof(coRoutine(string.init, int.init));


 Run2 : process(&Testfun, Test, Size, Str1);
 void process(T)(T function(string, int, string) coRoutine, 
 string Test, int Size, string Str1) {
 alias scRType = typeof(coRoutine(string.init, int.init, 
 string.int));


 Run3 : process(&Testfun, Test);
 void process(T)(T function(string, string) coRoutine, string 
 Test, int Size) {
 alias scRType = typeof(coRoutine(string.init));
 PFresult.get = coRoutine(args);

 Some what like this

 auto Testfun (string FFs, int Size) { return tuple(FFs, Size); 
 }

 void process(T ...)(T function(T args) coRoutine, T args) {
This would mean that if you pass a function that returns for example an int, it must also - take an int as argument - and process has to accept another int e.g. process((int i) => i+1, 3); if T would be (int, string) you would have to pass something like process((int i, string s) { return AliasSeq!(int, string); }, // error: not even sure how to express this 3, "hello"); where I'm not sure how to express the return type of (int, string)... Does anybody know this? Would the Tuple Dip make this possible? (https://forum.dlang.org/post/p3bdp1$2b4e$1 digitalmars.com)
 alias scRType = typeof(coRoutine(T.init));
 PFresult.get = coRoutine(T);

 void main() {
 string Test ="C:\\Temp\\BACKUP1"; int Size = 1;
 process(&Testfun, Test, Size);
 }


 Code : Working
 import std.stdio: writeln;
 import std.container.array;
 import std.typecons: tuple;
 import std.parallelism: taskPool;

 auto Testfun (string FFs, int Size) { return tuple(FFs, Size); 
 }

 void process(T)(T function(string, int) coRoutine, string 
 Test, int Size) {
 alias scRType = typeof(coRoutine(string.init, int.init));
 auto PFresult = taskPool.workerLocalStorage!scRType();
 PFresult.get = coRoutine(Test, Size);
 foreach(i; PFresult.toRange) { writeln(i[][]); }
 }

 void main() {
 string Test ="C:\\Temp\\BACKUP1"; int Size = 1;
 process(&Testfun, Test, Size);
 }

 From,
 Vino.B
I suggest taking a look at https://dlang.org/phobos/std_traits.html . E.g. ReturnType and Parameters: int func() { return 3; } assert(is(ReturnType!func == int)); void gunc(int i, double j) {} import std.meta : AliasSeq; assert(is(Parameters!gunc == AliasSeq!(int, double))); Perhaps you could tell us what your goal is. People here might come up with a nice solution. Why do you feel like having to use templated functions in the first place? That is, what is the generic goal of the functions you are trying to define?
Hi Timoses, We are converting a Power shell script to D in phased manner; the PS script has many functions and we converted few function to D in Phase 1. Phase 1: Structure of the Program Main -> Thread Manager->CoFunction1(Fs1,2,3,4,5) Main -> Thread Manager->CoFunction2(Fs1,2,3,4,5) The thread manager will call the Cofunctions and the function gets executed on “N” of file systems each of size 5-10 TB. The function that we transformed all has the same number of parameters (3) and the type was same (string, string, int), so we wrote a static thread manager as below void ptManager (T)(T function(string, string, int) coRoutine, Array!string Dirlst, string Step, int Size) { alias scRType = typeof(coRoutine(string.init, string.init, int.init)); auto PFresult = taskPool.workerLocalStorage!scRType(); ReturnType!coRoutine rData; foreach (string FFs; parallel(Dirlst[0 .. $],1)) { PFresult.get ~= coRoutine(FFs.strip, Step); } foreach(i; PFresult.toRange) { writeln(i[][]); } } void main () { ptManager(&function1, Fn1Dirlst, Step, Size); ptManager(&function2, Fn2Dirlst, Step, Age); } Phase 2: In phase 2 we are transferring few more function to the existing D code, and these functions has variable number of parameter and different type eg: Function3(string, string, string), Function(string, int, string, int). Initially I tried to re-write the ptManager function for each type of function which ended with 8 ptManager functions, Eg : ptManager1(string, string, int), ptManager2(string, string, string), ptManager3(string,int), so now trying as to whether we can use 1 ptManager function which can process function with “N” of parameter and types to process all the function, hence trying to implement the Variadic function. Hence request your help and suggestion to achieve this. Command Parameter to all the functions: Array!string Dirlist : This parameter will contain the the Fs names File logF: This parameter is used to store the outoput File logE: This parameter is used to store the Error Information. Rest of the function has variable parameters/type. From, Vino.B
Jul 08 2018
next sibling parent Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Monday, 9 July 2018 at 05:54:27 UTC, vino.B wrote:
 In phase 2 we are transferring few more function to the 
 existing D code, and these functions has variable number of 
 parameter and different type eg: Function3(string, string, 
 string), Function(string, int, string, int).

 Initially I tried to re-write the ptManager function for each 
 type of function which ended with 8 ptManager functions, Eg : 
 ptManager1(string, string, int), ptManager2(string, string, 
 string), ptManager3(string,int), so now trying as to whether we 
 can use 1 ptManager function which can process function with 
 “N” of parameter and types to process all the function, hence 
 trying to implement the Variadic function. Hence request your 
 help and suggestion to achieve this.
Variadic templates to the rescue: void ptManager1(Fn, Args...)(Fn coRoutine, Array!string Dirlst, Args args) if (__traits(compiles, coRoutine("", args))) { alias scRType = typeof(coRoutine("", args)); auto PFresult = taskPool.workerLocalStorage!scRType(); foreach (string FFs; parallel(Dirlst[], 1)) { PFresult.get ~= coRoutine(FFs.strip, args); } foreach(i; PFresult.toRange) { writeln(i[][]); } } unittest { ptManager1(&function1, Fn1Dirlst, Step, Size); ptManager1(&function2, Fn2Dirlst, Step, Age); } Alternatively, pass the co-routine as an alias: void ptManager2(alias coRoutine, Args...)(Array!string Dirlst, Args args) if (__traits(compiles, coRoutine("", args))) { alias scRType = typeof(coRoutine("", args)); auto PFresult = taskPool.workerLocalStorage!scRType(); foreach (string FFs; parallel(Dirlst[], 1)) { PFresult.get ~= coRoutine(FFs.strip, args); } foreach(i; PFresult.toRange) { writeln(i[][]); } } unittest { ptManager2!function1(Fn1Dirlst, Step, Size); ptManager2!function2(Fn2Dirlst, Step, Age); } These options are essentially equivalent; the main reason to prefer the first is if the functions are passed around at runtime. If you don't do that, ptManager2 may be slightly faster. Using logE and logF is left as an exercise for the reader. :p As an aside, I first thought of making a less generic ptManager that'd work something like this: ptManager3(dir => function1(dir, Step, Size), Fn1Dirlst); However, since the return value changes between functions, that doesn't really buy us much - we'll still have to templatize ptManager3 on the return type, and the contents of the function will be very much the same. -- Simen
Jul 09 2018
prev sibling parent Timoses <timosesu gmail.com> writes:
On Monday, 9 July 2018 at 05:54:27 UTC, vino.B wrote:
 On Sunday, 8 July 2018 at 19:22:32 UTC, Timoses wrote:
 Perhaps you could tell us what your goal is. People here might 
 come up with a nice solution. Why do you feel like having to 
 use templated functions in the first place? That is, what is 
 the generic goal of the functions you are trying to define?
Hi Timoses, We are converting a Power shell script to D in phased manner; the PS script has many functions and we converted few function to D in Phase 1. Phase 1: Structure of the Program Main -> Thread Manager->CoFunction1(Fs1,2,3,4,5) Main -> Thread Manager->CoFunction2(Fs1,2,3,4,5) The thread manager will call the Cofunctions and the function gets executed on “N” of file systems each of size 5-10 TB. The function that we transformed all has the same number of parameters (3) and the type was same (string, string, int), so we wrote a static thread manager as below void ptManager (T)(T function(string, string, int) coRoutine, Array!string Dirlst, string Step, int Size) { alias scRType = typeof(coRoutine(string.init, string.init, int.init)); auto PFresult = taskPool.workerLocalStorage!scRType(); ReturnType!coRoutine rData; foreach (string FFs; parallel(Dirlst[0 .. $],1)) { PFresult.get ~= coRoutine(FFs.strip, Step); } foreach(i; PFresult.toRange) { writeln(i[][]); } } void main () { ptManager(&function1, Fn1Dirlst, Step, Size); ptManager(&function2, Fn2Dirlst, Step, Age); } Phase 2: In phase 2 we are transferring few more function to the existing D code, and these functions has variable number of parameter and different type eg: Function3(string, string, string), Function(string, int, string, int). Initially I tried to re-write the ptManager function for each type of function which ended with 8 ptManager functions, Eg : ptManager1(string, string, int), ptManager2(string, string, string), ptManager3(string,int), so now trying as to whether we can use 1 ptManager function which can process function with “N” of parameter and types to process all the function, hence trying to implement the Variadic function. Hence request your help and suggestion to achieve this. Command Parameter to all the functions: Array!string Dirlist : This parameter will contain the the Fs names File logF: This parameter is used to store the outoput File logE: This parameter is used to store the Error Information. Rest of the function has variable parameters/type. From, Vino.B
Ok, interesting. I don't really know my way around parallelism, though I think you should take a look at Alex's suggestion (https://forum.dlang.org/post/adepbwetsiuwguuaaizs forum.dlang.org) for a template solution. You could e.g. do void ptManager(alias func, T ...)(T args) { import std.traits : Parameters, ReturnType; static assert(is(Parameters!func == T), "Arguments don't fit function!"); alias RetType = ReturnType!func; // only receive value if return type is not void static if (!is(RetType == void)) RetType mVal = func(args); // write it to stdout if mVal is a valid symbol // (could also combine that in the above static if...) static if (is(typeof(mVal))) { import std.stdio : writeln; writeln(mVal); } } unittest { ptManager!((int i) => i+1)(2); void someDelegate(string s1, string s2, int i1) { /* ... */ } ptManager!someDelegate("hello", "ptManager", 100); }
Jul 09 2018