Re: Interpolated strings
On Thursday, 24 August 2017 at 11:57:59 UTC, Petar Kirov [ZombineDev] wrote: On Thursday, 24 August 2017 at 11:07:16 UTC, Suliman wrote: All modern languages like Dart and C# have string interpolation. Sharp example: Console.WriteLine($"Hello {args[0]}!"); Who can summary is there any objective reasons why it's not realized in D? No one has submitted a DIP for that feature and no one has tried to implement it. You could be the first one :P FYI there has been an attempt: https://github.com/dlang/dmd/pull/6703 But I think this is more an issue of how the language should allow it then on the implementation itself.
Re: Interpolated strings
On Thursday, 24 August 2017 at 11:07:16 UTC, Suliman wrote: All modern languages like Dart and C# have string interpolation. Sharp example: Console.WriteLine($"Hello {args[0]}!"); Who can summary is there any objective reasons why it's not realized in D? Maybe you ought to read this entire thread?
Re: Interpolated strings
On Thursday, 24 August 2017 at 11:07:16 UTC, Suliman wrote: All modern languages like Dart and C# have string interpolation. Sharp example: Console.WriteLine($"Hello {args[0]}!"); Who can summary is there any objective reasons why it's not realized in D? As Raymond Chen once said[1], because no one implemented it. That certainly is part of the answer. If you want other "objective" reasons, there basically are none. It's technically possible to implement, but D devs haven't found it necessary or to their liking. Plenty of reasons for not implementing it have been given in this thread. You may disagree, in which case I encourage you to write a DIP and implement it. -- Biotronic [1] https://blogs.technet.microsoft.com/seanearp/2007/04/12/why-doesnt-this-feature-exist/
Re: Interpolated strings
On Thursday, 24 August 2017 at 11:07:16 UTC, Suliman wrote: All modern languages like Dart and C# have string interpolation. Sharp example: Console.WriteLine($"Hello {args[0]}!"); Who can summary is there any objective reasons why it's not realized in D? No one has submitted a DIP for that feature and no one has tried to implement it. You could be the first one :P
Re: Interpolated strings
All modern languages like Dart and C# have string interpolation. Sharp example: Console.WriteLine($"Hello {args[0]}!"); Who can summary is there any objective reasons why it's not realized in D?
Re: Interpolated strings
On Thursday, 20 April 2017 at 18:28:30 UTC, Atila Neves wrote: On Monday, 17 April 2017 at 19:38:33 UTC, Kapps wrote: On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen wrote: [...] 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. I don't understand how writeln($"{a} times 3 is {a * 3}"); is even marginally better than writeln(a, " times 3 is ", a * 3); // look ma, works right now! It's not even fewer characters. Atila I find the first one to be cleaner honestly. It shows exactly where values are coming from, doesn't have a bunch of commas that can be annoying to match up, and doesn't start and stop a string multiple times. And for the second one, that's only because writeln specifically includes overloads to take in multiple objects and merge them together. This isn't something functions should have to always do (except in the cases where taking in multiple arguments is actually more efficient, like presumably with writeln since it doesn't need to actually merge the string). It's not like it's a huge missing feature. Having something like the below isn't too bad: foo(format("Value of ", a, " * 3 is ", a * 3, ".")); But it's just not as nice as: foo($"Value of {a} * 3 is {a * 3}.");
Re: Interpolated strings
On 04/21/2017 08:45 AM, Gary Willoughby wrote: On Friday, 21 April 2017 at 12:32:01 UTC, Nick Sabalausky (Abscissa) wrote: "Completely unnecessary" features like that are exactly what make D worthwhile in the first place. Otherwise may as well stick to C++ or Java. Multiple ways of doing the same thing are not valuable or progressive. Go and Rust are both smashing D in popularity and user share, maybe we could learn why that's the case. As other have mentioned, there are plenty of far more more likely reasons for go/rust's popularity over D. As for not having multiple ways of doing things, that's what single-paradigm languages like Haskell or early versions of Java are for. D is deliberately multi-paradigm, which automatically throws the whole "python zen" philosophy right out the window: D is about letting the user choose the right tool for the job, not dictating that every shape of peg must be jammed into the square hole.
Re: Interpolated strings
On Friday, 21 April 2017 at 12:45:39 UTC, Gary Willoughby wrote: Go and Rust are both smashing D in popularity and user share, maybe we could learn why that's the case. Can't rely on RAII, can't rely on GC. This is the single biggest problem to me. GC performs slowly, and RAII is inconsistent(no default ctors, can be nested in GC objects, etc..)
Re: Interpolated strings
On Thursday, 20 April 2017 at 20:43:35 UTC, H. S. Teoh wrote: If you're doing internationalization, though, neither option is a good one (I gave an example using dates in another post): printf-style formats have ordering issues (is it year first, then month, then day? Or month first then day then year? Which argument is which?), and interpolated strings have the problem of exposing variable names to the translators (who are probably non-coders), potentially opening up the possibility of arbitrary code execution via l10n strings. This is machine checkable though, the translation code could at least check that the interpolated strings in the translations match the source string's interpolations (possibly in a different order). An issue remaining is: if successive interpolated values depend on the order they are evaluated in, translations can still cause bugs (when they change the order).
Re: Interpolated strings
On Thursday, 20 April 2017 at 21:34:44 UTC, Steven Schveighoffer wrote: Dmitry's solution is superior I think: $"{a} times 3 is {a * 3}" -> AliasSeq!(a, " times 3 is ", a * 3) +1, this is more flexible. Would work fine with writeln. Yep, and std.conv.text. We might want a function that takes the quoted AliasSeq expansion and writes it to an output range. Would work fine with format. No, std.format.format needs a format string as first argument, supplying extra arguments will not work. I like how this expansion *always* parses the string at compile-time. The expansion could be passed whole as template arguments if desired - I think this would allow text!(seq) which, if passed only literal strings and runtime scalar types, can return a fixed size static array, even though the scalar values are read and formatted at runtime.
Re: Interpolated strings
On Thursday, 20 April 2017 at 19:02:20 UTC, Kagamin wrote: Also how various kinds of strings would work? r$"{can}\i\has{slashes}" $`same {here}` r"" and `` are WysiwygStrings. Interpolation is not WYSIWYG. $"" would need to support escaping of the interpolation start character, so may as well escape with backslash like "" strings. $q{{balanced}braces} q{} strings have to lex correctly, so are intended for code - brace interpolation would play badly with braces in code. It might be useful with mixins if using a different interpolation syntax, e.g. $identifier or ${var+1} syntax within the string: void fun(string op)(T a, T b){ mixin(text($q{$a $op= $b;})); } (I used `text` for Dmitry's AliasSeq expansion - use `format` for Walter's).
Re: Interpolated strings
On Friday, 21 April 2017 at 12:45:39 UTC, Gary Willoughby wrote: Multiple ways of doing the same thing are not valuable or progressive. Go and Rust are both smashing D in popularity and user share, maybe we could learn why that's the case. Corporate backing and word-of-mouth? I recall reading a KDE blog article about the problems of internationalizaton where you have large tables of pattern strings (think WelcomeMessage[EN]="Welcome $user to $hostname") where the tokens were very much in different ordering depending on language, or how some may even be considered implicit and ommitted outright. (Japanese springs to mind.) It was way back now so I don't even know where to begin to start looking, but it highlighted how the ordering did not translate well into printf patterns. Citation needed but it's a use-case this would address.
Re: Interpolated strings
Gary Willoughby wrote: Go and Rust are both smashing D in popularity and user share, maybe we could learn why that's the case. 'cause go backed by google, and rust backed by mozilla.
Re: Interpolated strings
On Friday, 21 April 2017 at 12:32:01 UTC, Nick Sabalausky (Abscissa) wrote: "Completely unnecessary" features like that are exactly what make D worthwhile in the first place. Otherwise may as well stick to C++ or Java. Multiple ways of doing the same thing are not valuable or progressive. Go and Rust are both smashing D in popularity and user share, maybe we could learn why that's the case.
Re: Interpolated strings
On 04/21/2017 04:11 AM, Gary Willoughby wrote: On Thursday, 20 April 2017 at 18:28:30 UTC, Atila Neves wrote: I don't understand how writeln($"{a} times 3 is {a * 3}"); is even marginally better than writeln(a, " times 3 is ", a * 3); // look ma, works right now! It's not even fewer characters. Atila This! This is bloat that doesn't need adding. D is complicated already, stop adding more 'stuff' and fix what's already there. I wish more time was taken up on libraries and tooling than completely unnecessary features like this. "Completely unnecessary" features like that are exactly what make D worthwhile in the first place. Otherwise may as well stick to C++ or Java.
Re: Interpolated strings
On Thursday, 20 April 2017 at 18:28:30 UTC, Atila Neves wrote: I don't understand how writeln($"{a} times 3 is {a * 3}"); is even marginally better than writeln(a, " times 3 is ", a * 3); // look ma, works right now! It's not even fewer characters. Atila This! This is bloat that doesn't need adding. D is complicated already, stop adding more 'stuff' and fix what's already there. I wish more time was taken up on libraries and tooling than completely unnecessary features like this.
Re: Interpolated strings
On 04/20/2017 04:43 PM, H. S. Teoh via Digitalmars-d wrote: But if you're printing lots of variables according to a precise template (e.g., rows of a table or a list of fields), format strings make more sense, e.g.: foreach (rec; records) { writefln("[%8d] %20s %10.3f", rec.id, rec.name, rec.amount); writefln(" %20s %10s", rec.altName, rec.comment); writefln(" %20s %6s", rec.address, rec.postalCode); } Meh, I'd argue that's just an example of why interpolated strings need support for formatting: foreach (rec; records) { writeln(%"[%8{rec.id}] %20{rec.name } %10.3{rec.amount}"); writeln(%" %20{rec.altName} %10{rec.comment}"); writeln(%" %20{rec.address} %6{rec.postalCode}"); } And you can't beat this one with interpolated strings: auto matrix = [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]; writefln("Matrix:\n%([ %(%3d, %) ]%|\n%)", matrix); That's actually a perfect example of why I don't like printf-style formatting syntax. I've seen regexes that were more readable. If you're doing internationalization, though, neither option is a good one (I gave an example using dates in another post): printf-style formats have ordering issues (is it year first, then month, then day? Or month first then day then year? Which argument is which?), and There's an extension to printf (which, IIRC, D's format supports) that allows reordering of arguments, much like C#'s format strings, by specifying the argument numerically. But it's an u-g-l-y syntax. Hard to remember, too. And why bother referring to the args numerically when you can have a format string that simply refers to them by name instead (ie, interpolated strings)? interpolated strings have the problem of exposing variable names to the translators (who are probably non-coders), potentially opening up the possibility of arbitrary code execution via l10n strings. In this case, it would seem best to have named arguments with format strings. You're basically describing a templating engine: Which are essentially just interpolated strings with sandboxing (or alternatively, interpolated strings are just embedded templating engines). And yes, I'd rather use a templating engine for non-coder translators than anything I've seen built-into any programming language: whether format string or interpolated string. But the last thing I'd hand them is anything with printf syntax. Between these textbook cases, though, is plenty of gray areas where it's debatable whether one syntax is clearly superior over the other(s). And here, factors of what you're used to, the kind of output you usually need to produce, etc., all come into play and there doesn't seem to be a clear one-size-fits-all. When I see lots of options that are all basically the same thing, but each have their own little limitations and drawbacks (thus limiting each one's applicability to mere subsections of the overall problem domain)...well...that really bugs the shit out of me. ;) It's a big, loud, flashing sign that everybody's designs have gotten things wrong and none of them have quite hit the right mark. It makes me want to consolidate: Break down the limitations that divide the current options, reach the true "core" of the problem, and show that they're not really all separate tools, but mere approximations of the proper generalization that simply needed to be found and brought out. It's analogous to mathematical models: When the equations are complex and special-cased (like the rift between Newtonian physics and quantum physics) - that's how they know they probably got the model wrong. When they wind up with something simple, elegant and just-works, that's a sign they may be on the right track. Luckily, good general-purpose tools are a lot easier to come up with than unified field theory. ;) If scientists acted like programmers, the solar system model would still be stuck at the pre-Copernicus "All those planets have VERY COMPLEX movements! Very, VERY complex!! Good thing we have this big ol' toolbox with all the many, many tools involved in modeling all those complexities and special cases!" Basically, I'm the antithesis of a polyglot programmer :)
Re: Interpolated strings
On 4/18/17 4:50 AM, Walter Bright wrote: 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. Dmitry's solution is superior I think: $"{a} times 3 is {a * 3}" -> AliasSeq!(a, " times 3 is ", a * 3) Would work fine with writeln. Would work fine with format. Wouldn't be a drop-in replacement for a string, as other languages like to do. But has huge potential. I love Jonathan Marler's idea of using it for SQL inline grammar with prepared statements. Replacing something like: sql("INSERT INTO table VALUES (?, ?, ?, ?, ?, ?, ?, ?)", a, b, c, d, e, f, g, h); with: sql($"INSERT row INTO table VALUES ({a}, {b}, {c}, {d}, {e}, {f}, {g}, {h})"); That is absolutely awesome. What this does is match the parameter to where it belongs in the string, without all the extra quotes and commas. And it does no GC activity, and doesn't require any specific formatting tokens! -Steve
Re: Interpolated strings
On Thu, Apr 20, 2017 at 03:32:18PM -0400, Nick Sabalausky (Abscissa) via Digitalmars-d wrote: [...] > IMO, the only time a format string should be used instead of > std.conv.text() or interpolated strings is when: > > 1. You're just rendering *one* value at a time with non-standard > formatting options (ie, left-/right-justified, leading/trailing > zeroes, etc). (Speaking of which, `interp` could really use some > formatting features so this could be avoided, and for performance > reasons.) > > 2. You need to support custom formatting specified at runtime (ex: > software that supports displaying date/time in custom user-defined > formats) but want to be lazy about it and not bother finding/writing a > more user-friendly formatting syntax than printf-style (ie, extremely > rare). Hmm. I wonder if this is a matter of habituation and the kind of use cases you most commonly encounter. Having programmed in Perl extensively as well as in C/C++/D, I've dealt with both kinds of syntaxes, and I find that each has its own niche where it does best, while for use cases outside that niche it still works but not as well as the other syntax. For example, if you are printing lots and lots of text with only the occasional variable, the interpolated syntax is far more readable, e.g.: #!/usr/bin/perl print <
Re: Interpolated strings
On 04/20/2017 02:28 PM, Atila Neves wrote: I don't understand how writeln($"{a} times 3 is {a * 3}"); is even marginally better than writeln(a, " times 3 is ", a * 3); // look ma, works right now! It's not even fewer characters. Atila The latter IS pretty good, I use it often. It's *VASTLY* better than format strings[1]. But, cognitively, I find the former much easier to read and write (Apparently many other people seem to as well, although perhaps not everyone). I'm not sure I can explain why especially well, but the visual parsing is just much simpler and more symmetric, and it's much easier to tell at a glance where the full, umm "string", starts and ends, and what's going inside the string and what isn't. [1] Format strings, even with the new compile-time improvements in the latest DMD, for one thing, they still fail at DRY: Ie, with format strings, even compile-time ones, you're listing your parameters TWICE - once to describe WHERE they go and how they're formatted, and then again SEPARATELY to select WHAT data to be rendered. And then format strings also have the downside that the "WHAT data" is specified out-of-band, making it making it easy to get things flipped around, and just generally harder to see at-a-glance what's going on (similar to how UFCS chains can be easier to read than a tree of nested function calls, because for UFCS chains the ordering is perfectly sequential, unlike nested function calls and format strings where the logic jumps around). TBH, I'm not all that excited about the compile-time enhancements to format strings simply because...they're still format strings. And not only that, but they're printf-style syntax which is a total unintuitive mess (C#'s format string syntax was vastly better...for a format string, anyway...) IMO, the only time a format string should be used instead of std.conv.text() or interpolated strings is when: 1. You're just rendering *one* value at a time with non-standard formatting options (ie, left-/right-justified, leading/trailing zeroes, etc). (Speaking of which, `interp` could really use some formatting features so this could be avoided, and for performance reasons.) 2. You need to support custom formatting specified at runtime (ex: software that supports displaying date/time in custom user-defined formats) but want to be lazy about it and not bother finding/writing a more user-friendly formatting syntax than printf-style (ie, extremely rare).
Re: Interpolated strings
Also how various kinds of strings would work? r$"{can}\i\has{slashes}" $`same {here}` $q{{balanced}braces} For templates it's straightforward.
Re: Interpolated strings
On 04/20/2017 02:40 PM, Nick Sabalausky (Abscissa) wrote: auto exho() { return writeln("${name} and this are app ${age*365*24} hours!"); } Correction: auto exho() { return writeln( ""~ _interp_text(name)~ " and this are app "~ _interp_text(age*365*24)~ " hours!" ); } Where _interp_text is really just a thin wrapper over std.conv.text. Again, note that `name` and `age` are undefined symbols unless exho is defined as a nested function within the function that actually defines `name` and `age`. And again, this is exactly why interp!"..." was forced to work by returning a string for the caller to mixin.
Re: Interpolated strings
On 04/20/2017 06:23 AM, Martin Tschierschke wrote: and this not? import scriptlike; // with exho definition outside the scope of the used vars auto exho(string x)(){return mixin("writeln("~interp!x~")");} void main() { auto name = userInput!string("Please enter your name"); auto age = userInput!int("And your age"); writeln(mixin(interp!"${name} you are app. ${age*365} days old")); exho!"${name} and this are app ${age*365*24} hours!"; } The definition for: exho!"${name} and this are app ${age*365*24} hours!" ...once the template is instantiated and the mixin is evaluated, is turned into this: auto exho() { return writeln("${name} and this are app ${age*365*24} hours!"); } But, there is no identifier "name" or "age" within the scope of exho. However, if exho is instead defined as a nested function WITHIN main, then as with any (non-static) nested function, it DOES have access to the local variables from the outer function. This, incidentally, is exactly why interp!"..." needs to be a string mixin in the first place.
Re: Interpolated strings
On Thursday, 20 April 2017 at 18:28:30 UTC, Atila Neves wrote: writeln($"{a} times 3 is {a * 3}"); is even marginally better than writeln(a, " times 3 is ", a * 3); // look ma, works right now! Matching up the correct commas and quotes is a bit of a pain in the latter. Though I don't think it is a big deal... I think most string building is a mistake anyway, as in you should find some entirely different way to it rather than embedding variables like that. But if I am going to do it it, the writeln(a, ",", "\") is like my least favorite way (yet I use it a lot because it is in there)
Re: Interpolated strings
On Monday, 17 April 2017 at 19:38:33 UTC, Kapps wrote: On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen wrote: [...] 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. I don't understand how writeln($"{a} times 3 is {a * 3}"); is even marginally better than writeln(a, " times 3 is ", a * 3); // look ma, works right now! It's not even fewer characters. Atila
Re: Interpolated strings
On 2017-04-19 03:45, Jon Degenhardt wrote: On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen wrote: I've been wanting to have support for interpolated strings in D for some time now that will allow you to write e.g.: [...] One place I'd appreciate interpolated strings is as an option when working with heredoc strings. These strings are often multiple lines or paragraphs, using format style construction is often error-prone due to length. --Jon So, that makes 2 otherwise error-prone use-cases. The first being keeping arguments & format string in sync (Jonathan Marler). And they actually compound! (Large strings get out of sync quicker I would guess) And, I would like to add that this is are very newby friendly feature. Nowadays people might even expect a language to have this.
Re: Interpolated strings
On Thursday, 20 April 2017 at 10:23:30 UTC, Martin Tschierschke wrote: Can it be possible to allow a function to be defined outside the scope of use to return a "mixin object"? That's basically what I propose: https://forum.dlang.org/post/msotbcaqipiiqxiup...@forum.dlang.org this can be cheap compromise between macros and mixins.
Re: Interpolated strings
On Wednesday, 19 April 2017 at 17:51:05 UTC, Nick Sabalausky (Abscissa) wrote: On 04/17/2017 03:41 PM, Jonas Drewsen wrote: [...] exho!"The number ${num} doubled is ${num * 2}!" Also, it only works if you're just sending the string to writeln. It doesn't help the general case :( you can define: auto mixinter(string x)(){return mixin(interp!x);} (in the same scope as the vars used inside x) And use: string text = mixinter!"${name} and this are app ${age*365*24} hours!"; But can someone explain me why this works: import scriptlike; void main() { auto name = userInput!string("Please enter your name"); auto age = userInput!int("And your age"); // The proposed notation for scriplike string interpolation writeln(mixin(interp!"${name} you are app. ${age*365} days old")); // with exho definition auto exho(string x)(){return mixin("writeln("~interp!x~")");} exho!"${name} and this are app ${age*365*24} hours!"; } and this not? import scriptlike; // with exho definition outside the scope of the used vars auto exho(string x)(){return mixin("writeln("~interp!x~")");} void main() { auto name = userInput!string("Please enter your name"); auto age = userInput!int("And your age"); writeln(mixin(interp!"${name} you are app. ${age*365} days old")); exho!"${name} and this are app ${age*365*24} hours!"; } Can it be possible to allow a function to be defined outside the scope of use to return a "mixin object"?, than everything can be done in a lib outside, no need to add parsing complexity to the language?
Re: Interpolated strings
I forgot to mention - the pros and cons of whether the string interpolation is compile time or run time is a critical decision.
Re: Interpolated strings
On 4/19/2017 5:04 AM, Jonas Drewsen wrote: 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 :) I can't promise anything. But it does need a lot of work. A survey of how it is done in other languages is helpful to see what they find useful and to see what has been overlooked. A quick look by me shows a lot of variety. D's lambda syntax came about after such a survey, and we cherry-picked the best characteristics of the lot. The result was a nice home run for D. The n.g. discussion also brought up a couple of existing library solutions. Those need to be evaluated as well and compared with any language solution.
Re: Interpolated strings
On Wed, Apr 19, 2017 at 06:38:13PM +, Patrick Schluter via Digitalmars-d wrote: [...] > As a string interpolation sceptic I have to admit that I found one > application of that concept that is probably much better than the > current C derived format strings: Internationalisation. > > dates["en"] = "The date is %2$02d-%1$02d-%3$04d"; > dates["fr"] = "La date est %1$02d-%2$02d-%3$04d"; > > writeln(format(dates[lan], day, month, year)); > > with interpolation we have > > dates["en"] = $"The date is {month:%02d}-{day:02d}-{year:04d}"; > dates["fr"] = $"La date est {day:%02d}/{month:%02d}/{year:04d}"; > > which is a little bit easier to read than positional format specifiers, Somebody proposed some years ago to add named parameter support to format strings (if not to D itself). So ostensibly, instead of writing the nastiness like the above "La date est %1$02d...", you'd be able to write something like: dates["en"] = "The date is %{month}02d-%{day}02d-%{year}04d"; dates["fr"] = "La date est %{day}02d-%{month}02d-%{year}04d"; writefln(dates[lan], [ "day": day, "month": month, "year": year]); > which have the added backdraw (at least in C, I don't know for D) that > they are an none or ALL thing. When you need them, you have to put > them an all format specifiers. I think std.format.format actually allows you to mix positional and non-positional specifiers in the same format string. But the semantics have some tricky bits, though, so I wouldn't recommend doing it. > This said, the interpolation has in that case a big drawback, i.e. > that they "export" the variable names outside of the scope they are > defined in. That's a thing that is often required for I10N, that the > strings are defined in a separate file or module and selectively > imported (at runtime). With named parameter support in format strings, we wouldn't have this problem, since you could name the parameters however you want regardless of actual variable names. You could even perform arbitrary computations on the variables before passing it to format, e.g.: writefln("The date is %{year}04d-%{month}02d-%{day}02d", [ "year": yearsSinceEpoch + 1970, "month": zeroBasedMonth + 1, "day": zeroBasedDay + 1 ]); This way, implementation details like zero-based counting, years since the Unix Epoch, etc., are kept within the code where it belongs, not in the i18n strings. I'd argue that interpolated strings have a disadvantage here, because you wouldn't want to expose the computation `yearsSinceEpoch + 1970` to the l10n translators, who may inadvertently modify the expression to something wrong. Plus, allowing arbitrary (Turing-complete!) expressions inside l10n strings is just a security exploit waiting to happen. T -- Bare foot: (n.) A device for locating thumb tacks on the floor.
Re: Interpolated strings
On Wednesday, 19 April 2017 at 13:04:08 UTC, Jonathan Marler 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: 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*. As a string interpolation sceptic I have to admit that I found one application of that concept that is probably much better than the current C derived format strings: Internationalisation. dates["en"] = "The date is %2$02d-%1$02d-%3$04d"; dates["fr"] = "La date est %1$02d-%2$02d-%3$04d"; writeln(format(dates[lan], day, month, year)); with interpolation we have dates["en"] = $"The date is {month:%02d}-{day:02d}-{year:04d}"; dates["fr"] = $"La date est {day:%02d}/{month:%02d}/{year:04d}"; which is a little bit easier to read than positional format specifiers, which have the added backdraw (at least in C, I don't know for D) that they are an none or ALL thing. When you need them, you have to put them an all format specifiers. This said, the interpolation has in that case a big drawback, i.e. that they "export" the variable names outside of the scope they are defined in. That's a thing that is often required for I10N, that the strings are defined in a separate file or module and selectively imported (at runtime).
Re: Interpolated strings
On Tue, Apr 18, 2017 at 05:30:31PM -0700, Walter Bright via Digitalmars-d wrote: [...] > Reminds me of a story from the 1980s. Microsoft's MASM stood for > "Macro Assembler". Inevitably, Microsoft programmers invented a pile > of macros that sort of turned asm programming into a pseudo-high-level > language. This was shipped with every copy of MASM. > > A friend of mine who worked at MS was once given the task of fixing a > bug in 50K of MASM code written in this macro language. The author of > it had long since moved on. Every coder assigned to this task failed. > My friend got it fixed in a couple hours. He was asked by his > astonished manager how he'd managed to do it: > > "I assembled the code into an object file. Then I disassembled it with > Zortech's OBJ2ASM, figured out how to fix it, then submitted the > disassembled code as the new source code." +1, Classic! T -- VI = Visual Irritation
Re: Interpolated strings
On Wednesday, 19 April 2017 at 15:07:55 UTC, Jonas Drewsen wrote: 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). If we had language-level tuple literals you could desugar the expression into: ("The date is %04d and %s just logged into %s", year, user, here) And let a user do whatever they want with it. Even now it can be done with an AliasSeq, but not with the automatic insertion of format arguments, of course. alias fs = AliasSeq!("The date is %04d and %s just logged into %s", 1992, "Alan", "10.1.0.123"); writeln(format(fs)); //Prints "The date is 1992 and Alan just logged into 10.1.0.123"
Re: Interpolated strings
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 :(
Re: Interpolated strings
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?
Re: Interpolated strings
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.
Re: Interpolated strings
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).
Re: Interpolated strings
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.
Re: Interpolated strings
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"
Re: Interpolated strings
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*.
Re: Interpolated strings
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}"
Re: Interpolated strings
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 :)
Re: Interpolated strings
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)); `
Re: Interpolated strings
On Wednesday, 19 April 2017 at 00:08:19 UTC, Walter Bright wrote: On 4/18/2017 2:56 PM, Jonathan Marler wrote: Have you thought about supporting format specifiers as well? I looked at the C# version and it looks like they can specify them using a colon like this: $"{a} in hex is {a:x}" There are additional problems, such as: $"{a} in %s {b}" and positional parameters: $"{a} in {0}" Of course, the easiest solution is to just disallow that stuff. 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.
Re: Interpolated strings
On Wednesday, 19 April 2017 at 00:08:19 UTC, Walter Bright wrote: There are additional problems, such as: $"{a} in %s {b}" % should be escaped: "%s in %%s %s". There would be no use for a single % otherwise. and positional parameters: $"{a} in {0}" That would be literal 0: `"%s in %s", a, 0`. Could be disallowed but maybe not important. Presumably braces would be escaped $"\{ \}" -> "{ }". Also having no {code} block in an interpolated string should be an error. I like the simplicity of the lowering but it doesn't have much advantage over text(a, " in ", b), you still have to import a function. I suppose the advantage is readability for longer strings. Also, there are compile-time tricks to make formatting more efficient with a compile time format string - e.g. format!"%s in %s"(true, null). Here format can know the length of the resulting string. With your lowering format can't receive the format string as a compile-time argument.
Re: Interpolated strings
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. -- /Jacob Carlborg
Re: Interpolated strings
On 2017-04-19 02:30, Walter Bright wrote: I'm not saying you cannot do cool and useful things with AST macros. My position is it encourages absolutely awful code as (usually inexperienced) programmers compete to show how clever their macros are. The language gets balkanized into a collection of dialects that are unrecognizable across user groups. As a compiler dev who gets stuck figuring out users' bug reports, dealing with templates is bad enough (the first thing I do with a bug report is redo it to remove all the templates). I do not want to deal with some custom syntax. If I may pull the "I'm older" card, programmers will find as they gain experience that the AST macros are just not worth it. This disastrous state of affairs has occurred with every language that supports macros. If you want a nauseous example, check out the Boost C preprocessor metaprogramming library. Or C++ expression templates - so cool, and yet so utterly wretched. Reminds me of a story from the 1980s. Microsoft's MASM stood for "Macro Assembler". Inevitably, Microsoft programmers invented a pile of macros that sort of turned asm programming into a pseudo-high-level language. This was shipped with every copy of MASM. A friend of mine who worked at MS was once given the task of fixing a bug in 50K of MASM code written in this macro language. The author of it had long since moved on. Every coder assigned to this task failed. My friend got it fixed in a couple hours. He was asked by his astonished manager how he'd managed to do it: "I assembled the code into an object file. Then I disassembled it with Zortech's OBJ2ASM, figured out how to fix it, then submitted the disassembled code as the new source code." I have a suspension that it's the name "macro" that is the problem here. It leaves a bad taste due to issues with macros in the past. -- /Jacob Carlborg
Re: Interpolated strings
On Monday, 17 April 2017 at 19:41:14 UTC, 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. Thats a pity, so shouldn't we than try to find a way to define a alias like 'shortcut' for something like mixin(compiletime_expresion!var) so we can write just shortcut!var ? Or what about defining a new return type for functions allowing them to return a mixin even if defined in a lib? (Because the code above is allowed but only working if exho is defined in the same scope as the var 'num'.) Regards mt.
Re: Interpolated strings
On Wednesday, 19 April 2017 at 03:49:09 UTC, bpr wrote: I don't think I've ever heard from Common Lisp, Scheme or Clojure programmers that they'd like to remove macros from their respective languages for the reasons you mention. I don't see the disasters there. The Julia folks looked at the Lisp experience and decided to include macros. Lisp AST is minimal. Both Rust and Nim support macros. Scala too. Not long enough for the disaster yet? How many Rust programmers write their own macros? My impression is that Rust macros is a temporary fix because they don't have another meta programming scheme in place. I also believe that Rust macros can break between releases. last resort. But they're very powerful, and sometimes I'm not smart enough to figure out how to do what I want cleanly with less powerful features. Like what? Certainly, term-rewrite-languages are powerful, e.g. the language Pure: https://en.wikipedia.org/wiki/Pure_(programming_language) But I don't quite see it as an important feature for an imperative language with an AST as complex as D and with rather non-uniform semantics. 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").
Re: Interpolated strings
On Wednesday, 19 April 2017 at 00:30:31 UTC, Walter Bright wrote: I'm not saying you cannot do cool and useful things with AST macros. My position is it encourages absolutely awful code as (usually inexperienced) programmers compete to show how clever their macros are. I'd think that that's a problem with community coding standards. The language gets balkanized into a collection of dialects that are unrecognizable across user groups. I'm pretty sure that hasn't happened with every language that supports macros. Even in the case of Scheme, I don't think it's the macros that are responsible for all of the dialects. It's the fact that the core language never includes enough (no records, exceptions, modules, ...) so every group adds their own versions of these features. Maybe if macros didn't make that easier then Schemers would have added those things to the core, but that's a counterfactual that I don't find convincing. As a compiler dev who gets stuck figuring out users' bug reports, dealing with templates is bad enough (the first thing I do with a bug report is redo it to remove all the templates). I do not want to deal with some custom syntax. If I may pull the "I'm older" card, programmers will find as they gain experience that the AST macros are just not worth it. Some programmers will not find that. Others will find that other features you value are just not worth it. There are absolutely no categorical statements. :-) This disastrous state of affairs has occurred with every language that supports macros. I don't think I've ever heard from Common Lisp, Scheme or Clojure programmers that they'd like to remove macros from their respective languages for the reasons you mention. I don't see the disasters there. The Julia folks looked at the Lisp experience and decided to include macros. Both Rust and Nim support macros. Scala too. Not long enough for the disaster yet? It's certainly not all roses, and writing and debugging macros can be a PITA. I try to avoid them, and consider them a tool of last resort. But they're very powerful, and sometimes I'm not smart enough to figure out how to do what I want cleanly with less powerful features. If you want a nauseous example, check out the Boost C preprocessor metaprogramming library. Or C++ expression templates - so cool, and yet so utterly wretched. Have you checked out examples of macros that are not so nauseating? I find Nim decent, and of course the Lisps have a long history of macrology. I think you're drawing a view of macros from cpp, and MASM, and such, and not so much from the Lisp family, or Nim. cpp macrology is very different! D is interesting to me mostly because of it's powerful templates and CTFE. It seems a shame (to me, obviously) that such a powerful static metaprogramming feature as macros will not be a part of D, but it's your language!
Re: Interpolated strings
On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen wrote: I've been wanting to have support for interpolated strings in D for some time now that will allow you to write e.g.: [...] One place I'd appreciate interpolated strings is as an option when working with heredoc strings. These strings are often multiple lines or paragraphs, using format style construction is often error-prone due to length. --Jon
Re: Interpolated strings
On 4/18/2017 4:58 PM, bpr wrote: Here's how it's done in Nim, a statically typed language similar to D, but with Python syntax, and macros. It takes some knowledge to understand, sure, macros are not a beginner tool, but wouldn't say this is extremely complex. I bet a D-with-macros would have a similar complexity solution. I'm not saying you cannot do cool and useful things with AST macros. My position is it encourages absolutely awful code as (usually inexperienced) programmers compete to show how clever their macros are. The language gets balkanized into a collection of dialects that are unrecognizable across user groups. As a compiler dev who gets stuck figuring out users' bug reports, dealing with templates is bad enough (the first thing I do with a bug report is redo it to remove all the templates). I do not want to deal with some custom syntax. If I may pull the "I'm older" card, programmers will find as they gain experience that the AST macros are just not worth it. This disastrous state of affairs has occurred with every language that supports macros. If you want a nauseous example, check out the Boost C preprocessor metaprogramming library. Or C++ expression templates - so cool, and yet so utterly wretched. Reminds me of a story from the 1980s. Microsoft's MASM stood for "Macro Assembler". Inevitably, Microsoft programmers invented a pile of macros that sort of turned asm programming into a pseudo-high-level language. This was shipped with every copy of MASM. A friend of mine who worked at MS was once given the task of fixing a bug in 50K of MASM code written in this macro language. The author of it had long since moved on. Every coder assigned to this task failed. My friend got it fixed in a couple hours. He was asked by his astonished manager how he'd managed to do it: "I assembled the code into an object file. Then I disassembled it with Zortech's OBJ2ASM, figured out how to fix it, then submitted the disassembled code as the new source code."
Re: Interpolated strings
On 4/18/2017 2:56 PM, Jonathan Marler wrote: Have you thought about supporting format specifiers as well? I looked at the C# version and it looks like they can specify them using a colon like this: $"{a} in hex is {a:x}" There are additional problems, such as: $"{a} in %s {b}" and positional parameters: $"{a} in {0}" Of course, the easiest solution is to just disallow that stuff.
Re: Interpolated strings
On Tuesday, 18 April 2017 at 08:01:14 UTC, Jacob Carlborg wrote: On 2017-04-18 08:59, Stefan Koch wrote: The corresponding ast-macros would be extremely complex No, it's not that complex. Here's how it's done in Nim, a statically typed language similar to D, but with Python syntax, and macros. It takes some knowledge to understand, sure, macros are not a beginner tool, but wouldn't say this is extremely complex. I bet a D-with-macros would have a similar complexity solution. -- string_interpolation.nim -- import macros, parseutils, sequtils macro exho(text: string{lit}): untyped = var nodes: seq[NimNode] = @[] # Parse string literal into "stuff". for k, v in text.strVal.interpolatedFragments: if k == ikStr or k == ikDollar: nodes.add(newLit(v)) else: nodes.add(parseExpr("$(" & v & ")")) # Fold individual nodes into a statement list. result = newNimNode(nnkStmtList).add( foldr(nodes, a.infix("&", b))) const multiplier = 3.14 message = exho"$multiplier times 2.5 is ${multiplier * 2.5}" foo = "foo" message2 = exho"$foo 3 times is ${foo & foo & foo}" echo message echo message2 Running gives 3.14 times 2.5 is 7.851 foo 3 times is foofoofoo
Re: Interpolated strings
On 2017-04-18 23:56, Jonathan Marler wrote: I've thought about it and decided, I like this idea. I've only used interpolated strings in PHP which left a bad taste, but I realized that interpolating strings makes it impossible for your format string and your arguments to get out of sync. This makes interpolated strings harder to use incorrectly (Scott Meyers had a good talk on this, https://www.youtube.com/watch?v=5tg1ONG18H8). ++ (ps. named arguments ;)
Re: Interpolated strings
On Tue, Apr 18, 2017 at 09:56:28PM +, Jonathan Marler via Digitalmars-d wrote: [...] > I've thought about it and decided, I like this idea. I've only used > interpolated strings in PHP which left a bad taste, but I realized > that interpolating strings makes it impossible for your format string > and your arguments to get out of sync. This makes interpolated strings > harder to use incorrectly (Scott Meyers had a good talk on this, > https://www.youtube.com/watch?v=5tg1ONG18H8). [...] Phobos git HEAD now supports compile-time format strings of the form: writefln!"My %s value is %d."("field", 123); If your arguments are out of sync with the format string, this will abort with a compilation error. So you won't end up in the situation where the format string or arguments are wrong but you only find out when it throws a runtime exception. Or worse, in the C situation where mismatched format string / arguments can lead to stack overruns and security exploits. (Though C compilers have been hacked to check this and issue warnings. But that's veering offtopic.) Having said that, though, there is still one problem where you can still get into trouble: writefln!"The date is %04d-%02d-%02d"(month, year, day); It may not be immediately obvious that month and year have been transposed (presumably by mistake), because the %d specifier happens to work with both argument orderings. Whereas in an interpolated string, it becomes painfully obvious: // Using OP's tentative proposed syntax writeln($"The date is {month}-{year}-{day}"); //^^ mistake is obvious here This problem may be especially prominent in D because we're used to writing %s as a general specifier that works for any argument type. T -- Long, long ago, the ancient Chinese invented a device that lets them see through walls. It was called the "window".
Re: Interpolated strings
On Tuesday, 18 April 2017 at 08:50:07 UTC, Walter Bright wrote: 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. I've thought about it and decided, I like this idea. I've only used interpolated strings in PHP which left a bad taste, but I realized that interpolating strings makes it impossible for your format string and your arguments to get out of sync. This makes interpolated strings harder to use incorrectly (Scott Meyers had a good talk on this, https://www.youtube.com/watch?v=5tg1ONG18H8). The biggest drawback I could think of was overhead, but with an implementation like this there is NO RUNTIME OVERHEAD! It's also simple (easy to implement and understand) and flexible (works with all existing functions that accept "format-like" arguments). Have you thought about supporting format specifiers as well? I looked at the C# version and it looks like they can specify them using a colon like this: $"{a} in hex is {a:x}" However this may create an ambiguity in the grammar, not sure. I'm not sure what kind of expression would be supported in the braces. If the expression supported labels then this would definitely cause ambiguity. In the example "{a:x}", the symbol "a" could just be parsed as a label.
Re: Interpolated strings
On Tuesday, 18 April 2017 at 08:50:07 UTC, Walter Bright wrote: 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. For, say, sql query generator it would be nice to have a rewrite like sql!"select name from users where id={n}" => auto q=query("select name from users where id=@p0"); q.addParameter("p0",n); pragma(autoMixin) template sql(string txt) { enum string sql=generateCode(txt); } If this can be rewritten as automatic string mixin like so: sql!"select name from users where id={n}" => mixin(sql!"select name from users where id={n}")
Re: Interpolated strings
On 2017-04-18 10:50, Walter Bright wrote: 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. Then you would be forced to wrap it in a function call, to "format" or similar. The example of using "writeln" is not the best, a more useful example is when not printing the string immediately. For example: auto s = $"{a} times 3 is {a*3}"; With your example that would need to be written as: import std.format; auto s = format($"{a} times 3 is {a*3}"); -- /Jacob Carlborg
Re: Interpolated strings
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.
Re: Interpolated strings
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.
Re: Interpolated strings
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
Re: Interpolated strings
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.
Re: Interpolated strings
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
Re: Interpolated strings
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.
Re: Interpolated strings
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.
Re: Interpolated strings
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.
Re: Interpolated strings
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.
Re: Interpolated strings
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.
Re: Interpolated strings
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
Re: Interpolated strings
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.
Re: Interpolated strings
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.
Re: Interpolated strings
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
Re: Interpolated strings
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.
Re: Interpolated strings
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
Re: Interpolated strings
On Sat, 2017-04-15 at 21:48 +, cym13 via Digitalmars-d wrote: > […] > 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. Python now has string interpolation, f-strings. -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: Interpolated strings
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
Re: Interpolated strings
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?
Re: Interpolated strings
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).
Re: Interpolated strings
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.
Re: Interpolated strings
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.
Re: Interpolated strings
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.
Re: Interpolated strings
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.
Re: Interpolated strings
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 I shared my thoughts on such a feature just a couple weeks ago: https://forum.dlang.org/post/oedeijdewmhazaqaz...@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.
Re: Interpolated strings
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.
Re: Interpolated strings
On Saturday, 15 April 2017 at 20:04:13 UTC, Jonas Drewsen wrote: Hi all I shared my thoughts on such a feature just a couple weeks ago: https://forum.dlang.org/post/oedeijdewmhazaqaz...@forum.dlang.org
Re: Interpolated strings
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.
Re: Interpolated strings
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.
Re: Interpolated strings
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.
Re: Interpolated strings
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 $"".
Re: Interpolated strings
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}";
Re: Interpolated strings
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.