digitalmars.D.learn - Function Template for Dynamic Parameter
- vino.B (35/35) Jul 01 2018 All,
- Timoses (18/53) Jul 01 2018 Perhaps https://dlang.org/spec/template.html#variadic-templates
All,
Request your help, the D document states that "Template
functions are useful for avoiding code duplication - instead of
writing several copies of a function, each with a different
parameter type, a single function template can be sufficient"
which mean we can passing any type of parameter using function
template, similarly who we we pass in any number of parameter of
any type(dynamic parameters) , like in python
Python
def myfunc(*arg)
def myfunc(**kwargs) // multiple key-value
def myfunc(*args, **kwargs): mix
Do we have any thing similar to the above python in D
void (func(T)( T *args) // Example
Examples:
void func(T)(T x)
{
writeln(x);
}
void main()
{ func("x"); // pass a string }
void func(T)(T n3)
{
writeln(n); // where n = 3 parameters (1, string, char)
}
void func(T)(T n2)
{
writeln(n); // where n = 3 parameters (1, string)
}
void func(T)(T n1)
{
writeln(n); // where n = 3 parameters (1 or string or char)
}
From,
Vino.B
Jul 01 2018
On Sunday, 1 July 2018 at 09:46:32 UTC, vino.B wrote:
All,
Request your help, the D document states that "Template
functions are useful for avoiding code duplication - instead of
writing several copies of a function, each with a different
parameter type, a single function template can be sufficient"
which mean we can passing any type of parameter using function
template, similarly who we we pass in any number of parameter
of any type(dynamic parameters) , like in python
Python
def myfunc(*arg)
def myfunc(**kwargs) // multiple key-value
def myfunc(*args, **kwargs): mix
Do we have any thing similar to the above python in D
void (func(T)( T *args) // Example
Examples:
void func(T)(T x)
{
writeln(x);
}
void main()
{ func("x"); // pass a string }
void func(T)(T n3)
{
writeln(n); // where n = 3 parameters (1, string, char)
}
void func(T)(T n2)
{
writeln(n); // where n = 3 parameters (1, string)
}
void func(T)(T n1)
{
writeln(n); // where n = 3 parameters (1 or string or char)
}
From,
Vino.B
Perhaps https://dlang.org/spec/template.html#variadic-templates
void func(T ...)(T args)
{
static assert(T.length <= 3);
static assert(is(T[0] == int)); // 1
pragma(msg, T.stringof);
foreach (arg; args)
{
writeln(arg);
}
}
void main()
{
func(3, "s", 1.3);
//func(1.3); // error, first argument is not an int, see
// 1
}
Jul 01 2018
On Sunday, 1 July 2018 at 09:55:34 UTC, Timoses wrote:On Sunday, 1 July 2018 at 09:46:32 UTC, vino.B wrote:Hi Timoses, Thank you very much, can you help me on how to rewrite the below using Variadic template Passing function as a parameter to another function: void ptFun(T)(T function(string, string, int) coRoutine, Array!string Dirlst, ) { alias scRType = typeof(coRoutine(string.init, string.init, int.init)); where the "function(string, string, int) coRoutine" should be a variadic function From, Vino.BAll, Request your help, the D document states that "Template functions are useful for avoiding code duplication - instead of writing several copies of a function, each with a different parameter type, a single function template can be sufficient" which mean we can passing any type of parameter using function template, similarly who we we pass in any number of parameter of any type(dynamic parameters) , like in python Python def myfunc(*arg) def myfunc(**kwargs) // multiple key-value def myfunc(*args, **kwargs): mix Do we have any thing similar to the above python in D void (func(T)( T *args) // Example Examples: void func(T)(T x) { writeln(x); } void main() { func("x"); // pass a string } void func(T)(T n3) { writeln(n); // where n = 3 parameters (1, string, char) } void func(T)(T n2) { writeln(n); // where n = 3 parameters (1, string) } void func(T)(T n1) { writeln(n); // where n = 3 parameters (1 or string or char) } From, Vino.BPerhaps https://dlang.org/spec/template.html#variadic-templates void func(T ...)(T args) { static assert(T.length <= 3); static assert(is(T[0] == int)); // 1 pragma(msg, T.stringof); foreach (arg; args) { writeln(arg); } } void main() { func(3, "s", 1.3); //func(1.3); // error, first argument is not an int, see // 1 }
Jul 01 2018
On Sunday, 1 July 2018 at 11:19:50 UTC, vino.B wrote:
Hi Timoses,
Thank you very much, can you help me on how to rewrite the
below using Variadic template
Passing function as a parameter to another function:
void ptFun(T)(T function(string, string, int) coRoutine,
Array!string Dirlst, ) {
alias scRType = typeof(coRoutine(string.init, string.init,
int.init));
where the "function(string, string, int) coRoutine" should be a
variadic function
From,
Vino.B
I'm not sure, if get your question right, is this what you are
looking for?
´´´
import std.stdio;
import std.traits;
void main()
{
alias instantiation = ptFun!(size_t, fun!string);
instantiation(4);
alias instantiation2 = ptFun2!(fun!string);
instantiation2(4);
}
auto fun(T...)(T input)
{
return size_t(42);
}
void ptFun(T, alias funToCall)(size_t definedParam)
if(is(T == ReturnType!(funToCall)))
{
"ptFun called".writeln;
assert(42 == funToCall("some string"));
}
void ptFun2(alias funToCall)(size_t definedParam)
if(__traits(isSame, TemplateOf!(funToCall), fun))
{
"ptFun2 called".writeln;
assert(42 == funToCall("some string"));
}
´´´
Jul 01 2018
On Sunday, 1 July 2018 at 11:52:19 UTC, Alex wrote:On Sunday, 1 July 2018 at 11:19:50 UTC, vino.B wrote:Hi Alex, Something similar to the below code, when compling the below code i get an error NewType.d(19): Error: function declaration without return type. (Note that constructors are always named this) import core.time: days; import std.algorithm: each, filter, map, sort, strip; import std.container.array; import std.conv: to; import std.datetime.systime: Clock, SysTime; import std.file: dirEntries, isFile, SpanMode; import std.parallelism: parallel; import std.stdio: File, writefln, writeln; import std.string: strip; import std.traits: ReturnType; import std.typecons: Tuple, tuple; auto coCleanFiles(T ...)(T args) { auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(FFs, SpanMode.shallow).filter!(a => a.isFile).map!(a => tuple(a.name, a.timeLastModified))); return dFiles; } void ptManagecoRoutine(T)(T function(T ...)(T args), Array!string Dirlst) { alias scRType = typeof(coRoutine(args.init)); auto PFresult = taskPool.workerLocalStorage!scRType; ReturnType!coRoutine rData; foreach (string FFs; Dirlst[]) { PFresult.get ~= coRoutine(FFs.strip); } foreach(i; PFresult.toRange) { rData ~= i[][]; } if (!rData[].empty) { rData[].sort!((a,b) => a[1] < b[1]).each!(e => writefln!"%-83s %.20s"(e[0], e[1].to!string)); } } void main () { Array!string CleanDirlst; CleanDirlst.insertBack("C:\\Temp\\BACKUP1"); ptManagecoRoutine(&coCleanFiles, CleanDirlst); } From, Vino.BHi Timoses, Thank you very much, can you help me on how to rewrite the below using Variadic template Passing function as a parameter to another function: void ptFun(T)(T function(string, string, int) coRoutine, Array!string Dirlst, ) { alias scRType = typeof(coRoutine(string.init, string.init, int.init)); where the "function(string, string, int) coRoutine" should be a variadic function From, Vino.BI'm not sure, if get your question right, is this what you are looking for? ´´´ import std.stdio; import std.traits; void main() { alias instantiation = ptFun!(size_t, fun!string); instantiation(4); alias instantiation2 = ptFun2!(fun!string); instantiation2(4); } auto fun(T...)(T input) { return size_t(42); } void ptFun(T, alias funToCall)(size_t definedParam) if(is(T == ReturnType!(funToCall))) { "ptFun called".writeln; assert(42 == funToCall("some string")); } void ptFun2(alias funToCall)(size_t definedParam) if(__traits(isSame, TemplateOf!(funToCall), fun)) { "ptFun2 called".writeln; assert(42 == funToCall("some string")); } ´´´
Jul 01 2018
On Sunday, 1 July 2018 at 11:58:30 UTC, vino.B wrote:
On Sunday, 1 July 2018 at 11:52:19 UTC, Alex wrote:
NewType.d(19): Error: function declaration without return type.
(Note that constructors are always named this)
[...]
auto coCleanFiles(T ...)(T args) {
auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(FFs,
SpanMode.shallow).filter!(a => a.isFile).map!(a =>
tuple(a.name, a.timeLastModified)));
return dFiles;
}
void ptManagecoRoutine(T)(T function(T ...)(T args),
Array!string Dirlst) {
alias scRType = typeof(coRoutine(args.init));
auto PFresult = taskPool.workerLocalStorage!scRType;
ReturnType!coRoutine rData;
foreach (string FFs; Dirlst[]) { PFresult.get ~=
coRoutine(FFs.strip); }
foreach(i; PFresult.toRange) { rData ~= i[][]; }
if (!rData[].empty) { rData[].sort!((a,b) => a[1] <
b[1]).each!(e => writefln!"%-83s %.20s"(e[0], e[1].to!string));
}
}
void main () {
Array!string CleanDirlst;
CleanDirlst.insertBack("C:\\Temp\\BACKUP1");
ptManagecoRoutine(&coCleanFiles, CleanDirlst);
}
auto coCleanFiles(T ...)(T args)
{ ... }
void ptManagecoRoutine(T)(T fun, Array!string DirList)
{
foreach (dir; DirList)
fun(dir);
}
or
void ptManagecoRoutine2(alias func)(Array!string DirList)
if (is (typeof(func!(typeof(DirList[0]))) == function))
{
alias t = typeof(DirList[0]);
ptManagecoRoutine(&func!t, DirList);
}
callable via
Array!string CleanDirlst;
ptManagecoRoutine(&coCleanFiles!string, CleanDirlst);
ptManagecoRoutine2!coCleanFiles(CleanDirlst);
Jul 01 2018
On Sunday, 1 July 2018 at 12:46:30 UTC, Timoses wrote:On Sunday, 1 July 2018 at 11:58:30 UTC, vino.B wrote:Hi All, Request your help on the below code auto coCleanFiles(T ...) (T FFs) { auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(FFs, SpanMode.depth).map!(a => tuple(a.name, a.timeCreated))); return dFiles; } void process(T)(T pfunction, Array!string Dirlst) { alias wlsType = typeof(pfunction(T)); auto Result = taskPool.workerLocalStorage!wlsType(); foreach (FFs; parallel(Dirlst[],1)) { Result.get ~= pfunction(FFs); } foreach(i; Result.toRange) { writeln(i[][]); } } void main() { Array!string Cleanlst; Cleanlst.insert("C:\\Temp\\BACKUP1"); process(&coCleanFiles, Cleanlst); } Error : Error: coCleanFiles(T...)(T FFs) is not an lvalue and cannot be modified From, Vino.BOn Sunday, 1 July 2018 at 11:52:19 UTC, Alex wrote: NewType.d(19): Error: function declaration without return type. (Note that constructors are always named this) [...] auto coCleanFiles(T ...)(T args) { auto dFiles = Array!(Tuple!(string, SysTime))(dirEntries(FFs, SpanMode.shallow).filter!(a => a.isFile).map!(a => tuple(a.name, a.timeLastModified))); return dFiles; } void ptManagecoRoutine(T)(T function(T ...)(T args), Array!string Dirlst) { alias scRType = typeof(coRoutine(args.init)); auto PFresult = taskPool.workerLocalStorage!scRType; ReturnType!coRoutine rData; foreach (string FFs; Dirlst[]) { PFresult.get ~= coRoutine(FFs.strip); } foreach(i; PFresult.toRange) { rData ~= i[][]; } if (!rData[].empty) { rData[].sort!((a,b) => a[1] < b[1]).each!(e => writefln!"%-83s %.20s"(e[0], e[1].to!string)); } } void main () { Array!string CleanDirlst; CleanDirlst.insertBack("C:\\Temp\\BACKUP1"); ptManagecoRoutine(&coCleanFiles, CleanDirlst); }auto coCleanFiles(T ...)(T args) { ... } void ptManagecoRoutine(T)(T fun, Array!string DirList) { foreach (dir; DirList) fun(dir); } or void ptManagecoRoutine2(alias func)(Array!string DirList) if (is (typeof(func!(typeof(DirList[0]))) == function)) { alias t = typeof(DirList[0]); ptManagecoRoutine(&func!t, DirList); } callable via Array!string CleanDirlst; ptManagecoRoutine(&coCleanFiles!string, CleanDirlst); ptManagecoRoutine2!coCleanFiles(CleanDirlst);
Jul 05 2018
On Thursday, 5 July 2018 at 16:23:36 UTC, vino.B wrote:
Hi All,
Request your help on the below code
auto coCleanFiles(T ...) (T FFs) {
auto dFiles = Array!(Tuple!(string,
SysTime))(dirEntries(FFs, SpanMode.depth).map!(a =>
tuple(a.name, a.timeCreated)));
return dFiles;
}
void process(T)(T pfunction, Array!string Dirlst) {
alias wlsType = typeof(pfunction(T));
auto Result = taskPool.workerLocalStorage!wlsType();
foreach (FFs; parallel(Dirlst[],1)) { Result.get ~=
pfunction(FFs); }
foreach(i; Result.toRange) { writeln(i[][]); }
}
void main() {
Array!string Cleanlst;
Cleanlst.insert("C:\\Temp\\BACKUP1");
process(&coCleanFiles, Cleanlst);
}
Error : Error: coCleanFiles(T...)(T FFs) is not an lvalue and
cannot be modified
I guess since in above code `coCleanFiles` is a template, you can
not simply take the address of that function template. You'd have
to instantiate the template first
process(&coCleanFiles!string, ...)
If you want to pass the template to process you could define
process as something like
void process(alias func)(Array!string Dirlst)
{
func!string(Dirlst[0]);
}
and call
process!coCleanFiles(Cleanlst);
Jul 06 2018
On Sunday, 1 July 2018 at 11:19:50 UTC, vino.B wrote:
On Sunday, 1 July 2018 at 09:55:34 UTC, Timoses wrote:>
Hi Timoses,
Thank you very much, can you help me on how to rewrite the
below using Variadic template
Passing function as a parameter to another function:
void ptFun(T)(T function(string, string, int) coRoutine,
Array!string Dirlst, ) {
alias scRType = typeof(coRoutine(string.init, string.init,
int.init));
where the "function(string, string, int) coRoutine" should be a
variadic function
What's your use case?
You can pretty much pass anything to a template and use "static
if" and "static foreach" in the template to steer how the
template is instantiated.
void func(T ...)(T args)
{
foreach (i, arg; args)
{
static if (isSomeFunction!(T[i]))
{
arg();
}
else
writeln(arg);
}
}
unittest
{
func(() => writeln("I'm a lambda function), "I'm a
string", 3);
}
which would print:
I'm a lambda function
I'm a string
3
I'm actually a bit suprised that `isSomeFunction!(T[i])` works
here, I'd expect an error because `i` looks like a run-time
variable... And using that in a compile-time (static if)
statement usually throws a CT error.
With templates one has to think "compile-time". Any "static if",
"static foreach" or alias declarations are compile time
constructs. What results from that after compilation is an
instantiated template for a specific use case. For example in
above case the template exists (is instantiated) with the
template parameters `(void function() safe, string, int)`.
A good source to get some more insights is always:
http://ddili.org/ders/d.en/templates.html
(including all other sections of the book)
Jul 01 2018









Timoses <timosesu gmail.com> 