Tuples, CTFE, and Sliding Template Arguments

Walter Bright newshound2 at digitalmars.com
Sat Jan 13 06:27:51 UTC 2024


On 1/12/2024 8:13 PM, Steven Schveighoffer wrote:
> On Saturday, 13 January 2024 at 03:59:03 UTC, Timon Gehr wrote:
>> On 1/13/24 04:36, Walter Bright wrote:
>>>
>>> I don't know what "interpolate an expression sequence" means. As for things 
>>> getting out of sync, execi() with CTFE can reject a mismatch between format 
>>> specifiers and arguments.
>>
>> Oh, not at all.
>>
>> ```d
>> import std.stdio;
>> alias Seq(T...)=T;
>> void main(){
>>     writefln(i"$(Seq!(1,2)) %s");
>> }
>> ```

1027 can write a format string for a tuple as: "%s%s %%s" because the number of 
elements in the tuple is known at compile time.


> Yes, and there is more:
> 
> ```d
> writefln(i"is it here? ${}(1) Or here? %s");
> ```

An empty format ${} would be a compile time error. The %s would be rewritten as %%s.


> Bottom line is that if we make `%s` special, then all functions must deal with 
> the consequences. There is not a format specifier you can come up with that is 
> not easily reproduced in the string literal directly -- you have to escape it 
> and *know* that you must escape it. The easier path is just not to deal with 
> format specifiers at all -- tell the library exactly where the pieces are.

Escaping % is not hard to do. It's ordinary.


> And by the way, your example brings up another point not recently brought up 
> where 1036e handles and DIP1027 does not: tuples as interpolated expressions. 
> Because each expression is enclosed by `InterpolatedLiteral` pieces, you can 
> tell which ones were actually tuples.

And with 1027 the format string will be of type `FormatString` (not `string`), 
and you can tell which ones were actually tuples. So I take that back, nested 
formats are easily supported.

These are all straightforward solutions.



More information about the Digitalmars-d mailing list