www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - tuple(...).each error; why does foreach work and std.algorithms.each

reply wjoe <invalid example.com> writes:
Consider a function to format the parameters of a function call:

pure nothrow string fmtArgs(ARGS...)(ARGS args)
{
    string result;

    // 1)
    foreach(a; args) {
       result ~= a.to!string;
    }

    // 2)
    args.each!(a => result ~= a.to!string);

    return result;
}

In my mind, if something works with foreach, it should also work 
with std.algorithm.each.
However if I try something like 2) the compiler complains with 
error: cannot deduce function from argument types !()(uint, 
int)...

Technically I'd like to transform args into a range/array of 
strings but I'm not smart enough to understand the error messages 
these functions in std.algorithms produce.

How is 1) different from 2) ?
Feb 11 2020
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 11 February 2020 at 18:11:44 UTC, wjoe wrote:
 In my mind, if something works with foreach, it should also 
 work with std.algorithm.each.
They are very different, the each thing only works for ranges whereas foreach works with a variety of things.
 How is 1) different from 2) ?
The ARGS... is a compiler list and can have multiple different types included. Moreover, it will auto-expand when you use it to call a function etc. You can sometimes do [args] - with the [] around it to turn into an array. Then you can .each it and so on. But they must already be of compatible types to do that since an array elements must all be the same thing. I would suggest just using foreach for this.
Feb 11 2020
parent reply wjoe <invalid example.com> writes:
On Tuesday, 11 February 2020 at 18:21:11 UTC, Adam D. Ruppe wrote:
 On Tuesday, 11 February 2020 at 18:11:44 UTC, wjoe wrote:
 In my mind, if something works with foreach, it should also 
 work with std.algorithm.each.
They are very different, the each thing only works for ranges whereas foreach works with a variety of things.
 How is 1) different from 2) ?
The ARGS... is a compiler list and can have multiple different types included. Moreover, it will auto-expand when you use it to call a function etc. You can sometimes do [args] - with the [] around it to turn into an array. Then you can .each it and so on. But they must already be of compatible types to do that since an array elements must all be the same thing. I would suggest just using foreach for this.
What's a compiler list... is that something like a tuple? or more like a macro expansion? Or is it only valid to use in a foreach to take advantage of each item individually and for expansion in a function call ? Is it possible to partially expand like: void fn(int, uint) {} and ARGS(string, int, uint) and call fn(args[1..$]); Is that possible? as for the format function...foreach works as expected so I'll just keep that. Thanks for your fast reply :)
Feb 11 2020
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Tuesday, 11 February 2020 at 18:55:45 UTC, wjoe wrote:
 What's a compiler list... is that something like a tuple? or 
 more like a macro expansion?
 Or is it only valid to use in a foreach to take advantage of 
 each item individually and for expansion in a function call ?
 Is it possible to partially expand like:

 void fn(int, uint) {}
 and ARGS(string, int, uint)
 and call fn(args[1..$]);

 Is that possible?
This article answers all of your questions: https://dlang.org/articles/ctarguments.html
Feb 11 2020
parent wjoe <invalid example.com> writes:
On Tuesday, 11 February 2020 at 19:04:17 UTC, Paul Backus wrote:
 On Tuesday, 11 February 2020 at 18:55:45 UTC, wjoe wrote:
 What's a compiler list... is that something like a tuple? or 
 more like a macro expansion?
 Or is it only valid to use in a foreach to take advantage of 
 each item individually and for expansion in a function call ?
 Is it possible to partially expand like:

 void fn(int, uint) {}
 and ARGS(string, int, uint)
 and call fn(args[1..$]);

 Is that possible?
This article answers all of your questions: https://dlang.org/articles/ctarguments.html
That's more information than I had hoped for. Thank you :)
Feb 11 2020
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 11 February 2020 at 18:55:45 UTC, wjoe wrote:
 What's a compiler list... is that something like a tuple?
Yea, they are frequently called tuples too. It is basically just a list of arguments used for a function call that the compiler treats somewat magically.
 Is it possible to partially expand like:

 void fn(int, uint) {}
 and ARGS(string, int, uint)
 and call fn(args[1..$]);
Yes, slicing is the exact syntax for it. You can slice and index as if it were an array.
Feb 11 2020
parent wjoe <invalid example.com> writes:
On Tuesday, 11 February 2020 at 19:05:19 UTC, Adam D. Ruppe wrote:
 On Tuesday, 11 February 2020 at 18:55:45 UTC, wjoe wrote:
 What's a compiler list... is that something like a tuple?
Yea, they are frequently called tuples too. It is basically just a list of arguments used for a function call that the compiler treats somewat magically.
 Is it possible to partially expand like:

 void fn(int, uint) {}
 and ARGS(string, int, uint)
 and call fn(args[1..$]);
Yes, slicing is the exact syntax for it. You can slice and index as if it were an array.
Cool. thanks for your reply :)
Feb 11 2020