January 29, 2021
On Friday, 29 January 2021 at 12:41:35 UTC, Paul Backus wrote:
> You cannot actually pass an i"..." literal directly to `mixin` with this proposal; you have to call `idup` (or some other function) to convert it to a string first.

Why? I understood it like this: `mixin(i"foreach(i;0..${iterations}) foo();")` is first attempted as `mixin(Interp!"foreach(i;0.."(), iterations, Interp!") foo()"());`. Since `mixin` accepts only strings, `idup` is implicitly called on the arguments.

What went wrong?
January 29, 2021
On Friday, 29 January 2021 at 13:03:45 UTC, Dukc wrote:
> On Friday, 29 January 2021 at 12:41:35 UTC, Paul Backus wrote:
>> You cannot actually pass an i"..." literal directly to `mixin` with this proposal; you have to call `idup` (or some other function) to convert it to a string first.
>
> Why? I understood it like this: `mixin(i"foreach(i;0..${iterations}) foo();")` is first attempted as `mixin(Interp!"foreach(i;0.."(), iterations, Interp!") foo()"());`. Since `mixin` accepts only strings, `idup` is implicitly called on the arguments.
>
> What went wrong?

mixin does not only accept strings:

    int n = mixin(1);
    assert(n == 1);

From the language spec [1]:

> Each AssignExpression in the ArgumentList is evaluated at compile
> time, and the result must be representable as a string.

In concrete terms, what happens is that mixin implicitly calls `.stringof` on each of its arguments. So your mixin example would be lowered to

    mixin(interp!"foreach(i;0.."().stringof, iterations.stringof, interp!") foo();"().stringof);

And evaluating the `.stringof` calls would result in

    // assuming iterations == 5
    mixin(`interp()`, `5`, `interp()`);

...which in this specific case happens to be a compile error, so it actually *would* be rewritten by the compiler to use `idup`. But there is no guarantee that will happen in general.

[1] https://dlang.org/spec/expression.html#mixin_expressions
January 29, 2021
On Friday, 29 January 2021 at 13:21:18 UTC, Paul Backus wrote:
> In concrete terms, what happens is that mixin implicitly calls `.stringof` on each of its arguments. So your mixin example would be lowered to
>
>     mixin(interp!"foreach(i;0.."().stringof, iterations.stringof, interp!") foo();"().stringof);
>
> And evaluating the `.stringof` calls would result in
>
>     // assuming iterations == 5
>     mixin(`interp()`, `5`, `interp()`);

Oops. I quess the DIP would do well to solve that somehow.

>
> ...which in this specific case happens to be a compile error, so it actually *would* be rewritten by the compiler to use `idup`..

Or perhaps not, since the compiler error would not result from arguments not being accepted.



January 29, 2021
On Friday, 29 January 2021 at 14:17:41 UTC, Dukc wrote:
> On Friday, 29 January 2021 at 13:21:18 UTC, Paul Backus wrote:
>> In concrete terms, what happens is that mixin implicitly calls `.stringof` on each of its arguments. So your mixin example would be lowered to
>>
>>     mixin(interp!"foreach(i;0.."().stringof, iterations.stringof, interp!") foo();"().stringof);
>>
>> And evaluating the `.stringof` calls would result in
>>
>>     // assuming iterations == 5
>>     mixin(`interp()`, `5`, `interp()`);
>
> Oops. I quess the DIP would do well to solve that somehow.
>
>>
>> ...which in this specific case happens to be a compile error, so it actually *would* be rewritten by the compiler to use `idup`..
>
> Or perhaps not, since the compiler error would not result from arguments not being accepted.

...unless you happen to have something else named `interp` in scope that makes the `.stringof` results compile. Have fun chasing down *that* bug. :)
January 29, 2021
On Friday, 29 January 2021 at 14:21:39 UTC, Paul Backus wrote:
> ...unless you happen to have something else named `interp` in scope that makes the `.stringof` results compile. Have fun chasing down *that* bug. :)

What are you talking about?

this DIP is pretty explicit about where interp lives.
January 29, 2021
On Friday, 29 January 2021 at 14:30:03 UTC, Adam D. Ruppe wrote:
> On Friday, 29 January 2021 at 14:21:39 UTC, Paul Backus wrote:
>> ...unless you happen to have something else named `interp` in scope that makes the `.stringof` results compile. Have fun chasing down *that* bug. :)
>
> What are you talking about?
>
> this DIP is pretty explicit about where interp lives.

But you could define your own to the same module where the mixin lives. In that case, it would get called by the mixin, not `object.interp`.
January 29, 2021
On 1/29/21 3:02 AM, Walter Bright wrote:
> Comparing two simple examples of #DIP1036 and #DIP1027:
> 
> DIP1036:
>    printf(i"%s${item} %02d${other_item}"); // metaprogramming + printf overload

With a metaprogramming wrapper, it would be:

printf(i"${item} %02d${other_item}");

Without a metaprogramming wrapper, you call it like this:

printf("%s %02d", item, other_item); // yes, just use printf the way it was intended

The point of this is, we don't want to fit into printf-style formatting, because it's too niche a need, and extremely limiting. Use the wrapper if you want printf formatting. This is not a burden on anyone (the wrapper took me 15 minutes to write, and is an inlineable no-processing call).

> 
> DIP2027:
>    printf(i"$item ${%02d}other_item");  // direct

This is an error, unless item is a const char * (unlikely).

> DIP1036:
>    writeln(i"I ate ${apples} apples and ${bananas} bananas totaling ${apples + bananas} fruit.");
> 
> DIP1027:
>    writefln(i"I ate $apples apples and $bananas bananas totaling $(apples + bananas) fruit.");
> 
> 
> DIP1036 is more user typing, including awkward-to-type { }, along with needing substantial user code to implement (for printf).

It is possible for the DIP to allow omission of the {}. We did not do this for several reasons:

1. Just a literal $ is frequently used in string data (it is a denomination, and has valid uses in mixin D code).
2. The requirement to type {} is not much of a burden.
3. Using enclosing tokens has precedent in many string interpolation implementations. Javascript uses this exact sequence. Swift uses \( ... ). C# uses { ... }.
4. It's easier for a person to distinguish in a large string.

> 
> DIP1027's syntax is optimized to make the most common cases the simplest for the user, no user code is required.

DIP1027's syntax is designed to fit with a few existing functions. It puts the burden on the user to make sure they understand how the rewrite will happen, and which functions to use to do this. It is not forgiving of mistakes, which will compile and do the wrong thing.

But I don't want to rehash DIP1027 here, that discussion has already happened. If you want to compare the two briefly, I would say DIP1027 designed for writef and format, nothing else. It can be used unintuitively with printf and other functions that have some similar parameter layouts. It can be used accidentally with many functions that happen to accept the parameters as arranged. DIP1036 is designed to be used by library writers to provide a mechanism to distinguish and handle properly interpolation strings ONLY when intended, and do it with little effort, all while also providing the user a mechanism to seamlessly convert normal data into string data.

-Steve
January 29, 2021
On Friday, 29 January 2021 at 15:06:20 UTC, Steven Schveighoffer wrote:
> On 1/29/21 3:02 AM, Walter Bright wrote:
>> [...]
>
> With a metaprogramming wrapper, it would be:
>
> printf(i"${item} %02d${other_item}");
>
> [...]

+1

I've been using {} in C# for years and it's no effort.
January 29, 2021
On 1/29/21 6:14 AM, Walter Bright wrote:
> On 1/29/2021 2:53 AM, Arafel wrote:
>> Of course one could settle on a default placeholder and then reparse the string to adapt it as needed, that's in fact what JDBC does, but... here we have the chance to do the right thing from the beginning.
> 
> I bet it could be done with a template overload of the function call. This doesn't make it worse than DIP1036, which requires template overloads written by the user anyway.

No it cannot (for DIP1027). Because the function that accepts a string format already exists. This was my main complaint of 1027 and why we wrote a new DIP.

-Steve
January 29, 2021
On Friday, 29 January 2021 at 04:21:24 UTC, Walter Bright wrote:
> On 1/28/2021 12:34 PM, 12345swordy wrote:
>> That being said. Would it be easier to convince you to accept this if there is a prototype version of this?
>
> Prototype of a way to call printf, or prototype of the DIP?

Prototype of the dip.

-Alex