October 18, 2023
On Wednesday, 18 October 2023 at 00:45:40 UTC, Adam D Ruppe wrote:
> The text of the yaidip doesn't specify this

Actually, looking again, it states:

"Every i-string lowering introduces a header rvalue object that so far we conventionally denoted as __header (the exact name is uniquely compiler-generated and hence inaccessible)."

so this may not matter anyway, nevertheless, I  just did the 30 second find+replace of the abbreviated name with the fully qualified name to concretely specify this. Refresh the page.
October 17, 2023
On 10/17/2023 5:45 PM, Adam D Ruppe wrote:
> On Wednesday, 18 October 2023 at 00:27:16 UTC, Walter Bright wrote:
>> Neither would YAIDIP. write() takes a variadic argument list.
> 
> Which is irrelevant because it *works correctly* when passed to write(), so there's no need for the compiler to say anything.

I don't see how, from my reading of the proposal.

It doesn't matter that much if write() does not give a compile time error, as this is normal and accepted for variadic functions. But as you've characterized it as a fatal error, the YAIDIP spec should be improved to address it.



>> YAIDIP also requires the correct version of user-defined InterpolationHeader to be the one in scope.
> 
> The text of the yaidip doesn't specify this, but this is utterly trivial to solve; the dip 1036 specified a fully qualified name for it and this one could too.

If it's trivial, then please fix the proposal.

BTW, it's normal to uncover errors like this in a proposal for a new feature.

October 17, 2023
On 10/17/2023 6:07 PM, Adam D Ruppe wrote:
> On Wednesday, 18 October 2023 at 00:45:40 UTC, Adam D Ruppe wrote:
>> The text of the yaidip doesn't specify this
> 
> Actually, looking again, it states:
> 
> "Every i-string lowering introduces a header rvalue object that so far we conventionally denoted as __header (the exact name is uniquely compiler-generated and hence inaccessible)."
> 
> so this may not matter anyway, nevertheless, I  just did the 30 second find+replace of the abbreviated name with the fully qualified name to concretely specify this. Refresh the page.

How does the user specify the fully-qualified name of a compiler generated object?
October 18, 2023
On Wednesday, 18 October 2023 at 02:19:21 UTC, Walter Bright wrote:
> I don't see how, from my reading of the proposal.

The first example under the Description shows this exact situation and then goes on to explain how and why it works as expected.

> But as you've characterized it as a fatal error, the YAIDIP spec should be improved to address it.

It is a fatal error for YOUR (rejected) dip 1027, as it silently leads to wrong results in common cases. This was all explained in detail in the review process four years ago.

Things work correctly with this proposal, you either get the expected results or a compiler error, as a natural consequence of the existing type system. Nothing needs to be spelled out about this as there are not any special cases.

> If it's trivial, then please fix the proposal.

Already did, over an hour ago. It took about 30 seconds to specify. This isn't a big deal. (And btw, even if it didn't specify, the behavior is well-defined in the D Programming Language, and such things are already similar in other places, including other existing compiler hooks, see _d_cmain <http://dpldocs.info/this-week-in-d/Blog.Posted_2022_07_18.html>.

But now the text does specify the fully qualified name anyway, so this is all moot.
October 17, 2023
On 10/17/2023 7:39 PM, Adam D Ruppe wrote:
> On Wednesday, 18 October 2023 at 02:19:21 UTC, Walter Bright wrote:
>> I don't see how, from my reading of the proposal.
> 
> The first example under the Description shows this exact situation and then goes on to explain how and why it works as expected.

The line in question:

```
writeln(__header, "I ate ", apples, " apples and ", bananas, " bananas totalling ", apples + bananas, " fruit.")
```

What does writeln() do with __header?


> Things work correctly with this proposal, you either get the expected results or a compiler error, as a natural consequence of the existing type system. Nothing needs to be spelled out about this as there are not any special cases.

Does that mean writeln() gets rewritten to handle __header? If so, ok, but the YAIDIP doesn't say that.

Today, the only difference between writef() and write() is the former takes the first argument as the format string. Is this a fatal error? I suppose you could consider it as one, but that's an issue typical with variadic functions.


> Already did, over an hour ago.

Ok, I saw it after I posted that.

> It took about 30 seconds to specify. This isn't a big deal. (And btw, even if it didn't specify, the behavior is well-defined in the D Programming Language, and such things are already similar in other places, including other existing compiler hooks, see _d_cmain <http://dpldocs.info/this-week-in-d/Blog.Posted_2022_07_18.html>.
> 
> But now the text does specify the fully qualified name anyway, so this is all moot.

I think we're misunderstanding each other. What I am asking about is how does the user specify his own custom implementation of InterpolatedExpression?

October 18, 2023

On Thursday, 12 October 2023 at 13:39:46 UTC, Andrea Fontana wrote:

>

Real life example. Render a string like this:

\x1b[2K\r\x1b[1mProgress:\x1b[0m 50% \x1b[1m\tSpeed:\x1b[0m 15.5 KB/s

now (error prone and difficult to debug, try to code it!):

stderr.write(format("%s\r%sProgress:%s %5.1f%% %s\tSpeed:%s %6.1f %s%s", clear, white, clear, progress, white, clear, curSpeed, unit));

(or with string concat, good luck!)

vs:

stderr.write("${clear}\r{$white}Progress:${clear}${progress}% \t${white}Speed:${clear} ${curSpeed} ${unit}");

Andrea

Just a quick comment. Probably with string interpolation, less is more.

So the simplest DIP probably wins.

❤️

October 18, 2023
I decided to have a go and do my own little proposal. Its a pretty big mesh of things, with one key difference, the notion of a binary-less expression. This simplifies the grammar quite a bit and should do the same for the implementation.

https://gist.github.com/rikkimax/90a4b21feabcf34dbecb8efcb587f8e1

```d
stderr.write("$clear\r${white}Progress:$clear$progress% \t${white}Speed:$clear $curSpeed $unit");
```

It should be familiar to both C++ and Python folk.

I've already implemented a formatter read/write for ``{:}`` syntax so I might be a tad biased, especially since I want to use ``$Identifier`` for something (not that it conflicts here).
October 18, 2023
On Wednesday, 18 October 2023 at 03:57:52 UTC, Walter Bright wrote:
> The line in question:
>
> ```
> writeln(__header, "I ate ", apples, " apples and ", bananas, " bananas totalling ", apples + bananas, " fruit.")
> ```
>
> What does writeln() do with __header?

__header is implicitly converted to null string by writeln (the struct will have a toString method that returns null), so from the point of view of existing text methods such as writeln, text, everything is fine.

> Does that mean writeln() gets rewritten to handle __header? If so, ok, but the YAIDIP doesn't say that.
>
> Today, the only difference between writef() and write() is the former takes the first argument as the format string. Is this a fatal error? I suppose you could consider it as one, but that's an issue typical with variadic functions.
It's a pain to parse it (DIP 1027) when you'd like to define your own function accepting interpolated strings, compared to suggested DIP.

>> Already did, over an hour ago.
>
> Ok, I saw it after I posted that.
>
>> It took about 30 seconds to specify. This isn't a big deal.
> I think we're misunderstanding each other. What I am asking about is how does the user specify his own custom implementation of InterpolatedExpression?

I think the assumption is that __header type is passed as template argument, then there are no issues with voldemort types. If you really like to specify type not through template argument, I guess DIP could be enhanced saying that __header could implicitly convert to a predefined struct, i.e. RuntimeStoredInterpolationInfo.

Best regards,
Alexandru.


October 18, 2023
On Wednesday, 18 October 2023 at 03:57:52 UTC, Walter Bright wrote:
> What does writeln() do with __header?

"The __header value, to be discussed later, is generated by the compiler and contains compile-time information about the interpolated string."

<a few moments later>

"The header object has a trivial toString method that expands to the null string. This method makes it possible to pass interpolated strings directly to functions such as writeln and text because these functions detect and use toString to convert unknown data types to strings."

It just uses the existing rules for a struct. No special case here. It doesn't spell this out, but you can think about what happens to normal D functions if you pass some `struct` to a function expecting a `string` - an ordinary type mismatch error. This is what gives library authors such power with this proposal: they can overload a function to provided specialized behavior.

Which brings me to:

> I think we're misunderstanding each other. What I am asking about is how does the user specify his own custom implementation of InterpolatedExpression?

There's no need. You just pass it to a function.

Library authors overload functions on the type of what was passed, including an interpolated type if desired, same as any other overload. End users call a particular function uses the given arguments to create their desired result; a generic function forwarder still works, preserving the full interpolated argument, since it works like any other set of function arguments.

This gives *enormous* capability to both sides - mostly by using already existing features in the D language.
October 18, 2023
On Tuesday, 17 October 2023 at 20:05:59 UTC, Walter Bright wrote:
> On 10/17/2023 12:20 PM, Adam D Ruppe wrote:
>> And read the post above, which uses *write*, not write*f*. Think about the implications of that for a second.
>
> Yes, it means I forgot to use writef instead of write.

The DIP linked by Adam is very appealing to me. All the modern programming languages I frequently use have some form of string interpolation, and when I write code in D, I miss it. I genuinely don't understand the opposition to such a highly desired feature that can only enhance code readability.

I am less fond of the proposal related to printf/writef/writelnf/format/sformat, etc. It appears to add complexity to the code, introduces unnecessary noise, and is prone to errors.

Andrea