Strings and things
Brian Goetz
brian.goetz at oracle.com
Thu Sep 16 18:10:20 UTC 2021
> I do note a certain vagueness
> in the document about exactly how the method on Connection or
> ResourceBundle is defined (as the document stands, it looks like each
> class can have only one associated mechanism of accepting a
> TemplatedString).
The vagueness is deliberate, because the goal is not to design those
APIs here, but rather, to ensure that those API designers have
sufficient latitude to do what they need. Since template processing is
just an interface, those API designers have some flexibility; it could
be that Connection implements TemplatePolicy, or if it wants to expose
multiple such policies, can have methods that return values that
implement different policies, such as having both statement() and
preparedStatement() return different TemplatePolicy objects. Note too
that APIs have other choices too: they can expose methods that accept
unprocessed templates:
void logDebug(TemplatedString ts)
(which can even be overloaded against String-accepting methods) which
allow the library to defer not only the timing but also the choice of
policy. Again, though, the main discussion here is "do libraries have
the flexibility they need to do good things", rather than to design any
specific library.
> I believe however that there is a missing element - pre-processing at
> compile-time.
This could mean a few different things, so let me respond to the two
most obvious interpretations. The last section of Jim's document,
Translation, hints at reducing the number of invocations; that in many
cases, substantial pre-processing of the template string has to be done
by a processor, and when the template string is a constant, it is not
ideal to do this redundantly. (Much of the overhead of String::format
comes from parsing the string repeatedly.) We have spent a lot of time
considering the various translation issues, and doing so efficiently is
an important goal (we intend to address this with indy), but I'd like to
focus on the user model first, and the low-level details after the user
model has gained broader consensus.
The other interpretation is that you are asking for a way to let the
library plug into the parser (the lexer, actually!) so that you're not
stuck with the language's notion of "string with holes." This is a hard
no; while I realize how attractive it might seem to be able to control
the grammar with libraries, that's in an entire different universe of
complexity, risk, magnitude, and, frankly, advisability. So this is a
"way, way out of scope".
> If the premise of pre-processing is accepted, it is only a relatively
> small additional step to user-defined literals. Ultimately, the only
> real difference is that a typical user-defined literal doesn't have
> the concept of "holes".
We anticipated that it might be frustrating to realize that this is a
feature that almost seems vaguely maybe adjacent if you squint to
user-defined literals, but that's not remotely the design center here.
If we're going to go there, we're going to go there more directly (and
still in more constrained ways than you'd probably like.) I suspect
there will be a certain amount of overuse and abuse of templates at
first; the best we can do is provide guidance of "sure its legal, but
that's not the goal here, and the roadblocks you're about to run into
are not omissions."
> Thus, my feedback is to question whether restricting the mechanism of
> parsing the holes to the compiler is the right choice.
I see no practical flexibility here for supporting user control over
lexing rules. It's a different feature, and I think one that is simply
not on the table in the forseeable future.
More information about the amber-dev
mailing list