February 03, 2020
On Monday, 3 February 2020 at 14:52:24 UTC, Adam D. Ruppe wrote:
> On Monday, 3 February 2020 at 14:37:22 UTC, Steven Schveighoffer wrote:
>> 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)
>
> Yes, that would be excellent. If you make a motion to amend the DIP, I'll withdraw my motion and second yours. Let's form a coalition and get Walter onboard!

This looks really good. When using it as a DSL, there is no need to parse the '%s' the compiler just inserted.

Plus it is a bit more structured than the bare tuple there was before.

Best of both worlds, I would say.
February 03, 2020
On Mon, Feb 03, 2020 at 07:10:54PM +0000, Sebastiaan Koppe via Digitalmars-d wrote:
> On Monday, 3 February 2020 at 14:52:24 UTC, Adam D. Ruppe wrote:
> > On Monday, 3 February 2020 at 14:37:22 UTC, Steven Schveighoffer wrote:
> > > 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)
> > 
> > Yes, that would be excellent. If you make a motion to amend the DIP, I'll withdraw my motion and second yours. Let's form a coalition and get Walter onboard!
> 
> This looks really good. When using it as a DSL, there is no need to parse the '%s' the compiler just inserted.
> 
> Plus it is a bit more structured than the bare tuple there was before.
> 
> Best of both worlds, I would say.

+1, this proposal trumps all the other ones I've seen so far.


T

-- 
Let X be the set not defined by this sentence...
February 04, 2020
In current DIP I found a thing called IdentifierExpression. I searched both discussion threads and D documentations, founded no result regarding what it is (if I didn't miss something).

Is it the same thing as C++ id-expression? Will there be any differences between the following versions of interpolation strings?

    string someString = "abc";

    auto versionA = i"$someString";
    auto versionB = i"$(someString)";

February 04, 2020
On Thursday, 30 January 2020 at 09:46:38 UTC, Mike Parker wrote:
> This is the discussion thread for the Final Review of DIP 1027, "String Interpolation":
>
> https://github.com/dlang/DIPs/blob/d8f2e769c3a8c711e7886ccecc93eac9795dae9c/DIPs/DIP1027.md
>
> This is the first review in which we are operating under the new procedure of using separate threads for discussion and feedback. Please see my blog post on the topic:
>
> https://dlang.org/blog/2020/01/26/dip-reviews-discussion-vs-feedback/
>
> Here in the discussion thread, you are free to discuss anything and everything related to the DIP. Express your support or opposition, debate alternatives, argue the merits... in other words, business as usual.
>
> However, if you have any specific feedback for how to improve the the proposal itself, then please post it in the feedback thread. The feedback thread will be the source for the review summary I write at the end of this review round. I will post a link to that thread immediately following this post. Just be sure to read and understand the Reviewer Guidelines before posting there:
>
> https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md
>
> The review period will end at 11:59 PM ET on February 13, or when I make a post declaring it complete. Discussion in this thread may continue beyond that point.
>
> Please stay on topic here. I will delete posts that are completely off topic.


The main issue I have with this DIP is that it performs one too many steps:

Interpolated String > Strings and Expressions > Format String

Some applications want the "Strings and Expressions" form rather than the "Format String" form.  For example, my alterative D standard library that doesn't depend on libc https://github.com/dragon-lang/mar doesn't use format strings at all and I'd like to be able to use interpolated strings with it.  This means that I'm going to need to reverse the last step to turn the resulting "Format String" back into a tuple of "Strings and Expressions".  The problem is that it's easy to create a "Format String" from a tuple, but hard to reverse it, and by the time the compiler has performed this roundtrip conversion, compile times will start to suffer.

I recall Andrei Alexandrescu talking about the importance of "composability" when referring to his memory allocation library.  It's better to have many small components that perform one job that you can piece together, rather than a small number of big components that perform many jobs.  In the latter case, you end up with complex interfaces and duplicate functionality scattered throughout.  Interpolated Strings will be more powerful and flexible if we leave them in a "less processed form", where they can easily be used for more than string formatting functions.

February 03, 2020
On 2/3/2020 5:06 PM, Jonathan Marler wrote:
> Some applications want the "Strings and Expressions" form rather than the "Format String" form.

To have "strings and expressions" then write it that way:

    foo("I want ", i, " bananas");
February 04, 2020
On 2/3/20 10:17 AM, Steven Schveighoffer wrote:
> On 2/3/20 9:52 AM, Adam D. Ruppe wrote:
>> On Monday, 3 February 2020 at 14:37:22 UTC, Steven Schveighoffer wrote:
>>> 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)
>>
>> Yes, that would be excellent. If you make a motion to amend the DIP, I'll withdraw my motion and second yours. Let's form a coalition and get Walter onboard!
> 
> I hope this can work, but I feel Walter might not be on board due to past comments from him. This is why I feel we can wait and get string interpolation in, and then later add this.
> 
> But I'll throw the idea out there, and see what he says.

As I expected, this was rejected, and Walter didn't understand what I was saying, says we shouldn't bake % into the format specification (it doesn't), and that it's like AST macros (it's not). Since there's no arguing on the feedback thread, I didn't want to push it.

-Steve
February 04, 2020
On Tuesday, 4 February 2020 at 12:47:28 UTC, Steven Schveighoffer wrote:
> As I expected, this was rejected, and Walter didn't understand what I was saying, says we shouldn't bake % into the format specification (it doesn't)

Yeah, this change actually lives up the DIP's own rationale while making advanced uses doable.

Walter is wrong. We all need to stand united for these enhancements and not back down.
February 04, 2020
On Tuesday, 4 February 2020 at 12:47:28 UTC, Steven Schveighoffer wrote:
> [snip]
>
> As I expected, this was rejected, and Walter didn't understand what I was saying, says we shouldn't bake % into the format specification (it doesn't), and that it's like AST macros (it's not). Since there's no arguing on the feedback thread, I didn't want to push it.
>
> -Steve

Several people seem to think it is an important proposal, so I wouldn't want you to get discouraged. However, when you say "Walter didn't understand what I was saying", another way to look at it is "I didn't communicate this well enough to convince Walter".
February 05, 2020
On 05/02/2020 2:44 AM, jmh530 wrote:
> On Tuesday, 4 February 2020 at 12:47:28 UTC, Steven Schveighoffer wrote:
>> [snip]
>>
>> As I expected, this was rejected, and Walter didn't understand what I was saying, says we shouldn't bake % into the format specification (it doesn't), and that it's like AST macros (it's not). Since there's no arguing on the feedback thread, I didn't want to push it.
>>
>> -Steve
> 
> Several people seem to think it is an important proposal, so I wouldn't want you to get discouraged. However, when you say "Walter didn't understand what I was saying", another way to look at it is "I didn't communicate this well enough to convince Walter".

We talked about this on IRC, our way of looking at it seems to have been that we expected Walter to ask questions instead of dismissing a potentially important suggestion.

For the record, I do agree that it has potential to significantly improve the DIP and its use cases.
February 04, 2020
Due to the silly rules, I have to correct Walter's errors in this thread instead.

On Tuesday, 4 February 2020 at 05:41:34 UTC, Walter Bright wrote:
> On 2/3/2020 7:48 AM, Steven Schveighoffer wrote:
>>
>> The rationale for this change is twofold:
>
> No rationale is given why this needs to be supported at all.

I suggest you read the post again.

Moreover, consider this use case. We have an existing function

Result query(T...)(string q, T args) {}

The format of the `string q` here is to use `?n` to refer to `args[n-1]`.

    query("X > ?1", x);

A user wants to try the new interpolated string on it. They try:

    query(i"X > $x");

It compiles! Then it launches nuclear missiles and self-destructs the computer. Turns out %s was the special code to `query` to indicate universal armageddon.

(ok it'd probably just throw a syntax error exception BUT THERE IS NO WAY TO TELL.)

I know what you're going to say. "the user needs to be aware of the string format". Well, there's no type system check so I *guarantee* you this is going to be a common problem. With a new type as an overload target, library authors can do something about it. Without it, well, I guess it means i'll get more irc posts and stack overflow points answering confused user's questions.

But let's assume they do know. Do they have to consistently write:

    query(i"X > ${?1}(x)");

Of course, by this point the new feature has lost its appeal. You've made the wrong thing easy and the right thing hard. D, at its best, does the opposite.


Or consider this:

   Window createWindow(string title, int width = 0, int height = 0) {}

and the user writes

   createWindow(i"Window for $user_id on $pid")

it compiles... but throws an invalid argument exception (or creates a randomly sized window). Weird. (the addendum would still allow this by default, which I think is a mistake, but am compromising for your desired for compatibility with printf. But at least with the addendum, it becomes possible to for the library author to add `Window createWindow(T...)(InterpolatedFormat fmt, T args) { static assert(0, "sorry i didnt implement interpolation here try doing .format on your string instead");`

D has a type system for a reason. If anything, using it should be the default position and bypassing it requires special rationale!

So: why are you opposed to using it?

> Note that the user can always write:
>
>   writefln(i" ... $a ... ");
>   writefln(i" ... $b ... ");

That does not do the same thing as `writefln(i" ... $a ... ", i" ... $b ... ")`.

But even if it did, what about nesting? What happens if someone tries

i"$(i"$foo") $bar"

what happens? Under the current dip rules:

    ("%s %s", "%s", foo, bar)

and you can't use that. It is impossible to tell where it was nested. (If you say "well, don't do that", I'd note the DIP makes no mention of it and does not prohibit it. So again, are we relying on user's voluntarily following best practices?)

Of course, even with this addendum, printf wouldn't detect it. But just because not ALL errors will be detected doesn't mean we shouldn't detect MANY errors.


> The user can write writefln(i"$percentage%% complete") as required.

Again, relying on users to consistently do something (except when calling functions that do it differently!) with no help from compile errors / library design.

> Baking % into the specification with special escapes completely weds it to printf/writef formatting, which is carefully avoided (at your request!).

The current DIP bakes % into the specification. The addendum moves this to the library for both increased flexibility AND increased detection of user errors (without losing the DIP's (minimal) printf compatibility, at your request!)


> It's having the language semantics defined by a hidden template

This is just creating a type. Programs do this all the time.

foo("a") does something different than foo(1). foo("a"w) does something different than foo("a"). These are because they are all different types and foo is allowed to overload on the types of its parameters.

And guess what? With the DIP as-is, foo(i"$a") does something different than foo(i"$b"). They construct different types already!

All we're asking is that the format string itself also gets a new type for reliable detection in code. You need to justify why this is bad.

> (which happens nowhere else in D).
> [snip]
> The D compiler does such "lowering" to simpler forms in many places already.

lol