Possible improvement of phobos map?

JG someone at somewhere.com
Mon Jul 4 19:54:51 UTC 2022


On Monday, 4 July 2022 at 19:51:01 UTC, JG wrote:
> On Monday, 4 July 2022 at 19:44:11 UTC, JG wrote:
>> Hi,
>>
>> There was a recent discussion regarding suggesting some 
>> special algorithms for associative arrays, which made we 
>> wonder if the problem isn't actually that it is a slightly 
>> annoying when working with ranges of tuples or structs.
>>
>> For instance you might have code like this
>>
>> ```d
>>   auto a = ["a":5, "b":6];
>>   a.byPair.map!(t=>format!"%s=%s"(t[0],t[1])).writeln;
>> ```
>> or
>> ```d
>>   auto r = iota(1,10);
>>   auto gcds = cartesianProduct(r,r).map!(t=>gcd(t[0],t[1]));
>>
>> ```
>> which while not too bad isn't as readable as it could be, and 
>> it gets worse when the chain gets longer.
>>
>> With some slight changes to map (which wouldn't be needed if 
>> pattern matching exists), one can do this:
>>
>> ```d
>> import std;
>>
>> struct MapPrototype(alias f, R) {
>>     R r;
>>     bool empty() { return r.empty; }
>>     auto front() { return f(r.front.tupleof); }
>>     void popFront() { r.popFront; }
>>     auto save() { return typeof(this)(r.save); }
>> }
>>
>> auto mapPrototype(alias f, R)(R r) {
>>     return MapPrototype!(f,R)(r);
>> }
>>
>> struct Point {
>>     int x;
>>     int y;
>> }
>>
>> void main() {
>>     auto r = iota(1,10);
>>     auto gcds = cartesianProduct(r,r).mapPrototype!(gcd);
>>     gcds.writeln;
>>     auto a = ["a":5, "b":6];
>>     
>> a.byPair.mapPrototype!((name,value)=>format!"%s=%s"(name,value)).writeln;
>>     
>> [Point(1,2),Point(3,4)].mapPrototype!((x,y)=>x*x+y*y).writeln;
>> }
>> ```
>>
>> Thoughts?
>
> I should have added, this is incomplete code one needs to check 
> which behavior is wanted decomposition like above or the old 
> behavior.

To be clear I mean something like this:
```d
import std;

struct MapPrototype(alias f, R) {
     R r;
     bool empty() { return r.empty; }
     auto front() {
         static if(__traits(compiles,f(R.init.front))) {
             return f(r.front);
         } else {
           return f(r.front.tupleof);
         }
     }
     void popFront() { r.popFront; }
     auto save() { return typeof(this)(r.save); }
}

auto mapPrototype(alias f, R)(R r) {
     return MapPrototype!(f,R)(r);
}

struct Point {
     int x;
     int y;
}

void main() {
     auto r = iota(1,10);
     auto gcds = cartesianProduct(r,r).mapPrototype!(gcd);
     gcds.writeln;
     auto a = ["a":5, "b":6];
     
a.byPair.mapPrototype!((name,value)=>format!"%s=%s"(name,value)).writeln;
     [Point(1,2),Point(3,4)].mapPrototype!((x,y)=>x*x+y*y).writeln;
     [Point(1,2),Point(3,4)].mapPrototype!(p=>p.x).writeln;
}
```


More information about the Digitalmars-d mailing list