April 19, 2017
On Wednesday, 19 April 2017 at 11:59:51 UTC, Jonas Drewsen wrote:

> What about supporting an optional prefix inside the {} like:
>
> int year = 2017;
> format($"The date is {%04d year}");
>
> so if there is a % immediately following the { then the chars until next whitespace is format specifier. You can of course leave out the format specifier and it will default to %s.
I really don't see how string interpolation is better then
` "The date is " ~ format("%04d", year)); `

April 19, 2017
On Tuesday, 18 April 2017 at 08:42:38 UTC, Walter Bright wrote:
> On 4/15/2017 1:04 PM, Jonas Drewsen wrote:
>>[...]
>
> Thanks for doing the work to make a sample implementation, too. I don't know if this will make it into D, but Jonas is a fine example of a champion.

Thanks for the feedback. Nice to know that it is not immediately off the table at least :)

April 19, 2017
On Wednesday, 19 April 2017 at 12:03:47 UTC, Stefan Koch wrote:
> On Wednesday, 19 April 2017 at 11:59:51 UTC, Jonas Drewsen wrote:
>
>> What about supporting an optional prefix inside the {} like:
>>
>> int year = 2017;
>> format($"The date is {%04d year}");
>>
>> so if there is a % immediately following the { then the chars until next whitespace is format specifier. You can of course leave out the format specifier and it will default to %s.
> I really don't see how string interpolation is better then
> ` "The date is " ~ format("%04d", year)); `

As mentioned before it is only because it is such a common pattern that it justifies the change. Seems like many other languages reached that conclusion as well.
Also take a look at a more realistic example with some more formatting and it will be more obvious (at least to me it is :) )

"The date is " ~ format("%04d", year)) ~ " and " ~ user ~ " just logged into " ~ here;

$"The date is {%04d year} and {user} just logged into {here}"




April 19, 2017
On Wednesday, 19 April 2017 at 12:03:47 UTC, Stefan Koch wrote:
> On Wednesday, 19 April 2017 at 11:59:51 UTC, Jonas Drewsen wrote:
>
>> What about supporting an optional prefix inside the {} like:
>>
>> int year = 2017;
>> format($"The date is {%04d year}");
>>
>> so if there is a % immediately following the { then the chars until next whitespace is format specifier. You can of course leave out the format specifier and it will default to %s.
> I really don't see how string interpolation is better then
> ` "The date is " ~ format("%04d", year)); `

I can think of 3 reasons.

1. Requires GC.

NOTE: I believe that most applcations should use GC memory, that being said, library code has to be nogc wherever it can if it wants to be used by nogc apps, so this solution is unusable in alot of library code.

2. It's verbose.  Jonas provided a good example of why and he makes a good point that your example only has 1 formatted argument and this problem gets much worse with multiple.

3. The biggest reason I wouldn't use this solution because it uses string composition.  String composition wastes memory and memory management cycles.  And when I say "waste" what I mean is, the use is unnecessary.  In general composition is a powerful tool because it allows you to easily overload and abstract and add new functionality, however, it requires runtime overhead.  This is the reason that the toString(delegate) was created to replace the composable toString paradigm.  It's also the reason that string formatting exists at all.

To summarize:

// requires GC, too verbose, uses string composition which wastes heap resources
writeln("The date is " ~ format("%04d", year));

// efficient, but format string and args can get out of sync.
writefln("the date is %04d", year);

//
writefln($"the date is {year:04d}");

If string interpolation gets reduced to the 2nd case, then it will have the same efficiency and solve a problem.  Whether that problem justifies the change is up for debate, but I think it *might be*.


April 19, 2017
On Wednesday, 19 April 2017 at 12:10:33 UTC, Jonas Drewsen wrote:
> On Wednesday, 19 April 2017 at 12:03:47 UTC, Stefan Koch wrote:
>> On Wednesday, 19 April 2017 at 11:59:51 UTC, Jonas Drewsen wrote:
>>
>>> What about supporting an optional prefix inside the {} like:
>>>
>>> int year = 2017;
>>> format($"The date is {%04d year}");
>>>
>>> so if there is a % immediately following the { then the chars until next whitespace is format specifier. You can of course leave out the format specifier and it will default to %s.
>> I really don't see how string interpolation is better then
>> ` "The date is " ~ format("%04d", year)); `
>
> As mentioned before it is only because it is such a common pattern that it justifies the change. Seems like many other languages reached that conclusion as well.
> Also take a look at a more realistic example with some more formatting and it will be more obvious (at least to me it is :) )
>
> "The date is " ~ format("%04d", year)) ~ " and " ~ user ~ " just logged into " ~ here;
>
> $"The date is {%04d year} and {user} just logged into {here}"

I see.
So you want to build format strings as well.
This is going to be nasty, and likely to complex for a robust implementation.
Here is what I would support:

String interpolation literals can only be used with strings.
And they need to start with some prefix which is not an operator.

I"The date is %dateString and the time is %timeString"
April 19, 2017
On Wednesday, 19 April 2017 at 12:03:47 UTC, Stefan Koch wrote:
> I really don't see how string interpolation is better then
> ` "The date is " ~ format("%04d", year)); `

That code is hideous, not hard to beat on every level... inefficient, hard to read.

The built in thing could potentially optimize it a little too - maybe have it be syntax sugar over a range.
April 19, 2017
On Wednesday, 19 April 2017 at 14:02:43 UTC, Stefan Koch wrote:
> On Wednesday, 19 April 2017 at 12:10:33 UTC, Jonas Drewsen wrote:
>> On Wednesday, 19 April 2017 at 12:03:47 UTC, Stefan Koch wrote:
>>> On Wednesday, 19 April 2017 at 11:59:51 UTC, Jonas Drewsen wrote:
>>>
>>>> What about supporting an optional prefix inside the {} like:
>>>>
>>>> int year = 2017;
>>>> format($"The date is {%04d year}");
>>>>
>>>> so if there is a % immediately following the { then the chars until next whitespace is format specifier. You can of course leave out the format specifier and it will default to %s.
>>> I really don't see how string interpolation is better then
>>> ` "The date is " ~ format("%04d", year)); `
>>
>> As mentioned before it is only because it is such a common pattern that it justifies the change. Seems like many other languages reached that conclusion as well.
>> Also take a look at a more realistic example with some more formatting and it will be more obvious (at least to me it is :) )
>>
>> "The date is " ~ format("%04d", year)) ~ " and " ~ user ~ " just logged into " ~ here;
>>
>> $"The date is {%04d year} and {user} just logged into {here}"
>
> I see.
> So you want to build format strings as well.
> This is going to be nasty, and likely to complex for a robust implementation.
> Here is what I would support:
>
> String interpolation literals can only be used with strings.
> And they need to start with some prefix which is not an operator.
>
> I"The date is %dateString and the time is %timeString"

I'm talking about building format strings just yet... I'm just working with the suggestion that Walter brought up with converting the interpolated string into something that can be fed into format e.g.:

$"The date is {%04d year} and {user} just logged into {here}"

is rewritten by the compiler to:

"The date is %04d and %s just logged into %s", year, user, here

which can be fed into for example format(). Not sure I like the need to call format to get the resulting string, but just working with the idea here.

I also think it would loose a lot of value to only allow strings as you suggest (e.g. %dateString).














April 19, 2017
On Wednesday, 19 April 2017 at 09:49:16 UTC, Jacob Carlborg wrote:
> On 2017-04-19 08:51, Ola Fosheim Grøstad wrote:
>
>> If you want AST-macros in D you should also argue for redefining the
>> core language, and turn everything that is unnecessary and that can be
>> done as lowering into macros (e.g. "for each").
>
> If D had AST macros from the beginning, then yes, "foreach" could have been implemented as a macro.

Yup. And actually also "while" and "for". More minimal languages just have: block, conditional and jump-to-start-of-block.



April 19, 2017
On Wednesday, 19 April 2017 at 16:19:09 UTC, Ola Fosheim Grøstad wrote:
>
> Yup. And actually also "while" and "for". More minimal languages just have: block, conditional and jump-to-start-of-block.

This reminds me of Rust's mid-level IR for some reason. For instance, according to one of the Rust blog posts goto completely replaces loop, break, and continue.

Does it make sense to think of MIR as AST macros that only the compiler has access to?
April 19, 2017
On 04/17/2017 03:41 PM, Jonas Drewsen wrote:
> On Monday, 17 April 2017 at 19:12:37 UTC, Martin Tschierschke wrote:
>> defining a new method exho! (derived from echo + mixin...:-)
>>
>>   auto exho(string x)(){
>>      return mixin("writeln("~interp!x~")");}
>>
>> You can just write:
>>
>>    exho!"The number ${num} doubled is ${num * 2}!"
>
> It requires 'num' to be available to the exho function definition so
> will not
> work in the general case.

Also, it only works if you're just sending the string to writeln. It doesn't help the general case :(