On Tuesday, 9 January 2024 at 20:01:34 UTC, Walter Bright wrote:
>With the istring, there are 4 calls to struct member functions that just return null.
This can't be good for performance or program size.
A valid point, thanks. Could you test if that fixes the issue?
import core.interpolation;
import std.meta: AliasSeq, staticMap;
import std.stdio;
template filterOutEmpty(alias arg) {
alias T = typeof(arg);
static if (is(T == InterpolatedLiteral!s, string s))
static if (s.length)
alias filterOutEmpty = s;
else
alias filterOutEmpty = AliasSeq!();
else static if (
is(T == InterpolationHeader) ||
is(T == InterpolatedExpression!code, string code) ||
is(T == InterpolationFooter)
)
alias filterOutEmpty = AliasSeq!();
else
alias filterOutEmpty = arg;
}
pragma(inline, true) // This pragma is necessary unless you compile with `-inline`.
void log(Args...)(InterpolationHeader, Args args, InterpolationFooter) {
writeln(staticMap!(filterOutEmpty, args));
}
void main() {
int baz = 3;
log(i"$(baz + 4)");
writeln(baz + 5);
}
> Adam's implementation of execi() also runs at run time, not compile time.
We are probably talking about different things. Adam’s implementation constructs a format string at compile time thanks to enum
storage class in line 36. Constructing it at compile time is essential so that we can validate the generated SQL and abort compilation, as Paolo demonstrated.
execi could be extended to reject arguments that contain %s sequences.
I disagree. Storing a string that contains %s
in a database should be allowed (storing any string should obviously be allowed, regardless of its contents). But execi
is unable to differentiate between a string that happens to contain %s
and a nested format string:
// DIP1027
example(i"prefix1 $(i"prefix2 $(x) suffix2") suffix1");
// Gets rewritten as:
example("prefix1 %s suffix1", "prefix2 %s suffix2", x);
I might be wrong, but it appears to me that DIP1027 is not able to deal with nested format strings, in a general case. DIP1036 has no such limitation (demonstrated in point 2 here).
>Nor does it need the extra two arguments, which aren't free of cost.
I explained here why these two arguments are valuable. Aren’t free of cost—correct unless you enable inlining. execi
may require some changes (like filterOutEmpty
I showed above) to make them free of cost, but it is doable.
What happens when ?3 is included in a DIP1036 istring? i"string ?3 ($betty)"
? I didn't see any check for that. Of course, one could add such a check to the 1036 execi.
You are right, it doesn’t. Timon’s point (expressed as “This does not work”) is that DIP1036 is able to do validation at compile time while DIP1027 is only able to do it at runtime, when this function actually gets invoked.