Tuples, CTFE, and Sliding Template Arguments

Steven Schveighoffer schveiguy at gmail.com
Sat Jan 13 00:15:56 UTC 2024


On Friday, 12 January 2024 at 22:35:54 UTC, Walter Bright wrote:
> Given the interest in CTFE of istrings, I have been thinking 
> about making a general use case out of it instead of one 
> specific to istrings.
> 
> ---------------------
>
> Sliding Template Arguments

This is a workable solution. But still not with format strings 
(which are specific to writef).

If I were to use this to implement interpolation tuples, I'd 
prefer the first parameter to be of type `struct Interpolation { 
immutable string[] parts; }`, and therefore the compiler would do:

```d
void foo(Interpolation interp, Args...)(Args args) {...}

void main()
{
     string name = "Steve";
     int age = 42;
     foo(i"Hello, $name, I see you are $age years old.");
     // equivalent to:
     foo!(Interpolation(["Hello, ", "name", ", I see you are ", 
"age", " years old."]))(name, age);
}
```

There is still value, I think, in passing the parameters in the 
order they appear. And this doesn't allow for e.g. functions that 
take multiple istrings. But maybe that's fine?

Another interesting development from this, is that you can take 
the string literal data at runtime as well (when you prefer, or 
are ok with, runtime processing of the string literal data):

```d
void writeln(Args...)(Interpolation interp, Args args)
{
     assert(interp.parts.length == args.length * 2 + 1);
     write(interp.parts[0]); // always a leading string;
     static foreach(i; 0 .. args.length)
         write(args[i], interp.parts[(i+1)*2]);
     writeln();
}
```

I don't view this as simpler than DIP1036e or DIP1027 -- a simple 
transformation is a simple transformation. Certainly a hybrid 
DIP1027 with a format string passed at compile time is still not 
viable, due to reasons already stated.

But it will be slightly less bloat. And it has benefits 
elsewhere, as you say.

If this mechanism is what gets it over the finish line, I can 
compromise with this.

Is this something that can be implemented and played with?

This does seem like it has the potential to break code:

```d
void foo(int x, Args...)(Args args) {

}
void foo(Args...)(Args args) {
}

foo(1, 2, 3); // which is called? Today, the second is
```

So I would heed Timon's advice, maybe we do need an explicit 
opt-in.

-Steve


More information about the Digitalmars-d mailing list