www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Interpolated strings

reply Jonas Drewsen <nospam4321 hotmail.com> writes:
Hi all

   I've been wanting to have support for interpolated strings in D 
for some time now that will allow you to write e.g.:

auto a = 7;
writeln( $"{a} times 3 is {a*3}" );

Code speaks louder that words so I've made a PR that adds this 
support to ddmd as a RFC [1].

The compiler will basically lower the $"..." string to a mixin 
that concatenates
the expression parts of the (inside the {}) and the plain text 
parts.

I do recognize that this is not part of the 2017 H1 plan but I 
also believe such smaller improvements added regularly can make 
the language both more productive and attractive.

In case this addition gets a thumbs up I will of course improve 
test coverage and any needed quality of implementation.

[1] https://github.com/dlang/dmd/pull/6703
Apr 15
next sibling parent reply cym13 <cpicard openmailbox.org> writes:
On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen wrote:
 Hi all

   I've been wanting to have support for interpolated strings in 
 D for some time now that will allow you to write e.g.:

 auto a = 7;
 writeln( $"{a} times 3 is {a*3}" );

 Code speaks louder that words so I've made a PR that adds this 
 support to ddmd as a RFC [1].

 The compiler will basically lower the $"..." string to a mixin 
 that concatenates
 the expression parts of the (inside the {}) and the plain text 
 parts.

 I do recognize that this is not part of the 2017 H1 plan but I 
 also believe such smaller improvements added regularly can make 
 the language both more productive and attractive.

 In case this addition gets a thumbs up I will of course improve 
 test coverage and any needed quality of implementation.

 [1] https://github.com/dlang/dmd/pull/6703
This has been proposed before, and I still don't see the added value compared to: auto a=7; writeln(a, " times 3 is ", a*3); besides adding compiler complexity, language complexity and parsing complexity which leaves room for more bugs to be invented. I'm a bit more harsh than I could be, but if this simple question has no clear answer I don't see why it sould make it into the language.
Apr 15
parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Saturday, 15 April 2017 at 20:12:41 UTC, cym13 wrote:
 On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen wrote:
 This has been proposed before, and I still don't see the added 
 value compared to:

     auto a=7;
     writeln(a, " times 3 is ", a*3);

 besides adding compiler complexity, language complexity and 
 parsing complexity which leaves room for more bugs to be 
 invented. I'm a bit more harsh than I could be, but if this 
 simple question has no clear answer I don't see why it sould 
 make it into the language.
Try a different context: auto a = 7; import std.format; auto str = format("%s times 3 is %s", a, a*3); //or import std.conv; auto str = text(a, " times 3 is ", a*3); //or auto str = $"{a} times 3 is {a*3}";
Apr 15
next sibling parent reply Jonas Drewsen <nospam4321 hotmail.com> writes:
On Saturday, 15 April 2017 at 20:20:49 UTC, Stanislav Blinov 
wrote:
 On Saturday, 15 April 2017 at 20:12:41 UTC, cym13 wrote:
 On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen 
 wrote:
 This has been proposed before, and I still don't see the added 
 value compared to:

     auto a=7;
     writeln(a, " times 3 is ", a*3);

 besides adding compiler complexity, language complexity and 
 parsing complexity which leaves room for more bugs to be 
 invented. I'm a bit more harsh than I could be, but if this 
 simple question has no clear answer I don't see why it sould 
 make it into the language.
Try a different context: auto a = 7; import std.format; auto str = format("%s times 3 is %s", a, a*3); //or import std.conv; auto str = text(a, " times 3 is ", a*3); //or auto str = $"{a} times 3 is {a*3}";
Yes this is a very basic lowering. The value comes from the fact (assumption?) that this pattern of constructing a string from a mix of strings and expressions is very common. The value of a feature could be described as usage * productivity_improvement = feature_value So while the productivity_improvement may be modest the usage is high enough to give a high feature_value and justify the addition. A sign of this is the number of other popular languages supporting this feature (not arguing for just copy other languages but it is still an indicator). Unfortunately I have no hard data for these numbers.
Apr 15
parent reply cym13 <cpicard openmailbox.org> writes:
On Saturday, 15 April 2017 at 20:45:23 UTC, Jonas Drewsen wrote:
 On Saturday, 15 April 2017 at 20:20:49 UTC, Stanislav Blinov 
 wrote:
 On Saturday, 15 April 2017 at 20:12:41 UTC, cym13 wrote:
 On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen 
 wrote:
 This has been proposed before, and I still don't see the 
 added value compared to:

     auto a=7;
     writeln(a, " times 3 is ", a*3);

 besides adding compiler complexity, language complexity and 
 parsing complexity which leaves room for more bugs to be 
 invented. I'm a bit more harsh than I could be, but if this 
 simple question has no clear answer I don't see why it sould 
 make it into the language.
Try a different context: auto a = 7; import std.format; auto str = format("%s times 3 is %s", a, a*3); //or import std.conv; auto str = text(a, " times 3 is ", a*3); //or auto str = $"{a} times 3 is {a*3}";
Yes this is a very basic lowering. The value comes from the fact (assumption?) that this pattern of constructing a string from a mix of strings and expressions is very common. The value of a feature could be described as usage * productivity_improvement = feature_value So while the productivity_improvement may be modest the usage is high enough to give a high feature_value and justify the addition. A sign of this is the number of other popular languages supporting this feature (not arguing for just copy other languages but it is still an indicator). Unfortunately I have no hard data for these numbers.
There is a very big hole in your equation. It's more like: feature_value = usage * productivity_improvement - (development_cost + maintainance cost) also it's worth noting that the productivity improvement is weighed down by the time needed to learn the new way, to understand other people's code that use yet another way to do things, to sift through code to find bugs... I'm not saying the end value isn't positive, maybe it is. I just don't see how right now. Just an anecdote: I often do security code reviews, that's my thing. I work with a lot of languages in that context, and I hate having to audit perl or ruby code. It's not because they're bad languages, but there is just so many ways to build strings and so many ways to execute shell code that finding them all in the code to check them is a nightmare. In python on the contrary there is a small set of functions that you can use for subprocessing. Besides they are all functions so even if they're different the structure is alike. This makes it *so* much easier. I want to be able to find bugs easily. I want D to be like python on that part. Not perl. Not ruby.
Apr 15
parent Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sat, 2017-04-15 at 21:48 +0000, cym13 via Digitalmars-d wrote:
 [=E2=80=A6]
 structure is alike. This makes it *so* much easier. I want to be=C2=A0
 able to find bugs easily. I want D to be like python on that=C2=A0
 part. Not perl. Not ruby.
Python now has string interpolation, f-strings. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Apr 15
prev sibling parent reply cym13 <cpicard openmailbox.org> writes:
On Saturday, 15 April 2017 at 20:20:49 UTC, Stanislav Blinov 
wrote:
 On Saturday, 15 April 2017 at 20:12:41 UTC, cym13 wrote:
 On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen 
 wrote:
 This has been proposed before, and I still don't see the added 
 value compared to:

     auto a=7;
     writeln(a, " times 3 is ", a*3);

 besides adding compiler complexity, language complexity and 
 parsing complexity which leaves room for more bugs to be 
 invented. I'm a bit more harsh than I could be, but if this 
 simple question has no clear answer I don't see why it sould 
 make it into the language.
Try a different context: auto a = 7; import std.format; auto str = format("%s times 3 is %s", a, a*3); //or import std.conv; auto str = text(a, " times 3 is ", a*3); //or auto str = $"{a} times 3 is {a*3}";
This tells me nothing. What value does it add really? Do we need yet another way to make a damn string? There is value in having a clear, unique interface. I know it's nowhere near unique right now but that only more reasons not to add yet another method to do what can already be done with 3 (!) more keystrokes.
Apr 15
parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Saturday, 15 April 2017 at 21:38:24 UTC, cym13 wrote:
 On Saturday, 15 April 2017 at 20:20:49 UTC, Stanislav Blinov 
 wrote:
 On Saturday, 15 April 2017 at 20:12:41 UTC, cym13 wrote:
 On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen 
 wrote:
 This has been proposed before, and I still don't see the 
 added value compared to:

     auto a=7;
     writeln(a, " times 3 is ", a*3);

 besides adding compiler complexity, language complexity and 
 parsing complexity which leaves room for more bugs to be 
 invented. I'm a bit more harsh than I could be, but if this 
 simple question has no clear answer I don't see why it sould 
 make it into the language.
Try a different context: auto a = 7; import std.format; auto str = format("%s times 3 is %s", a, a*3); //or import std.conv; auto str = text(a, " times 3 is ", a*3); //or auto str = $"{a} times 3 is {a*3}";
This tells me nothing. What value does it add really? Do we need yet another way to make a damn string? There is value in having a clear, unique interface. I know it's nowhere near unique right now but that only more reasons not to add yet another method to do what can already be done with 3 (!) more keystrokes.
How about... it removes an import or two? Roughly 41.5% of Phobos (module-wise) depends on either format() or text(). And I didn't even include the ~ and .stringofs in the search. Quick visual scan suggests that a good portion of that could be replaced with the proposed solution, removing the dependency. Talk about "parsing complexity"... You have a peculiar way of asking for a clear answer. There are ways to vent frustration without inflicting it on others, you know.
Apr 15
next sibling parent reply cym13 <cpicard openmailbox.org> writes:
On Saturday, 15 April 2017 at 23:11:42 UTC, Stanislav Blinov 
wrote:
 On Saturday, 15 April 2017 at 21:38:24 UTC, cym13 wrote:
 On Saturday, 15 April 2017 at 20:20:49 UTC, Stanislav Blinov 
 wrote:
 On Saturday, 15 April 2017 at 20:12:41 UTC, cym13 wrote:
 On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen 
 wrote:
 This has been proposed before, and I still don't see the 
 added value compared to:

     auto a=7;
     writeln(a, " times 3 is ", a*3);

 besides adding compiler complexity, language complexity and 
 parsing complexity which leaves room for more bugs to be 
 invented. I'm a bit more harsh than I could be, but if this 
 simple question has no clear answer I don't see why it sould 
 make it into the language.
Try a different context: auto a = 7; import std.format; auto str = format("%s times 3 is %s", a, a*3); //or import std.conv; auto str = text(a, " times 3 is ", a*3); //or auto str = $"{a} times 3 is {a*3}";
This tells me nothing. What value does it add really? Do we need yet another way to make a damn string? There is value in having a clear, unique interface. I know it's nowhere near unique right now but that only more reasons not to add yet another method to do what can already be done with 3 (!) more keystrokes.
How about... it removes an import or two? Roughly 41.5% of Phobos (module-wise) depends on either format() or text(). And I didn't even include the ~ and .stringofs in the search. Quick visual scan suggests that a good portion of that could be replaced with the proposed solution, removing the dependency. Talk about "parsing complexity"... You have a peculiar way of asking for a clear answer. There are ways to vent frustration without inflicting it on others, you know.
Removing imports is a good point, the first concrete one to be mentionned. I'm not sure it matters that much though as I think those imports are generic enough that I believe they would be imported anyway, but it's a real point. For parsing complexity I'm not talking about quantity actually, maybe I should say "parser complexity" instead. There again, all I want is a solid rational. This is far from being a little change, if the only things it brings are "looks nicer" and "one less import in some cases" I'm sure you'll agree that the case is pretty thin. It won't ever be my call but bear with me challenging the idea. I'm not venting frustration, and I'm not being insulting or anything, just clear and explicit with what problem I see.
Apr 15
parent Walter Bright <newshound2 digitalmars.com> writes:
On 4/15/2017 4:51 PM, cym13 wrote:
 Removing imports is a good point, the first concrete one to be mentionned. I'm
 not sure it matters that much though as I think those imports are generic
enough
 that I believe they would be imported anyway, but it's a real point.
It may not be necessary to have any dependencies on any import. $"{a} times 3 is {a*3}" could be rewritten by the parser to: "%s times 3 is %s", a, a * 3 and that is that. (I.e. just an AST rewrite.) It would be quite a bit simpler than Jonas' proposed implementation.
Apr 18
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 15 April 2017 at 23:11:42 UTC, Stanislav Blinov 
wrote:
 How about... it removes an import or two?
It doesn't actually remove the dependency, it is just syntax sugar over it (there is precedent for this in the language, the pow operator calls a Phobos function, but it means you don't actually gain decoupling of modules).
Apr 15
parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Saturday, 15 April 2017 at 23:58:18 UTC, Adam D. Ruppe wrote:
 On Saturday, 15 April 2017 at 23:11:42 UTC, Stanislav Blinov 
 wrote:
 How about... it removes an import or two?
It doesn't actually remove the dependency, it is just syntax sugar over it (there is precedent for this in the language, the pow operator calls a Phobos function, but it means you don't actually gain decoupling of modules).
As presented, it doesn't. But it can be implemented in a way that it does. The compiler is capable of conversions without ever needing std.conv, and if custom .toString() is required, it will already be available anyway. As to the importance of this, I can only suggest measuring the code, both public and your own. Constructing a string out of variable values without any special formatting is, in my experience, a very common operation. Do importing a module *just* to build a mixin without building a mixin to build that mixin, static error message or a result for a script; CTFE evaluating a good deal of general-purpose code for a trivial use case have to be common as well?
Apr 15
parent Jonas Drewsen <nospam4321 hotmail.com> writes:
On Sunday, 16 April 2017 at 00:25:19 UTC, Stanislav Blinov wrote:
 On Saturday, 15 April 2017 at 23:58:18 UTC, Adam D. Ruppe wrote:
 On Saturday, 15 April 2017 at 23:11:42 UTC, Stanislav Blinov 
 wrote:
 How about... it removes an import or two?
It doesn't actually remove the dependency, it is just syntax sugar over it (there is precedent for this in the language, the pow operator calls a Phobos function, but it means you don't actually gain decoupling of modules).
As presented, it doesn't. But it can be implemented in a way that it does. The compiler is capable of conversions without ever needing std.conv, and if custom .toString() is required, it will already be available anyway.
I guess the phobos dependency could be removed with some extra work which I'll happily do. But the main worry I hear from people is the added language complexity which isn't going away.
Apr 17
prev sibling next sibling parent reply crimaniak <crimaniak gmail.com> writes:
On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen wrote:
 The compiler will basically lower the $"..." string to a mixin 
 that concatenates
 the expression parts of the (inside the {}) and the plain text 
 parts.
It's easy implementable as a library (see https://github.com/Abscissa/scriptlike#string-interpolation) so it does not seem like a good idea to modify the language, only to change interp!"" to $"".
Apr 15
next sibling parent Jonas Drewsen <nospam4321 hotmail.com> writes:
On Saturday, 15 April 2017 at 20:35:56 UTC, crimaniak wrote:
 On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen wrote:
 The compiler will basically lower the $"..." string to a mixin 
 that concatenates
 the expression parts of the (inside the {}) and the plain text 
 parts.
It's easy implementable as a library (see https://github.com/Abscissa/scriptlike#string-interpolation) so it does not seem like a good idea to modify the language, only to change interp!"" to $"".
Lowerings are by definition possible to implement in a library. Using that argument foreach (i; 0..100) {} should not be part of the language even though I think very few would live without foreach.
Apr 15
prev sibling parent reply "Nick Sabalausky (Abscissa)" <SeeWebsiteToContactMe semitwist.com> writes:
On 04/15/2017 04:35 PM, crimaniak wrote:
 On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen wrote:
 The compiler will basically lower the $"..." string to a mixin that
 concatenates
 the expression parts of the (inside the {}) and the plain text parts.
It's easy implementable as a library (see https://github.com/Abscissa/scriptlike#string-interpolation) so it does not seem like a good idea to modify the language, only to change interp!"" to $"".
Yea, and note, I'm still open to the idea of better names than "interp". I'm still not entirely happy with that name. I'm even half-tempted to use "_". The only one problem I've found with doing it in library though: Far as I could tell, it seems to require the caller uses string mixins, which makes actually using it a little uglier and more verbose than I would like. Maybe I'm overlooking something obvious, but I haven't been able to find a way to change it to either a template mixin or even just a plain template without sacrificing to whole point of interpolated strings: specifying the arguments 100% inline. What I think would be ideal is a language enhancement to allow "interp" to do its job without the extra syntactical noise. That would not only give us good interpolates strings, but would likely have other applications as well.
Apr 16
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2017-04-16 18:10, Nick Sabalausky (Abscissa) wrote:

 What I think would be ideal is a language enhancement to allow "interp"
 to do its job without the extra syntactical noise. That would not only
 give us good interpolates strings, but would likely have other
 applications as well.
It's called AST macros ;) -- /Jacob Carlborg
Apr 17
prev sibling next sibling parent crimaniak <crimaniak gmail.com> writes:
On Sunday, 16 April 2017 at 16:10:15 UTC, Nick Sabalausky 
(Abscissa) wrote:
 Yea, and note, I'm still open to the idea of better names than 
 "interp". I'm still not entirely happy with that name. I'm even 
 half-tempted to use "_".
When I needed interpolation, I did not know about this library. So I create my own implementation and name it `expand`. I only needed class properties and did not support the expression, so this can not be considered a general solution, but name `expand` seems to be good for me. unittest { class InterTest { static int a = 1; static string bb = "--bb--"; mixin ExpandLocals; auto getInterpolated() { return expand!"a is $a, bb is $bb, and this is just $ sign"; } } assert((new InterTest).getInterpolated() == "a is 1, bb is --bb--, and this is just $ sign"); }
 What I think would be ideal is a language enhancement to allow 
 "interp" to do its job without the extra syntactical noise. 
 That would not only give us good interpolates strings, but 
 would likely have other applications as well.
Now I spend thinking some time about it and didn't find common solution without text mixin too.
Apr 17
prev sibling parent reply Martin Tschierschke <mt smartdolphin.de> writes:
On Sunday, 16 April 2017 at 16:10:15 UTC, Nick Sabalausky 
(Abscissa) wrote:
 On 04/15/2017 04:35 PM, crimaniak wrote:
 On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen 
 wrote:
 The compiler will basically lower the $"..." string to a 
 mixin that
 concatenates
 the expression parts of the (inside the {}) and the plain 
 text parts.
It's easy implementable as a library (see https://github.com/Abscissa/scriptlike#string-interpolation) so it does not seem like a good idea to modify the language, only to change interp!"" to $"".
Yea, and note, I'm still open to the idea of better names than "interp". I'm still not entirely happy with that name. I'm even half-tempted to use "_". The only one problem I've found with doing it in library though: Far as I could tell, it seems to require the caller uses string mixins, which makes actually using it a little uglier and more verbose than I would like.
I was trying to get it shorter: // From // Output: The number 21 doubled is 42! int num = 21; writeln( mixin(interp!"The number ${num} doubled is ${num * 2}!") ); 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}!" This now looks more like "normal" scripting than writeln( mixin(interp!"The number ${num} doubled is ${num * 2}!") );
 Maybe I'm overlooking something obvious, but I haven't been 
 able to find a way to change it to either a template mixin or 
 even just a plain template without sacrificing to whole point 
 of interpolated strings: specifying the arguments 100% inline.

 What I think would be ideal is a language enhancement to allow 
 "interp" to do its job without the extra syntactical noise. 
 That would not only give us good interpolates strings, but 
 would likely have other applications as well.
I am not against the idea making string interpolations part of the language, in vibe.d diet templates the extrapolation is marked with #{var}, the ruby style, I like this too. At the beginning I thought this is already part of d. Regards mt.
Apr 17
parent Jonas Drewsen <nospam4321 hotmail.com> writes:
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.
Apr 17
prev sibling next sibling parent reply Jack Stouffer <jack jackstouffer.com> writes:
On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen wrote:
 ...
First, there's a process for language additions, please see https://github.com/dlang/DIPs/blob/master/README.md Secondly, I can tell you that any proposal that can be solved via the standard library has a very low chance of being accepted. D is already a complex language and it would take a important problem in order to justify making it more complex. As this is already do-able via Phobos, I would personally vote no to this addition.
Apr 15
parent Jonas Drewsen <nospam4321 hotmail.com> writes:
On Saturday, 15 April 2017 at 20:57:33 UTC, Jack Stouffer wrote:
 On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen wrote:
 ...
First, there's a process for language additions, please see https://github.com/dlang/DIPs/blob/master/README.md Secondly, I can tell you that any proposal that can be solved via the standard library has a very low chance of being accepted. D is already a complex language and it would take a important problem in order to justify making it more complex. As this is already do-able via Phobos, I would personally vote no to this addition.
Thank you. I have been following the forums for many years so am aware of the process and chances of something like this getting in. For that exact reason I wanted to do a minimal implementation to show that I'm serious and a RFC. Doing a DIP is a lot of work that I'm only willing to use my time on if I have some confidence that it will not be in vain. I will do the DIP if this ever gets a thumbs up.
Apr 15
prev sibling next sibling parent reply Xinok <xinok live.com> writes:
On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen wrote:
 Hi all

 <snip>
I shared my thoughts on such a feature just a couple weeks ago: https://forum.dlang.org/post/oedeijdewmhazaqazdyo forum.dlang.org
Apr 15
parent Jonas Drewsen <nospam4321 hotmail.com> writes:
On Saturday, 15 April 2017 at 21:03:27 UTC, Xinok wrote:
 On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen wrote:
 Hi all

 <snip>
I shared my thoughts on such a feature just a couple weeks ago: https://forum.dlang.org/post/oedeijdewmhazaqazdyo forum.dlang.org
Most of you points applies to std.conv.text as well don't they? If you need special output buffers or memory management then use the tools right for that. This is about making the common case easier and keep the uncommon as it has always been.
Apr 15
prev sibling next sibling parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 4/15/17 10:04 PM, Jonas Drewsen wrote:
 Hi all

   I've been wanting to have support for interpolated strings in D for
 some time now that will allow you to write e.g.:

 auto a = 7;
 writeln( $"{a} times 3 is {a*3}" );

 Code speaks louder that words so I've made a PR that adds this support
 to ddmd as a RFC [1].

 The compiler will basically lower the $"..." string to a mixin that
 concatenates
 the expression parts of the (inside the {}) and the plain text parts.
Just a quick comment - I would be more interested if the string interpolation was extendable by the user. A simple path would be to make string interpolation produce AliasSeq of interleaved pieces of string with the arguments. So in your example writeln($"{a} times 3 is {a*3}") lowers to writeln(AliasSeq!(a, " times 3 is ", a*3)); which is basically writeln(a, " times 3 is ", a*3); but notice how depending on the function it can be used for other things such as DSLs.
 I do recognize that this is not part of the 2017 H1 plan but I also
 believe such smaller improvements added regularly can make the language
 both more productive and attractive.

 In case this addition gets a thumbs up I will of course improve test
 coverage and any needed quality of implementation.

 [1] https://github.com/dlang/dmd/pull/6703
--- Dmitry Olshansky
Apr 15
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2017-04-15 22:04, Jonas Drewsen wrote:
 Hi all

    I've been wanting to have support for interpolated strings in D for
 some time now that will allow you to write e.g.:

 auto a = 7;
 writeln( $"{a} times 3 is {a*3}" );

 Code speaks louder that words so I've made a PR that adds this support
 to ddmd as a RFC [1].

 The compiler will basically lower the $"..." string to a mixin that
 concatenates
 the expression parts of the (inside the {}) and the plain text parts.

 I do recognize that this is not part of the 2017 H1 plan but I also
 believe such smaller improvements added regularly can make the language
 both more productive and attractive.

 In case this addition gets a thumbs up I will of course improve test
 coverage and any needed quality of implementation.
My initial reaction is that this is something that can be implemented as library code if the language would have support for AST macros. On the other hand, this is something I would like to have in the language or the standard library. -- /Jacob Carlborg
Apr 16
parent reply Jonas Drewsen <nospam4321 hotmail.com> writes:
On Sunday, 16 April 2017 at 08:01:02 UTC, Jacob Carlborg wrote:
 On 2017-04-15 22:04, Jonas Drewsen wrote:
 [...]
My initial reaction is that this is something that can be implemented as library code if the language would have support for AST macros. On the other hand, this is something I would like to have in the language or the standard library.
I'm in favor of AST macros but I think that has been shot down by Walter already afaik.
Apr 17
parent Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Monday, April 17, 2017 18:10:23 Jonas Drewsen via Digitalmars-d wrote:
 On Sunday, 16 April 2017 at 08:01:02 UTC, Jacob Carlborg wrote:
 On 2017-04-15 22:04, Jonas Drewsen wrote:
 [...]
My initial reaction is that this is something that can be implemented as library code if the language would have support for AST macros. On the other hand, this is something I would like to have in the language or the standard library.
I'm in favor of AST macros but I think that has been shot down by Walter already afaik.
Walter is very much against AST macros and has said so on several occasions. It's one of those features that probably has about as much chance making it into the language as a snowball has in hell... - Jonathan M Davis
Apr 17
prev sibling next sibling parent reply Jonas Drewsen <nospam4321 hotmail.com> writes:
On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen wrote:
 Hi all

   I've been wanting to have support for interpolated strings in 
 D for some time now that will allow you to write e.g.:

 auto a = 7;
 writeln( $"{a} times 3 is {a*3}" );

 Code speaks louder that words so I've made a PR that adds this 
 support to ddmd as a RFC [1].

 The compiler will basically lower the $"..." string to a mixin 
 that concatenates
 the expression parts of the (inside the {}) and the plain text 
 parts.

 I do recognize that this is not part of the 2017 H1 plan but I 
 also believe such smaller improvements added regularly can make 
 the language both more productive and attractive.

 In case this addition gets a thumbs up I will of course improve 
 test coverage and any needed quality of implementation.

 [1] https://github.com/dlang/dmd/pull/6703
Seems like there are mixed opinions about inclusion of a thing like this. Looking at all the old PRs on dlang github slowly bit rotting it makes me wonder how not to end up in that pool. I think that history has shown that Walter/Andrei are gatekeepers on what will ever get into the language. For the sake of contributers (incl. me or course :) ) it would make sense to get a preliminary "never going in" clarification by them early on. Even before a DIP has been written because writing that takes a good amount of effort. Also collect these declined language change decisions (such as AST Macros) on the wiki for future contributers to scan through before anything else. I volunteer to add "interpolated strings" to the page in case it gets declined. The page could also list pre-approved language changes such as async functions (which Walter wants afaik). I guess the main question is really to Walter and Andrei if we could get some kind "never going in" or "could be considered" clarification on e.g. news group threads named like e.g. "Language Design Change: Interpolated string"? Based on that the next steps: DIP, PR etc. step would take place.
Apr 17
parent reply Jacob Carlborg <doob me.com> writes:
On 2017-04-17 21:28, Jonas Drewsen wrote:

 The page could also list pre-approved language
 changes such as async functions (which Walter wants afaik).
Another feature that can be implemented with AST macros. This is starting to get ridicules. So many features have been added and are talked about that can be implemented with AST macros instead. Same as with the scope/safe related DIPs. Many smallish specialized features are added instead of a generic feature that can handle all of them. Increasing the complexity of the language. -- /Jacob Carlborg
Apr 17
parent reply Stefan Koch <uplink.coder googlemail.com> writes:
On Tuesday, 18 April 2017 at 06:54:11 UTC, Jacob Carlborg wrote:
 On 2017-04-17 21:28, Jonas Drewsen wrote:

 The page could also list pre-approved language
 changes such as async functions (which Walter wants afaik).
Another feature that can be implemented with AST macros. This is starting to get ridicules. So many features have been added and are talked about that can be implemented with AST macros instead. Same as with the scope/safe related DIPs. Many smallish specialized features are added instead of a generic feature that can handle all of them. Increasing the complexity of the language.
The corresponding ast-macros would be extremely complex, slow and worst of all not checkable.
Apr 17
parent Jacob Carlborg <doob me.com> writes:
On 2017-04-18 08:59, Stefan Koch wrote:

 The corresponding ast-macros would be extremely complex
No, it's not that complex.
, slow and worst
 of all not checkable.
What do you mean "not checkable"? -- /Jacob Carlborg
Apr 18
prev sibling next sibling parent Kapps <opantm2+spam gmail.com> writes:
On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen wrote:
 Hi all

   I've been wanting to have support for interpolated strings in 
 D for some time now that will allow you to write e.g.:

 auto a = 7;
 writeln( $"{a} times 3 is {a*3}" );

 Code speaks louder that words so I've made a PR that adds this 
 support to ddmd as a RFC [1].

 The compiler will basically lower the $"..." string to a mixin 
 that concatenates
 the expression parts of the (inside the {}) and the plain text 
 parts.

 I do recognize that this is not part of the 2017 H1 plan but I 
 also believe such smaller improvements added regularly can make 
 the language both more productive and attractive.

 In case this addition gets a thumbs up I will of course improve 
 test coverage and any needed quality of implementation.

 [1] https://github.com/dlang/dmd/pull/6703
C# got this feature recently. I didn't expect it to be a significant difference, but I do find it a substantial improvement. Not only does it clearly show what goes where, but it's so much cleaner and more convenient.
Apr 17
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
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.
Apr 18