DIP 1027--String Interpolation--Final Review Discussion Thread
Arine
arine123445128843 at gmail.com
Mon Feb 3 02:57:41 UTC 2020
On Sunday, 2 February 2020 at 23:54:35 UTC, Adam D. Ruppe wrote:
> Do those two small changes and this DIP will have my support.
>
> * specify that % in the user string gets translated to %% in
> the format literal
> * put the format literal in a wrapper type.
>
> i"$foo %"
>
> is translated to the tuple:
>
> __d_format_literal!("%s %%"), foo
>
>
> struct __d_format_literal(string fmt) {
> enum f = fmt;
> alias f this;
> }
>
> That implicitly converts and just works in printf. That's the
> answer.
I don't think you should compromise. Using printf as the basis
just limits what can be done with an interpolated string. How do
you handle custom types?
The DIP doesn't go over this but it'd have to either disallow it
completely. Or convert it to a string first using `.toString()`,
or similar. Since printf() wouldn't be able to take a custom
type. This inhibits any sort of user implementation or
customization and forces the type to be converted to a string
first, losing any additional detail and preventing possible
optimizations in only allocating one buffer for the entire thing.
For each object toString() would allocate it's own buffer, when
it could be constructed in place.
SqlValue value;
ExecuteSettings settings;
execute(settings, i"SELECT * FROM table WHERE value=$value");
void execute(InterpolatedString)(ref ExecuteSettings
settings, InterpolatedString str) {
string output;
// static foreach(i; str.args) {
// static if(is(typeof(str.args[i]) == SqlValue)) {
// ...
// typeof(str.args[i]) == SqlValue
if( str.args[i].someProperty && settings.someSetting ) {
// ...
}
str.args[i].emplaceToString(output); // or otherwise
}
printf(i"something $value".c); // ok, "c" would call
toString() to make it compatible
printf(i"something $value"); // or with overload for printf()
Compared to how'd you have to implement it with the current DIP:
// this implementation can be used with printf
void execute(Args...)(ref ExecuteSettings settings, string
format, Args args) {
// typeof(args[0]) == string, can't determine what type
it was
// more difficult to parse format and verify it is valid
// can't access SqlValue for properties as it is now just
a string
}
printf(i"something $value"); // works, calls toString first
Or to retain the type, it would then not work with printf().
void execute(Args...)(ref ExecuteSettings settings, string
format, Args args) {
// typeof(args[0]) == SqlValue
// what specifier was inserted into format? %s?
// what if we know we can check now and instead use %d?
// now we have to be able to parse printf-style formats
properly to change
// the formatting to be more efficient and make more sense
//
// also can't do in place optimizations without
completely re-implementing
// sprintf or otherwise support all of printf format
capabilities
}
printf(i"something $value"); // error, passing SqlValue
printf(i"something $value.toString()"); // ok, but kind of
counter intuitive
Trying to cator to printf results in an implementation with the
least amount of flexibility imo. It forces legacy debt onto the
user to support. It will ultimately just be left to the handful
of functions that use it now.
More information about the Digitalmars-d
mailing list