DIP 1027--String Interpolation--Final Review Discussion Thread

Steven Schveighoffer schveiguy at gmail.com
Mon Feb 3 14:37:22 UTC 2020


On 2/2/20 6:54 PM, Adam D. Ruppe wrote:
> 
> I'm dropping other stuff just cuz I don't want to argue down rabbit 
> holes. Let's see what common ground we can find and build upon that.
> 
> On Sunday, 2 February 2020 at 20:13:36 UTC, Steven Schveighoffer wrote:
>> I think we could get the best of both worlds if the interpolated 
>> string itself was not just a string, but rather a library-defined type 
>> (well something slightly more special -- it should implicitly cast to 
>> a null-terminated immutable(char)* if needed, just like string literals).
> 
> Yes, indeed, I proposed this in the last round too. I think it is our 
> best bet for a compromise to salvage this DIP.
> 
> You would lose the methods on it ... however, we have UFCS, so not a 
> deal breaker.
> 
> Lots of the community is opposed to the requirement to import something 
> for the UFCS flavor; that is a psychological barrier for many people. 
> I'm not in love with that myself, but I can live with it.

Not too concerned. If you want actual strings from this feature, then 
you need to pay the cost of importing stuff from phobos. It also allows 
for someone to define their own less-heavy version.

> And I remain legit concerned about implicit conversions though:
> 
> printf(i"$some_int");
> 
> that looks OK, but SILENTLY DOES THE WRONG THING.  But if dmd warned on 
> the format specifier like gcc does, we're cool. Could be an enhancement 
> later. I warn about this but do not withhold support about it.

This doesn't concern me AT ALL. If you want printf to work, you need to 
understand printf and the problems it can have. writef is there, and 
works. I don't think the compiler has any business complaining about 
printf usage.

> The DIP mentions this one: `printf("%s $something", foo);` This also 
> does the wrong thing. But so does `printf(i"$something% complete");`, 
> since `% c` is a valid format specifier.... yet it doesn't look like 
> one, especially since the interpolated string use $ now.
> 
> We need to make % go ahead and get translated to %% by the compiler so 
> the parsing function can still work sanely with it. That's the solution 
> to this. If the compiler makes % magic in the generated string, it needs 
> to encode % in the user input too.

I disagree. I don't want my SQL interpolated strings (which can use % 
for matching) to be tainted by the interpolation. Again, if you want to 
use string interpolation to call printf (or writef), you need to know 
what will happen, just like if you were calling it with string + args form.

> Then put a type on the format string, if it implicitly converts is up to 
> y'all.  I just need some way to detect the format string's presence via 
> in the type system for overloading existing functions.

I think this is the only thing we really agree on. Having a specialized 
type gives so much more options, and should decay into what is already 
proposed.

> 
> Do those two small changes and this DIP will have my support.
> 
> * specify that % in the user string gets translated to %% in the format 
> literal
> * put the format literal in a wrapper type.
> 
> i"$foo %"
> 
> is translated to the tuple:
> 
> __d_format_literal!("%s %%"), foo

I'd do it a little different, so we don't throw away the work the 
compiler already did:

i"$apples and ${%d}bananas"

=>

(__d_format_literal!(Format.init, " and ", Format("%d")), apples, bananas)

If there is an overload that takes whatever this returns, then this is 
used as the lowering. Otherwise, a string literal as specified by the 
DIP is used (or we have an alias this in the result to the string version).

> struct __d_format_literal(string fmt) {
>          enum f = fmt;
>          alias f this;
> }
> 
> That implicitly converts and just works in printf. That's the answer.

This isn't much better than just passing the string, but still provides 
overload capability. However, this still means we have to parse things 
in the library if we want to do anything interesting.

>> And we can actually add later the idea of making the interpolated 
>> string a new type after this DIP is implemented,
> 
> As soon as this DIP is implemented, we're frozen. Any future change will 
> face additional barriers as a breaking change. It is going to be a lot 
> better to just do it at least somewhat correctly now.

I think we can do it in a way that's not a breaking change. Or at least 
doesn't break things that explicitly accept string format + args.

We shouldn't be frozen with this. And of course, string interpolation 
may prove to leave things wanting, so there may be an appetite to update 
to something like this.

-Steve


More information about the Digitalmars-d mailing list