Feedback Thread: DIP 1036--String Interpolation Tuple Literals--Community Review Round 2
Q. Schroll
qs.il.paperinik at gmail.com
Wed Feb 3 17:47:19 UTC 2021
On Wednesday, 27 January 2021 at 10:33:53 UTC, Mike Parker wrote:
> * All posts must be a direct reply to the DIP manager's initial
> post, with only two exceptions:
A problem I see is that i"..." becomes an interp sequence too
easily.
D's templates have a low entrance barrier and passing an
interpolated string to a variadic function template is something
not too outlandish to do. Then, the by the current form of the
proposal, the interpolated becomes an `interp` sequence. This may
be completely unexpected as most variadic function templates
won't be written with an interp sequence in mind at all.
Imagine someone (especially a newcommer from e.g. C#) naively
using
auto tup = tuple(1, i"I'm ${name}.", 2.3)
expecting Tuple!(int, string, double). First, tup.length != 3 and
its content are wild.
Basically, an interpolated string should be a string, except in
very specific circumstances; variadic templates aren't even close
to being a very specific circumstance.
The typing is better done akin to slices vs static arrays.
As a reminder, to a newcomer,
auto xs = [ 1, 2, 3 ];
looks like it would infer int[3] as the type of xs. It is
obviously the most descriptive type for that literal. Why would
it infer int[] forgetting its compile-time known length and even
do an allocation? That seems so much worse. At least, for
consistency, typeof([1,2,3]) is int[], too, and not int[3]. We
know why D does it the way it does, and why it uses int[3] with
no allocation only when requested explicitly. You can do that
with a template with a flexible length like this:
void takesStaticArray(T, size_t n)(T[n] staticArray);
Here, `T` and `n` can usually be inferred from the argument:
takesStaticArray([1, 2, 3]);
won't allocate.
Interpolated strings should behave similarly:
1. typeof(i"...") is `string`.
2. auto str = i"..." infers string (cf. typeof) and gc-allocates
if necessary.
3. i"..." has a secondary type akin to [1,2,3] having int[3] as a
secondary type. (The secondary type is a sequence, but that's a
detail.)
If an interpolated string is bound to a parameter of that
secondary type (`interp` in the DIP) it uses its secondary type
(cf. calling takesStaticArray with [1,2,3]). In any other case,
e.g. `auto` or otherwise generic template parameters will infer
string.
My suggestion is that one cannot do this:
ResultSeq mysql_query(Args...)(Args args) if (Args.length > 0
&& isInstanceOf!(interp, Args[0])) { ... }
because Args... is too unspecific to force i"..." to become an
interp sequence. Therefore
auto rseq = mysql_query(i"...");
results in mysql_query!string and then fails the constraint. You
have to request an interp sequence explicitly like this
ResultSeq mysql_query(string first, Args...)(interp!first arg,
Args args)
to force the secondary type. This is akin to
takesStaticArray(size_t n, T)(T[n]). Since it cannot bind an int[]
However, if you already have an interp!"..." object in hand, of
course passing it to a template will use its static type
interp!"..." (and not string), like an int[3] variable will, too.
This is fine, because at this point, you know what you're dealing
with and that it is not a string.
Akin to `staticArray`, Phobos can (should) supply a template
`asInterp` that forces a i"..." literal to be statically typed as
a tuple around the respective `interp` sequence.
auto asInterp(string str, Args...)(interp!str first, Args
rest)
{
import std.typecons : tuple;
return tuple(first, rest);
}
Function templates handling interpolated strings can either
provide an overload taking a tuple containing an interp!"..." as
its first entry (likely result of asInterp) or require the user
to use `expand` on the tuple.
Example: https://run.dlang.io/is/h5LgF4
Getting a string is probably what most users expect most of the
time, even in templates. Handling the secondary type must be
explicit. It is almost an implementation detail that shouldn't be
exposed to the user too easily.
More information about the Digitalmars-d
mailing list