www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Feedback Thread: DIP 1036--Formatted String Tuple Literals--Community

reply Mike Parker <aldacron gmail.com> writes:
This is the feedback thread for the first round of Community 
Review of DIP 1036, "Formatted String Tuple Literals".

===================================
**THIS IS NOT A DISCUSSION THREAD**

Posts in this thread must adhere to the feedback thread rules 
outlined in the Reviewer Guidelines (and listed at the bottom of 
this post).

https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

That document also provides guidelines on contributing feedback 
to a DIP review. Please read it before posting here. If you would 
like to discuss this DIP, please do so in the discussion thread:

https://forum.dlang.org/post/vwrbvacnuerasbphgtjy forum.dlang.org
==================================

You can find DIP 1036 here:

https://github.com/dlang/DIPs/blob/15537f9b36afa48f1c1cd57468e8c77f8f2499dd/DIPs/DIP1036.md

The review period will end at 11:59 PM ET on September 22, or 
when I make a post declaring it complete. Feedback posted to this 
thread after that point may be ignored.

At the end of this review round, the DIP will be moved into the 
Post-Community Round 1 state. Significant revisions resulting 
from this review round may cause the DIP manager to require 
another round of Community Review, otherwise the DIP will be 
queued for the Final Review.

==================================
Posts in this thread that do not adhere to the following rules 
will be deleted at the DIP author's discretion:

* All posts must be a direct reply to the DIP manager's initial 
post, with only two exceptions:

     - Any commenter may reply to their own posts to retract 
feedback contained in the original post

     - The DIP author may (and is encouraged to) reply to any 
feedback solely to acknowledge the feedback with agreement or 
disagreement (preferably with supporting reasons in the latter 
case)

* Feedback must be actionable, i.e., there must be some action 
the DIP author can choose to take in response to the feedback, 
such as changing details, adding new information, or even 
retracting the proposal.

* Feedback related to the merits of the proposal rather than to 
the contents of the DIP (e.g., "I'm against this DIP.") is 
allowed in Community Review (not Final Review), but must be 
backed by supporting arguments (e.g., "I'm against this DIP 
because..."). The supporting arguments must be reasonable. 
Obviously frivolous arguments waste everyone's time.

* Feedback should be clear and concise, preferably listed as 
bullet points (those who take the time to do an in-depth review 
and provide feedback in the form of answers to the questions in 
this document will receive much gratitude). Information 
irrelevant to the DIP or is not provided in service of clarifying 
the feedback is unwelcome.
Sep 08 2020
next sibling parent reply Daniel N <no public.email> writes:
On Tuesday, 8 September 2020 at 10:59:58 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review of DIP 1036, "Formatted String Tuple Literals".

 ===================================
 **THIS IS NOT A DISCUSSION THREAD**

 Posts in this thread must adhere to the feedback thread rules 
 outlined in the Reviewer Guidelines (and listed at the bottom 
 of this post).

 You can find DIP 1036 here:

 https://github.com/dlang/DIPs/blob/15537f9b36afa48f1c1cd57468e8c77f8f2499dd/DIPs/DIP1036.md
Correct me if I'm wrong, but this proposal is incompatible with scanf. *) 'scanf' should be added in a section with known limitations. *) Can you envision a way to solve this issue, in a future more powerful D, without changing the design of this DIP?
Sep 08 2020
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 8 September 2020 at 19:21:49 UTC, Daniel N wrote:
 Correct me if I'm wrong, but this proposal is incompatible with 
 scanf.
int foo; scanf(i"${%d}(&foo)"); expands to: scanf(InterpolatedString("%d"), &foo); then InterpolatedString implicitly `alias this`es itself to: scanf("%d".ptr, &foo); which is exactly what is required.
Sep 08 2020
prev sibling next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 9/8/20 3:21 PM, Daniel N wrote:
 On Tuesday, 8 September 2020 at 10:59:58 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community Review of 
 DIP 1036, "Formatted String Tuple Literals".

 ===================================
 **THIS IS NOT A DISCUSSION THREAD**

 Posts in this thread must adhere to the feedback thread rules outlined 
 in the Reviewer Guidelines (and listed at the bottom of this post).

 You can find DIP 1036 here:

 https://github.com/dlang/DIPs/blob/15537f9b36afa48f1c1cd57468e8c77f8f24
9dd/DIPs/DIP1036.md 
Correct me if I'm wrong, but this proposal is incompatible with scanf. *) 'scanf' should be added in a section with known limitations. *) Can you envision a way to solve this issue, in a future more powerful D, without changing the design of this DIP?
Can you clarify? I believe this would work: int i; float f; scanf(i"${%d}(&i) ${%f}(&f)"); It would be essentially called as scanf("%d %f", &i, &f); However, I don't know that this is something you would typically do. scanf was not a target for this DIP. -Steve
Sep 08 2020
prev sibling parent Daniel N <no public.email> writes:
On Tuesday, 8 September 2020 at 19:21:49 UTC, Daniel N wrote:
 Correct me if I'm wrong, but this proposal is incompatible with 
 scanf.

 *) 'scanf' should be added in a section with known limitations.
 *) Can you envision a way to solve this issue, in a future more 
 powerful D, without changing the design of this DIP?
I retract my comment, after reading Adam's and Steven's reply. I misread a section of the proposal, thinking &var would have to be send as a template param, but it doesn't, so it works fine. Impressive work!
Sep 08 2020
prev sibling next sibling parent reply Piotr Mitana <the.mail.of.mi2 gmail.com> writes:
Do I understand correctly, that

int i = 5;
string someStr = i"Give me ${i} apples";

will not work? In this case it's usage is very limited and this I 
don't think it should be a new syntax. If it could be replaced 
with either a template or a trait, it could be the way to go. But 
otherwise it will be very unintuitive.
Sep 09 2020
parent Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 9 September 2020 at 09:25:26 UTC, Piotr Mitana 
wrote:
 string someStr = i"Give me ${i} apples";
yourfile.d(3): Cannot assign value of type `interpolated_tuple` to variable of type `string`. Try using `.idup`. Learn more at wiki.dlang.org/interpolation
Sep 09 2020
prev sibling next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Tuesday, 8 September 2020 at 10:59:58 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review of DIP 1036, "Formatted String Tuple Literals".
Scott Meyers has a talk, available on youtube [1], in which he argues that the single most important software design guideline is that "interfaces should be easy to use correctly, and hard to use incorrectly." Let's assume, for the sake of argument, that we all agree with him. (If you do not agree, feel free to disregard this comment.) What this DIP proposes is an interface that is both hard to use correctly, and hard to use incorrectly. While the efforts taken to prevent misuse are admirable, the burden they impose on programmers who merely wish to use string interpolation as-intended is unacceptably high. Personally, I've supported adding string interpolation to D in the past, but I would not use it if it were implemented as this DIP proposes. I could point to specific details of the proposal that I think lead to undue complexity, but I don't think I need to. The fact that the DIP authors feel the need to devote as many words to "justifications" of their proposal's complexity as they do to actually explaining it in the first place is evidence enough. They are well aware of what they have written, and of its flaws. I think the reason the DIP authors have ended up with such a flawed proposal is that they have tried too hard to reach a compromise between mutually-incompatible visions of what string interpolation ought to be. Some people want compatibility with `printf`, and others want compatibility with `writeln`, so we end up with a proposal that's compatible with neither. Some people want implicit conversion to `string`, others want implicit conversion to `const(char)*`, so we end up with explicit conversion required for both. And so on, for each point of contention raised in every previous discussion of string interpolation in D. This approach is fundamentally flawed. It can lead to Good Work, but never to Great Work [2], and Great Work is the standard that I expect a language addition like this will be held to. As such, I do not think any version of this proposal has much chance of being accepted by the language maintainers. I recommend that this DIP be withdrawn. [1] https://www.youtube.com/watch?v=5tg1ONG18H8 [2] https://forum.dlang.org/thread/q6plhj$1l9$1 digitalmars.com?page=15
Sep 09 2020
next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 9/9/20 10:19 AM, Paul Backus wrote:
 On Tuesday, 8 September 2020 at 10:59:58 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community Review of 
 DIP 1036, "Formatted String Tuple Literals".
First, thanks for your opinion. We value all the opinions of people in the community, especially long-standing members with a lot of experience with D such as yourself. However, this entire post has no actionable or specific items, and really should have been added to the discussion thread instead. I'm responding to it here because in the past I have had cases where I posted feedback and got no response or changes, and it irked me.
 
 What this DIP proposes is an interface that is both hard to use 
 correctly, and hard to use incorrectly. While the efforts taken to 
 prevent misuse are admirable, the burden they impose on programmers who 
 merely wish to use string interpolation as-intended is unacceptably 
 high. Personally, I've supported adding string interpolation to D in the 
 past, but I would not use it if it were implemented as this DIP proposes.
The interface is actually simple to use. Without specific concerns, it's hard to address these comments further.
 
 I could point to specific details of the proposal that I think lead to 
 undue complexity, but I don't think I need to. The fact that the DIP 
 authors feel the need to devote as many words to "justifications" of 
 their proposal's complexity as they do to actually explaining it in the 
 first place is evidence enough. They are well aware of what they have 
 written, and of its flaws.
This measure of "complexity" is arbitrary, and has no bearing on the validity of the DIP. in fact, many already-accepted DIPS have relatively similar ratios of description and rationale. One thing to note is that this DIP has a prior very similar DIP, but just used a string for the formatting specification. The Justification section is ENTIRELY devoted to explaining why this DIP does not use that. In fact, we can remove the entire section, and it doesn't change anything about the DIPs features or benefits. But without a distinction between DIP1027 and this DIP, arguably it would be rejected on principle (why approve something that was just rejected).
 I think the reason the DIP authors have ended up with such a flawed 
 proposal is that they have tried too hard to reach a compromise between 
 mutually-incompatible visions of what string interpolation ought to be. 
 Some people want compatibility with `printf`, and others want 
 compatibility with `writeln`, so we end up with a proposal that's 
 compatible with neither. Some people want implicit conversion to 
 `string`, others want implicit conversion to `const(char)*`, so we end 
 up with explicit conversion required for both. And so on, for each point 
 of contention raised in every previous discussion of string 
 interpolation in D.
This assessment is incorrect. There is an implicit conversion of the format specification to immutable char * in the circumstance that you have specified all format information. This makes it compatible with printf. Implicitly converting the format spec to string would result in undoubtedly incorrect function calls, and we address the concerns quite thoroughly. Even if it is a desired thing, it's not something we should provide. This is not the same as trying and failing. We intend misuse of string conversion to not compile. I would characterize the DIP as not only trying to address these issues, but succeeding. printf is supported for valid cases. writefln will be supported as expected. Conversion to string or immutable char * is possible with a library call which should be provided. There are no flaws I can see. -Steve
Sep 09 2020
prev sibling parent reply Seb <seb wilzba.ch> writes:
On Wednesday, 9 September 2020 at 14:19:43 UTC, Paul Backus wrote:
 On Tuesday, 8 September 2020 at 10:59:58 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review of DIP 1036, "Formatted String Tuple Literals".
Scott Meyers has a talk, available on youtube [1], in which he argues that the single most important software design guideline is that "interfaces should be easy to use correctly, and hard to use incorrectly." Let's assume, for the sake of argument, that we all agree with him. (If you do not agree, feel free to disregard this comment.) What this DIP proposes is an interface that is both hard to use correctly, and hard to use incorrectly. While the efforts taken to prevent misuse are admirable, the burden they impose on programmers who merely wish to use string interpolation as-intended is unacceptably high. Personally, I've supported adding string interpolation to D in the past, but I would not use it if it were implemented as this DIP proposes. I could point to specific details of the proposal that I think lead to undue complexity, but I don't think I need to. The fact that the DIP authors feel the need to devote as many words to "justifications" of their proposal's complexity as they do to actually explaining it in the first place is evidence enough. They are well aware of what they have written, and of its flaws. I think the reason the DIP authors have ended up with such a flawed proposal is that they have tried too hard to reach a compromise between mutually-incompatible visions of what string interpolation ought to be. Some people want compatibility with `printf`, and others want compatibility with `writeln`, so we end up with a proposal that's compatible with neither. Some people want implicit conversion to `string`, others want implicit conversion to `const(char)*`, so we end up with explicit conversion required for both. And so on, for each point of contention raised in every previous discussion of string interpolation in D. This approach is fundamentally flawed. It can lead to Good Work, but never to Great Work [2], and Great Work is the standard that I expect a language addition like this will be held to. As such, I do not think any version of this proposal has much chance of being accepted by the language maintainers. I recommend that this DIP be withdrawn.
I second this. I like this DIP more than 1027, but I fully agree with Paul that in its current form this DIP does too many wrong compromises. 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. 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 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 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". 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. 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; }` 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. 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`.
Sep 09 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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
Sep 09 2020
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 9/9/20 3:48 PM, Steven Schveighoffer wrote:
 mixin(i""q{class D { auto $varName = 20; });
Oops, this should be: mixin(i""q{class D { auto $varName = 20; }.idup); -Steve
Sep 09 2020
prev sibling next sibling parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Tuesday, 8 September 2020 at 10:59:58 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review of DIP 1036, "Formatted String Tuple Literals".
The fear of the gc has negatively impact this DIP. Why does the average programmer have to call .idup when it comes frequent used feature in other languages? If speed is an issue then the solution is to optimized the gc, not avoid it entirely. We shouldn't let c/c++ fear of the garbage collector potential handicap new d features here. -Alex
Sep 09 2020
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 9 September 2020 at 18:39:59 UTC, 12345swordy wrote:
 The fear of the gc has negatively impact this DIP.
That decision wasn't made because of the GC. It is more due to working the the variety of use cases in D like ref params, types without toString, compile-time arguments, and more that are all well-defined for argument lists but not in other places. Perhaps the text should call these out more explicitly.
Sep 09 2020
prev sibling parent 12345swordy <alexanderheistermann gmail.com> writes:
On Wednesday, 9 September 2020 at 18:39:59 UTC, 12345swordy wrote:
 On Tuesday, 8 September 2020 at 10:59:58 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review of DIP 1036, "Formatted String Tuple Literals".
The fear of the gc has negatively impact this DIP. Why does the average programmer have to call .idup when it comes frequent used feature in other languages? If speed is an issue then the solution is to optimized the gc, not avoid it entirely. We shouldn't let c/c++ fear of the garbage collector potential handicap new d features here. -Alex
I forgot the mention, that this dip doesn't explore how other languages implement string interpolation. -Alex
Sep 13 2020
prev sibling next sibling parent reply burt <invalid_email_address cab.abc> writes:
On Tuesday, 8 September 2020 at 10:59:58 UTC, Mike Parker wrote:
 This is the feedback thread for the first round of Community 
 Review of DIP 1036, "Formatted String Tuple Literals".

 ===================================
 **THIS IS NOT A DISCUSSION THREAD**

 Posts in this thread must adhere to the feedback thread rules 
 outlined in the Reviewer Guidelines (and listed at the bottom 
 of this post).

 https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

 That document also provides guidelines on contributing feedback 
 to a DIP review. Please read it before posting here. If you 
 would like to discuss this DIP, please do so in the discussion 
 thread:

 https://forum.dlang.org/post/vwrbvacnuerasbphgtjy forum.dlang.org
 ==================================

 You can find DIP 1036 here:

 https://github.com/dlang/DIPs/blob/15537f9b36afa48f1c1cd57468e8c77f8f2499dd/DIPs/DIP1036.md

 The review period will end at 11:59 PM ET on September 22, or 
 when I make a post declaring it complete. Feedback posted to 
 this thread after that point may be ignored.

 At the end of this review round, the DIP will be moved into the 
 Post-Community Round 1 state. Significant revisions resulting 
 from this review round may cause the DIP manager to require 
 another round of Community Review, otherwise the DIP will be 
 queued for the Final Review.

 ==================================
 Posts in this thread that do not adhere to the following rules 
 will be deleted at the DIP author's discretion:

 * All posts must be a direct reply to the DIP manager's initial 
 post, with only two exceptions:

     - Any commenter may reply to their own posts to retract 
 feedback contained in the original post

     - The DIP author may (and is encouraged to) reply to any 
 feedback solely to acknowledge the feedback with agreement or 
 disagreement (preferably with supporting reasons in the latter 
 case)

 * Feedback must be actionable, i.e., there must be some action 
 the DIP author can choose to take in response to the feedback, 
 such as changing details, adding new information, or even 
 retracting the proposal.

 * Feedback related to the merits of the proposal rather than to 
 the contents of the DIP (e.g., "I'm against this DIP.") is 
 allowed in Community Review (not Final Review), but must be 
 backed by supporting arguments (e.g., "I'm against this DIP 
 because..."). The supporting arguments must be reasonable. 
 Obviously frivolous arguments waste everyone's time.

 * Feedback should be clear and concise, preferably listed as 
 bullet points (those who take the time to do an in-depth review 
 and provide feedback in the form of answers to the questions in 
 this document will receive much gratitude). Information 
 irrelevant to the DIP or is not provided in service of 
 clarifying the feedback is unwelcome.
I think that, in principle, the way that is described by the DIP is the best way for i"" strings to work. However, I still have some points: * The DIP says the name of the interpolation spec template defined in DRuntime is unspecified, but then does specify a name for `isInterpolationSpec`. Is this even necessary? I think that name should remain unspecified as well. * The DIP tries to explain the implementation of `toFormatString` and `hasAllSpecs` in great depth. But is this even necessary? It seems to me that this should actually be an optional mechanic (like `idup`) that is implemented by DRuntime as a convenience function, and those sections can be removed entirely, which will also simplify the DIP, or can be moved to an "optional mechanics" section. * The addition of an optional `alias this` implicit conversion only if all the format specifiers are defined seems way too complicated for me. My preference would be to add an implementation-defined function (just like `idup` now) to the template, so users of `printf` can just write: ```d printf(i"${%d}a + ${%d}b = ${%d}(a + b)".toFormatz()); ``` or something. Alternatively, it's not that hard to write a wrapper around `printf` which overloads for interpolated strings, but an implicit conversion tailored for immutable(char)* seems excessive. * The grammar changes have some issues: "Expression" is defined, but this name already exists at https://dlang.org/spec/grammar.html#expressions. So, it should be given its own name. * I feel like interpolated strings should work out of the box together with `mixin` without requiring a DRuntime CTFE `.idup` call. * As a personal matter, the i"" q{$a + $b} implicit concatenation magic seems weird. My advice would be to just add `iq{$a + $b}`. (* As a minor point, some code blocks don't have the language set to D, which would improve readability.)
Sep 11 2020
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 9/11/20 1:13 PM, burt wrote:
 I think that, in principle, the way that is described by the DIP is the 
 best way for i"" strings to work. However, I still have some points:
Thanks. We are most certainly evolving on what we think is best, based on feedback here and internal discussions. I hate to leave this feedback hanging, even though likely the DIP as is will be moot once we update. However I will respond to the points you made in the context of the current DIP text.
 
 * The DIP says the name of the interpolation spec template defined in 
 DRuntime is unspecified, but then does specify a name for 
 `isInterpolationSpec`. Is this even necessary? I think that name should 
 remain unspecified as well.
As a function which accepts parameters, you need some way to determine whether you have an interpolation spec. If we don't name the type or template, you can't specify the type to accept. So you need some way to determine that you got one. Doing it this way leaves more discretion to the implementation.
 * The DIP tries to explain the implementation of `toFormatString` and 
 `hasAllSpecs` in great depth. But is this even necessary? It seems to me 
 that this should actually be an optional mechanic (like `idup`) that is 
 implemented by DRuntime as a convenience function, and those sections 
 can be removed entirely, which will also simplify the DIP, or can be 
 moved to an "optional mechanics" section.
In the current DIP text, toFormatString is the only official way to fetch the spec text. hasAllSpecs is really just a mechanism to enable the implicit conversion to const char *. I'm not sure we had to allow access to it.
 
 * The addition of an optional `alias this` implicit conversion only if 
 all the format specifiers are defined seems way too complicated for me. 
 My preference would be to add an implementation-defined function (just 
 like `idup` now) to the template, so users of `printf` can just write:
 ```d
 printf(i"${%d}a + ${%d}b = ${%d}(a + b)".toFormatz());
 ```
 or something.
This won't work, because you need to translate just the format specifier, and your proposed form must pass through all the parameters. This *might* work, if you use a template, but it's getting to the point where it's really not worth it.
 Alternatively, it's not that hard to write a wrapper 
 around `printf` which overloads for interpolated strings, but an 
 implicit conversion tailored for immutable(char)* seems excessive.
The goal was to keep the ability from DIP 1027 to be able to call printf (and other C format + varargs functions) without modifications. However, we agree with you (and most other commenters here) that this requirement does not hold its own weight, and too much complexity was added for this one possibility.
 
 * The grammar changes have some issues: "Expression" is defined, but 
 this name already exists at 
 https://dlang.org/spec/grammar.html#expressions. So, it should be given 
 its own name.
There are more than just this one problem in the grammar (I have found another which nobody has pointed out yet). Admittedly, both Adam and I are not grammar experts, and we basically copied what Walter had written in DIP1027.
 
 * I feel like interpolated strings should work out of the box together 
 with `mixin` without requiring a DRuntime CTFE `.idup` call.
It would be nice (along with any other usage that binds directly to a string). We think we have this issue solved with the next DIP iteration.
 
 * As a personal matter, the i"" q{$a + $b} implicit concatenation magic 
 seems weird. My advice would be to just add `iq{$a + $b}`.
We also agree with this. Again, the next version should help here. This also was a holdover from DIP1027.
 (* As a minor point, some code blocks don't have the language set to D, 
 which would improve readability.)
 
Thanks, I will make sure the code blocks are properly annotated (Mike actually did a lot of them as an editing review). -Steve
Sep 15 2020
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
Under "Wrong-use in unrelated function" it says:

--------
     Window createWindow(string title, int width = 0, int height = 0);

A user has some code that calls it like so:

     import std.conv;
     auto window = createWindow("Process debugger " ~ to!string(pid));

A new version of the compiler is released and the user, eager to try D's new 
string interpolation feature, rewrites that code as would be common in many 
other languages:

     auto window = createWindow(i"Process debugger $pid");

This would compile without error, but would not do what the user intended.
----------

This is indeed correct, but I take issue with "as would be common in many other 
languages". Because of D's close relationship with C, it would be a fair 
statement to compare with C. But C doesn't have string interpolation. It is 
impossible to constrain D based on what people expect from "many other
languages".


is not unreasonable to expect people to at least glance at the instructions 
before assuming D is just like Language X. If they don't (and we're all guilty 
of that) then they get to debug it, like first noticing that the window title 
reads "Process debugger %s", which is not disastrous.

#DIP1038 needs a much better rationale as to why it should be preferred over 
#DIP1027.

(On a related note, I propose that default arguments are an overused feature, 
and should raise an eyebrow when used. There are many other inadvertent
problems 
one can run into with careless use of it.)
Sep 12 2020
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 9/12/20 11:23 PM, Walter Bright wrote:
 Under "Wrong-use in unrelated function" it says:
 
 --------
      Window createWindow(string title, int width = 0, int height = 0);
 
 A user has some code that calls it like so:
 
      import std.conv;
      auto window = createWindow("Process debugger " ~ to!string(pid));
 
 A new version of the compiler is released and the user, eager to try D's 
 new string interpolation feature, rewrites that code as would be common 
 in many other languages:
 
      auto window = createWindow(i"Process debugger $pid");
 
 This would compile without error, but would not do what the user intended.
 ----------
 
 This is indeed correct, but I take issue with "as would be common in 
 many other languages". Because of D's close relationship with C, it 
 would be a fair statement to compare with C. But C doesn't have string 
 interpolation. It is impossible to constrain D based on what people 
 expect from "many other languages".
We meant what many other languages do for string interpolation specifically (there are quite a few users of Python that find a good home with D, I don't think we should ignore them because they didn't come from C). But let's put this on the back burner for a bit, the next version of the DIP I think will solve this problem in a cleaner way.
 

 Haskell. It is not unreasonable to expect people to at least glance at 
 the instructions before assuming D is just like Language X.
We agree with this, as I think actually there aren't really any other languages that have done string interpolation in this exact way. D has a chance here to really shine with its introspection capabilities and focus on lowering. However, it's also good to look at what works in other languages, and to frame the expectations of cross-language developers. If we can make it work like they expect AND cater to D's tremendous introspection capabilities, we have a very big win.
 If they 
 don't (and we're all guilty of that) then they get to debug it, like 
 first noticing that the window title reads "Process debugger %s", which 
 is not disastrous.
I have been thinking a lot about "incorrect usage" and this DIP. How many of us have done: writeln("Name: %s, age: %d", name, age); And are surprised when you get unexpected output. I do it all the time. And it's not terrible, I just fix it and move on. Perhaps we put too much emphasis on the dangers of misuse. But I think a more reasonable pushback on the "surprise" factor here is that if call DOES happen to bind to an existing function not designed to take string interpolation tuples, the parameter ordering is much different than expected (Andrei pointed this out, and it's a very good point). To be fair though, the biggest problem with the createWindow accidental match isn't necessarily the title, but the window width might be 20, or 65000. Honestly, you might not even notice the title when your window appears to open with random sizes.
 #DIP1038 needs a much better rationale as to why it should be preferred 
 over #DIP1027.
Our next revision will be vastly different from DIP1027. So this is kind of a moot point.
 (On a related note, I propose that default arguments are an overused 
 feature, and should raise an eyebrow when used. There are many other 
 inadvertent problems one can run into with careless use of it.)
default parameters are a nice way to avoid having to write simple overloads which just call the other overloads. I wouldn't say this example is *completely* careless, but if I were to design it with this in mind, I probably would have provided a Size struct as the second parameter (and make it a default parameter). The truth is, we don't always get to design the APIs we use, and if we can keep intact the expectations that the original designers had when designing them, the DIP is in a better place. -Steve
Sep 15 2020
prev sibling parent Mike Parker <aldacron gmail.com> writes:
On Tuesday, 8 September 2020 at 10:59:58 UTC, Mike Parker wrote:

 The review period will end at 11:59 PM ET on September 22, or 
 when I make a post declaring it complete. Feedback posted to 
 this thread after that point may be ignored.
Thanks to everyone who provided feedback!
Sep 23 2020