DIP 1027---String Interpolation---Community Review Round 1
jab_293 at gmall.com
Tue Dec 17 05:37:53 UTC 2019
On Monday, 16 December 2019 at 22:48:30 UTC, mipri wrote:
> Those other languages also have some severe problems owing to
> how they do string interpolation:
> 1. a universe of SQL injection and similar exploits, as it's
> easy and convenient to build strings with interpolation even
> though the underlying database APIs can accept arguments
> separately and safely, with no need for ad-hoc 'sanitization'.
> Well-written database code in these languages is therefore
> written as if string interpolation is not a feature of the
> $db->query("INSERT INTO names VALUES (?)", "Bob");
This would push the complexity onto the query implementation. As
now it has to be able to parse the string.
> 2. internationalization is defeated, as the structure of the
> string that variables are interpolated into is lost. Invariably
> as programs get international their developers have to comb
> through the code base and remove uses of string interpolation:
> print("Hello, $name!");
> # is corrected to:
> printf(gettext("Hello, %s!"), name);
This would usually be a warning/error in C/C++ compilers as you
aren't using a constant string for the format. It's a runtime
variable and can't be checked by the compiler or at runtime so
it's a security risk. D can do better due to varidic templates,
but you are using printf and D doesn't have as robust
warning/errors as some C/C++ compilers.
Ultimately this doesn't really help with localization either.
What if you need to change the order? Languages have different
ways of formatting. Maybe not the best example, but say you have
"$year-$month-$day", but in a different location it is more
common to do "$month-$day-$year". The gettext() can't do anything
about that, cause it'll always have to be "%d-%d-%d", it can't
rearrange the order.
> where gettext() might look up "Hello, %s" in a
> translator-maintained table of greetings, to substitute
> "Bonjour, %s".
> In D, string interpolation is convenient for the simplest
> tasks, and D is unusual in that string interpolation *remains*
> convenient as tasks get more serious.
> This comes at the small cost of having to pass an interpolated
> string to a string-building function, like std.format's format,
> if that's what you want.
> string s1 = i"Hello, $name!"; // error
> string s2 = i"Hello, $name!".format; // this is fine
> string s3 = format("Hello, %s!", name); // without i""
> Even if the intended purpose is working with C-style printf()
> functions, I'd highlight this use of i"" in a C interface or
> BetterC section.
What happens if you want to implement your own type and pass it
in? The DIP doesn't mention it at all. If you do what to do that
it won't work with printf anymore. Unless you forcibly require
some .toString() method for types that aren't supported. But even
then that information about what type it was is then lost. It
could have been passed with the type information and the caller
could decide what to do with the extra information. Rather than
requiring it to be forced into a string and potentially losing
relevant information if it was otherwise passed to the function
as a tuple.
More information about the Digitalmars-d