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