The state of string interpolation
Neia Neutuladh
neia at ikeran.org
Thu Dec 6 02:14:12 UTC 2018
On Thu, 06 Dec 2018 00:10:56 +0000, o wrote:
> And please don't mention Phobos' sorry excuse for string interpolation:
> "a is: %s, b is: %s, sum is %s.".format(a, b, a + b)
> Is no better than "a is: "~a.to!string~"b is: "~b.to!string~" and the
> sum is: "~(a+b).to!string~"."
I mean, let's not be hyperbolic. Or contemptuous. format() is a lot more
readable than a bunch of concatenation for a lot of things. It gives you a
coherent view of the structure of the string as a whole. As a tradeoff,
it's harder to see the relationship between the format specifiers and the
parameters.
String interpolation gets rid of that tradeoff.
However, that would also force druntime to include formatting code that it
currently lacks. It's very likely that this would have some
inconsistencies with std.conv. Like, the most straightforward way to make
this work is to have a runtime function taking variadic arguments:
string _d_stringinterpc(...);
wstring _d_stringinterpw(...);
dstring _d_stringinterpd(...);
That would allow a pluggable approach, which allows for the maximum amount
of compatibility.
So you write:
auto bar = "hello world".lazyReplace('l', 'p');
writeln("foo ${bar}");
This compiles down to:
writeln(_d_stringinterpc("foo ", bar));
And it prints:
foo scratch.LazyReplacementRange!(immutable(char),
string).LazyReplacementRange
lazyReplace returns a LazyReplacementRange, which doesn't define
toString(). Its corresponding TypeInfo_Struct doesn't have a xtoString
function pointer set, so we can't convert it to a string by
calling .toString() on it (even indirectly through reflection). We can't
list its properties and fields at runtime, so we can't iterate through it
like std.format would. We can't even assemble a toString() that looks like
the default for structs in std.conv.
The only thing we have available is the name of the type.
In 2007, this would have worked.
----
Okay, it's bad to use that sort of runtime function. What about putting a
template inside object.d?
That would require us to put std.conv and std.format into object.d. It
wouldn't be even remotely pluggable.
This isn't an issue in most languages. Most languages tie their standard
libraries to their compilers. D maintains a greater separation than
normal, in part because of the Tango / Phobos separation.
More information about the Digitalmars-d
mailing list