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