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

Arine arine123445128843 at gmail.com
Mon Feb 3 02:57:41 UTC 2020


On Sunday, 2 February 2020 at 23:54:35 UTC, Adam D. Ruppe wrote:
> 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
>
>
> struct __d_format_literal(string fmt) {
>         enum f = fmt;
>         alias f this;
> }
>
> That implicitly converts and just works in printf. That's the 
> answer.

I don't think you should compromise. Using printf as the basis 
just limits what can be done with an interpolated string. How do 
you handle custom types?

The DIP doesn't go over this but it'd have to either disallow it 
completely. Or convert it to a string first using `.toString()`, 
or similar. Since printf() wouldn't be able to take a custom 
type. This inhibits any sort of user implementation or 
customization and forces the type to be converted to a string 
first, losing any additional detail and preventing possible 
optimizations in only allocating one buffer for the entire thing. 
For each object toString() would allocate it's own buffer, when 
it could be constructed in place.

     SqlValue value;
     ExecuteSettings settings;

     execute(settings, i"SELECT * FROM table WHERE value=$value");

     void execute(InterpolatedString)(ref ExecuteSettings 
settings, InterpolatedString str) {
         string output;

         // static foreach(i; str.args) {
         // static if(is(typeof(str.args[i]) == SqlValue)) {
         // ...

         // typeof(str.args[i]) == SqlValue
         if( str.args[i].someProperty && settings.someSetting ) {
             // ...
         }

         str.args[i].emplaceToString(output); // or otherwise

     }

     printf(i"something $value".c); // ok, "c" would call 
toString() to make it compatible
     printf(i"something $value"); // or with overload for printf()

Compared to how'd you have to implement it with the current DIP:

     // this implementation can be used with printf
     void execute(Args...)(ref ExecuteSettings settings, string 
format, Args args) {
         // typeof(args[0]) == string, can't determine what type 
it was
         // more difficult to parse format and verify it is valid
         // can't access SqlValue for properties as it is now just 
a string
     }

     printf(i"something $value"); // works, calls toString first


Or to retain the type, it would then not work with printf().

     void execute(Args...)(ref ExecuteSettings settings, string 
format, Args args) {
         // typeof(args[0]) == SqlValue
         // what specifier was inserted into format? %s?
         // what if we know we can check now and instead use %d?
         // now we have to be able to parse printf-style formats 
properly to change
         // the formatting to be more efficient and make more sense
         //
         // also can't do in place optimizations without 
completely re-implementing
         // sprintf or otherwise support all of printf format 
capabilities
     }

     printf(i"something $value"); // error, passing SqlValue
     printf(i"something $value.toString()"); // ok, but kind of 
counter intuitive

Trying to cator to printf results in an implementation with the 
least amount of flexibility imo. It forces legacy debt onto the 
user to support. It will ultimately just be left to the handful 
of functions that use it now.






More information about the Digitalmars-d mailing list