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