DIP 1027--String Interpolation--Final Review Discussion Thread
Adam D. Ruppe
destructionator at gmail.com
Wed Feb 5 16:04:07 UTC 2020
On Wednesday, 5 February 2020 at 15:20:56 UTC, Steven
Schveighoffer wrote:
> 0. You have missed one edit:
thx, I'll come back to it later.
> 1. I hate that this doesn't work:
>
> alias toFormatString!null this
Yeah, I assumed it would because an eponymous template to an enum
string does work. But then you lose the ability to detect the new
type (maybe if we had typedef LOL).
But it doesn't... and you know that createWindow one actually
really gets to me. I think that is likely to be a big problem
with unintentional interactions confusing people. And, of course,
other people's concerns about implicit GC contextual allocations
are fair too.
However, I agree it is likely a bug. That said... this is one of
those trade-offs that could go either way anyway.
Of course, it is purely in the library which in theory can be
tweaked more easily in the future.
> 2. I disagree that you shouldn't be able to do
> writefln(i"someint : $someint")
>
> But your CreateWindow example is also pretty compelling.
Yeah, this is back to the both-sides-have-merit trade-off. I
could probably go either way - we could default to permissive and
handle more cleanly with another lib overload too (which we also
talked about earlier in this thread). Or restrictive with helper
functions as I'll get into next.
> It would be nice to make "send the first parameter as a string"
> opt-in. Is there a way we can do that without requiring
> overloads?
I can't think of a perfect way. Can't use a helper template on
params (call(help!i"xx")) since that triggers "variable X is not
available at compile time", and can't do a helper UFCS function
(call(i"xx").help) since they cannot return a tuple.
We could do `help!call(i"..")` though... opt-in at the call site
on the function, not the args. (I'm using "help" cuz i can't
think of a name right now but meh). So basically a template that
makes a new overload right there.
callWithFirstAsString!writefln(i"...");
and the implementation is
auto help(alias fn, T...)(T t) {
return fn(t[0].toFormatString!"%s", t[1 .. $]);
}
so that's easy enough. And of course you could provide other
customization arguments in there like a different default
formatter etc. So that could be our hook into existing functions.
And of course that could be done for printf too instead of alias
const char* this, but then we're talking an import so... again
not perfect but plenty of good enough library options we can talk
about or even develop independently once we get the core language
rewrite in place.
Interestingly a printf one could inspeect the types of t[1..$] to
change the default specifier, e.g. if(is(typeof(t) == int) fmt ~=
"%d" else static assert(0) and so on. So it could actually work
quite nicely. Of course do that as a ctfe to enum so it isn't GC
at runtime. (or failing that use a stack buffer.)
It just needs that help!printf instead of printf. Which we can
debate. (I actually would prefer to go that way but I'm trying to
maintain Walter's printf desire too.)
But lots of options. With zero changes to dmd itself once we get
this change.
> 3. I'm also not sold on the "if they provided a format
> specifier, they know it returns a tuple" logic. Plenty of
> existing string interpolation libraries provide ways to format
> the parameters into strings, and still can be used as strings.
Yeah, I just figure if the user is specifying all the strings it
means they must have at least thought about the format of those
specifiers. They might be doing it for other purposes or just be
wrong, but eh.
Note the only change that did is enable `alias this` conversions;
you can still ignore it and use the other facilities.
> Note that C# does something pretty cool [1] (as I just looked
> it up to see what other interpolation libraries do)
Indeed, not bad. It looks like C# is similar to my old proposal,
creating an object :) Then we could implicitly convert to a
single string with `alias toString this` or use the specialized
type. but of course i think this tuple is a wee bit better since
it lets us keep `ref` and `alias`. Might also be relevant with
other storage classes like `scope`, `return`, etc. So that's the
trade off there (with current D at least).
I could go either way, but like I said in my other message with
the list, I think the tuple's potential is indeed worth
sacrificing the object's convenience (but idup and other
functions 95% make up for that anyway!).
> Inspired by that C# type, maybe "formattable tuple" is a good
> description.
that would work.
More information about the Digitalmars-d
mailing list