Recommendations on avoiding range pipeline type hell

SealabJaster sealabjaster at gmail.com
Sun May 16 10:10:54 UTC 2021


On Sunday, 16 May 2021 at 09:55:31 UTC, Chris Piker wrote:
> Maybe that's eminently reasonable to those with deep knowledge, 
> but it seems crazy to a new D programmer.  It breaks a general 
> assumption about programming when copying and pasting a 
> definition yields two things that aren't the same type. (except 
> in rare cases like SQL where null != null.)

It's due to a quirk with passing lambdas as template arguments. 
Each lambda is actually separated into its own function.

It's kind of hard to explain, but examine this code:

```d
// runnable version: https://run.dlang.io/is/NbU3iT
struct S(alias Func)
{
     pragma(msg, __traits(identifier, Func));
}

int func(int a)
{
     return a*2;
}

void main()
{
     auto a = S!(a => a*2)();
     auto b = S!(a => a*2)();

     // Comment above. Then uncomment below for a working version.
     /*
     auto a = S!func();
     auto b = S!func();
     */

     pragma(msg, typeof(a));
     pragma(msg, typeof(b));
     a = b;
}
```

In its given state, this is the following output:

```
__lambda1
__lambda3
S!((a) => a * 2)
S!((a) => a * 2)
onlineapp.d(24): Error: cannot implicitly convert expression `b` 
of type `onlineapp.main.S!((a) => a * 2)` to 
`onlineapp.main.S!((a) => a * 2)`
```

So while `typeof(a)` and `typeof(b)` **look** like they are the 
same, in actuality you can see that `auto a` uses `__lambda1`, 
whereas `auto b` uses `__lambda3`.

This means that, even though visually they should be equal, they 
are in fact two entirely separate types.

So if you had a nested `Result` struct, it'd look more like 
`S!__lambda1.Result` and `S!__lambda3.Result`, instead of just 
`S!IDENTICAL_LAMBDA.Result`.

Confusing, I know...

So if we change this to using a non-lambda function (doing the 
commenting/uncommenting as mentioned in the code) then we get 
successful output:

```
func
S!(func)
S!(func)
```

p.s. I love that you can debug D within D.


More information about the Digitalmars-d-learn mailing list