Feedback Thread: DIP 1036--Formatted String Tuple Literals--Community Review Round 1

Steven Schveighoffer schveiguy at gmail.com
Wed Sep 9 19:48:44 UTC 2020


On 9/9/20 12:43 PM, Seb wrote:
> Just to re-state my points:
> 
> 1) I strongly believe that printf shouldn't make up most of the design 
> considerations and DIPs space. This is about a D feature, not C. Trying 
> to bridge both worlds will please none.
> 
> 2) No C string magic: "spec will automatically convert to a compile-time 
> NUL-terminated C string if spec.hasAllSpecs is true." is just a big NO.

It does not take up most of the design consideration, or the DIP's space.

It is a judgment call as to which is more useful. In our opinion, a C 
library is unlikely to provide bindings that work directly with 
parsed-out format specifiers, whereas a D function likely could provide 
those. It's much more likely that a D function would rather provide 
mechanisms to work directly with the actual spec type than have a 
conversion to a string happen.

This is basically a free feature on top of the existing implementation. 
It is not the main focus.

> 3) `${%d}bananas` is an awful syntax compromise as it will be very 
> unintuitive to newcomers as it's not clear what the variable is.
> For example, `${bananas:2f}` would read much better. In general, I like 
> the way Python handles the format specifiers:
> 
> https://www.python.org/dev/peps/pep-0498/#format-specifiers

That is syntactically a problem. Remember that any expression can be the 
Argument to the string interpolation parameter. A colon followed by 2f 
could be valid syntax at the end of an expression.

${cond ? 1f:2f}

If there are unambiguous alternatives that would be more acceptable to 
the language maintainers, we are fine with it, as long as the format 
string resolves in the way specified with the DIP. Note that this syntax 
comes directly from DIP1027.

> 4) Format specifiers need to be 100% customizable. The NodeJS community 
> got this right and it lead to a few awesome libraries. One example that 
> has been mentioned before is https://github.com/chalk/chalk

Format specifiers are 100% customizable. You specify whatever you want 
in the format specifier, or as part of the expression.

> 5) APIs will need to be written specifically to cater for 
> _d_interpolated_strings if no implicit conversion is allowed anyhow, so 
> the interpolated_string struct should always containing its arguments. 
> This would allow for adding methods like `idup`, `toString` etc. 
> directly inside the struct. I don't see the DIP explaining the advantage 
> of doing rewrite magic to `writefln(<interpolationSpec>, apples, 
> bananas, apples + bananas);` and this will only confuse people.
> More importantly, it severely restricts the freedom for function 
> designers as they can not accept two interpolated strings nor argument 
> afters the interpolated string.
> Note that this also removes most-of the problems with "wrong-use of 
> functions".

The issue here is that enclosing the parameters into a single structure 
has issues with forwarding ref-ness, or binding to aliases or lazy 
parameters, etc.

> 6) "if a StringLiteral follows an InterpolatedString, it is appended to 
> the InterpolatedString in the parsing pass (not the lexer pass)". 
> Automatic string concatenation was deprecated for good reasons. This DIP 
> does not provide a good motivation for this nor explains how all the 
> risks learned from this are mitigated.

This was copy-pasted from DIP1027. We do not have strong preferences 
either way. However, forming interpolation string tuples using multiple 
lines or multiple types of strings should be supported. For sure, 
explicit concatenation does not work for this instance. Implicit 
concatenation solves the problem, but I'm open to other ideas.

> 
> 7) A main use-case for interpolated strings is D mixins. It doesn't 
> address combineing it with token strings  to create D code, e.g. 
> `qi{class D { auto $varName = 20; }`

mixin(i""q{class D { auto $varName = 20; });

> 8) A lot of people want `string k = i"foo $bar";` to work and the DIP 
> should at least a very good explanation why the compiler shouldn't 
> rewrite such assignments to `string k = i"foo $bar".idup;` as it's very 
> clear what the user wants here and the @nogc argument applies to normal 
> strings as well.
> In fact, the overload resolution could be changed, s.t. d_to_string 
> struct overloads have a higher priority, but the `string` overloads are 
> still being considered. The compiler would need to implement this logic 
> anyhow to issue the mentioned: "Did you mean to use .idup?" messages.

The idup is a convenience feature that can be used on top of the 
proposal. The DIP as proposed could still be valid without idup, and I 
do not want to tie acceptance or rejection based on the presence of the 
idup function. That being said, if the language maintainers wish to add 
more compiler magic to this in order to accept, it is not something that 
we would be against.

What we are against is the format spec ALONE implicitly converting to a 
string.

> 9) The DIP does not mention operator overloading, e.g.
> 
> string s = "foo";
> ....
> s ~= i"foo $bar";
> 
> IMHO this is unambiguous and would reduce the need to call `.idup`.

This specific usage is not possible, without more compiler magic. There 
is no opOpAssignRight (or whatever you would call it) that would make 
this possible, even if the interpolation string was a struct that did 
have access to the parameters.

However, for a custom type for s, this would work exactly as intended 
with your code:

void opOpAssign(string op: "~", S, Args...)(S spec, Args args) if 
(isInterpolationSpec!S)
{
     myOutputRange.formattedWrite(spec.toFormatString!"%s", args);
}

-Steve


More information about the Digitalmars-d mailing list