New blog post on the cost of compile time

Nick Treleaven nick at geany.org
Sat Feb 18 12:04:04 UTC 2023


On Monday, 16 January 2023 at 15:13:04 UTC, Steven Schveighoffer 
wrote:
> In general, Phobos templates should try to avoid using simple 
> wrappers for internal things. One thing I didn't discuss in the 
> post is that the `ReturnType` instances here are only ever 
> going to be instantiated *once*, and on something that is 
> *never used* (the lambda function).

If each test used `lvalueOf` from std.traits then the 
instantiations would be reused (there would be 2 just in 
isInputRange), and likely elsewhere too. There could be a 
convention to use lvalueOf too and avoid instantiating rvalueOf 
for instantiation reuse.

```d
is(typeof(() { return (*cast(R*)null).empty; }()) == bool)
is(typeof(() { return lvalueOf!R.empty; }()) == bool)
```

That looks a bit nicer as it says what its intent is. Hopefully 
it wouldn't affect memory/performance much.

Another idea is to factor out all the `r` parameter declarations 
into one, and use that for the return type tests too:

```d
// now
enum isInputRange(R) =
     is(typeof(R.init) == R)
     && is(typeof(() { return (*cast(R*)null).empty; }()) == bool)
     && (is(typeof((return ref R r) => r.front)) ||
         is(typeof(ref (return ref R r) => r.front)))
     && !is(typeof(() { return (*cast(R*)null).front; }()) == void)
     && is(typeof((R r) => r.popFront));

// factored
enum isInputRange(R) =
     __traits(compiles, (R r) {
         static assert(
             is(typeof(R.init) == R) &&
             is(typeof({ return r.empty; }()) == bool) &&
             is(typeof(() return => r.front)) &&
             is(typeof(ref () return => r.front)) &&
             !is(typeof({ return r.front; }()) == void) &&
             is(typeof({ r.popFront; }))
         );
     });
```
The factored version looks much easier to read for me. I don't 
know how they compare for memory/performance though.


More information about the Digitalmars-d mailing list