DIP 1027---String Interpolation---Community Review Round 1

Adam D. Ruppe destructionator at gmail.com
Fri Dec 13 01:30:43 UTC 2019


On Friday, 13 December 2019 at 01:19:32 UTC, mipri wrote:
> This doesn't work though:
>
>   auto n = 4;
>   [1,2,3].map!(format("a + %s", n)).each!writeln;

Indeed, but it does work to pass seq!(() => n). That's why I've 
amended my proposal to do that instead. Then it inherits the 
CT-ness of n while still being usable in a runtime context.

It is similar to `lazy` parameters built into the language;

> So I imagine i"" strings won't be useful in static arguments
> except with static parameters.


auto interpolate(T...)() {
         import std.conv;
         string s;
         foreach(t; T)
                 static if(is(typeof(t) == string))
                         s ~= t;
                 else
                         s ~= to!string(t());
         return s;
}

void main() {
         int n;
         enum n2 = 56;
         // runtime variable works for runtime, but errors if 
`enum s;`
         string s = interpolate!("this works: ", () => n);
         // CT variable works in either cse
         enum e = interpolate!("this works too ", () => n2);
         import std.stdio;
         writeln(s);
         writeln(e);
}



In my original proposal I was just going to use a value, but the 
compiler-generated lambda is more flexible as seen here.

So

i"foo #{a}"

becomes

__DInterpolatedString!("foo ", () => a);

and you can do all kinds of magical things with that. (In my 
original proposal I rejected this hybrid library solution because 
of this very problem, but this little bit of magic allows it. The 
compiler simply rewrites the i"" string into a call to that 
template, then object.d can be responsible for doing the rest.)


If you like I could actually go ahead and write up a library 
implementation and we pretend the syntax lowering is in place to 
evaluate it.


More information about the Digitalmars-d mailing list