Discussion Thread: DIP 1036--String Interpolation Tuple Literals--Community Review Round 2

Steven Schveighoffer schveiguy at gmail.com
Wed Feb 3 17:40:40 UTC 2021


On 2/3/21 11:52 AM, Q. Schroll wrote:
> On Friday, 29 January 2021 at 12:58:32 UTC, Dukc wrote:
>> On Thursday, 28 January 2021 at 14:58:36 UTC, Steven Schveighoffer at 
>> the feedback theard wrote:
>>> On 1/28/21 3:35 AM, Dukc wrote:
>>>> The DIP states that foo(i"a:${a}, ${b}.") is rewritten as 
>>>> `foo(Interp!"a:", a, Interp!", ", b, Interp!".")`. It think it's 
>>>> better to rewrite it as `foo(Interp!"a:", Interp!typeof(a)(a), 
>>>> Interp!", ", Interp!typeof(b)(b), Interp!".")`. That way, `foo` has 
>>>> easier time introspecting which came from the interpolated string.
>>>
>>> First, I don't think it's critical for overloading, and will simply 
>>> add to the template bloat. What are you going to do differently with 
>>> `a` than you would with `Interp!(typeof(a))(a)`?
>>
>> I was mainly thinking that I'd have easier time differentiating 
>> between an `int` in interpolated string and `int` passed before/after 
>> the interpolated string. And I have a type that will implicitly 
>> convert to string if I want to do that - no need to call 
>> `to!string(a)` or `a.Interp!(typeof(a))` first.
>>
>>> The parameters are guaranteed to start and end with an 
>>> InterpolationLiteral, so one can assume that non-literal arguments 
>>> are interspersed inside the literal.
>>
>> It can be done, but it sounds more complex for the introspecting 
>> function. I'm not strict about this though, what the DIP now proposes 
>> be worth it to be able to pass `ref` parameters in interpolated strings.
>>
>>>
>>>> The type of interpolated string literal is very special cased. [snip]
>>>
>>> I was fully aware that this would be the most controversial part. I 
>>> feel like it will not be full of corner cases, but I'm not sure. Can 
>>> you specify any?
>>>
>>> Consider a normal string literal can be used as a string, 
>>> immutable(char)*, wstring, or dstring. I find it very similar to this 
>>> feature, and I don't feel like there are a lot of corner cases there.
>>
>> A string literal is a string that is implicitly assignable to the 
>> other alternatives via value range propagation mechanics, or that's 
>> how I understand it at least.
>>
>> The compromise that the interpolated string would be an expanded 
>> tuple, that would be implicitly assignable to string via value range 
>> propagation mechanics, sounds acceptable. But it needs to be clear IMO 
>> what the primary type of an interpolated string is. If it is not an 
>> expanded tuple, what it is then? I mean that this must be guaranteed 
>> to pass IMO:
> 
> Sorry, I'm late to the game here. This reminds me of slices vs static 
> arrays.
> As a reminder, to a newcomer,
>      auto xs = [ 1, 2, 3 ];
> looks like it would infer int[3] as the type of xs. It is obviously the 
> most descriptive type for the literal. Why would it infer int[] 
> forgetting its compile-time known length and even do an allocation? That 
> seems so much worse. Even typeof([1,2,3]) is int[] and not int[3]. We 
> know why D does it the way it does and goes int[3] with no allocation 
> only if requested explicitly. You can do that with a template with a 
> flexible length like this:
>      void takesStaticArray(size_t n)(int[n] staticArray);
> Here, `n` can usually be inferred from the argument.
> 
> Interpolated strings could do the exact same thing:
> 1. make typeof(i"...") result to `string`.
> 2. make auto str = i"..." infer string (cf. typeof) and gc-allocate if 
> necessary.
> 3. give i"..." a secondary type akin to [1,2,3] having int[3] as a 
> secondary type.

I don't want to do it that way, because then the overload is not easy to 
ask for. I really really don't want the string form to be passed into a 
vararg template.

I've been having second thoughts about having auto x = i"..."; be a 
string, and typeof(i"...") be a string. See my later response here: 
https://forum.dlang.org/post/rv6jr4$uor$1@digitalmars.com

> If an interpolated string is bound to a parameter of that secondary type 
> (`interp` in the DIP) it uses its secondary type (cf. calling 
> takesStaticArray with [1,2,3]). In any other case, e.g. `auto` or 
> otherwise generic template parameters will infer string.
> 
> Getting a string is probably what most users expect most of the time. 
> Handling the secondary type must be explicit. It is almost an 
> implementation detail that shouldn't be exposed to the user too easily.

I'm not sure how this could be possible. You can't say T... and have it 
match the tuple over the string, unless the primary type is the tuple.

But if you have ideas, surely I'd prefer it to be a string first in most 
cases!

-Steve


More information about the Digitalmars-d mailing list