<html><body><div dir="ltr"><span style="color:var(--quotedTextColor)">On 31 Mar 2023 at 17:37:00, Brian Goetz <<a href="mailto:brian.goetz@oracle.com">brian.goetz@oracle.com</a>> wrote:</span><br></div><div class="gmail_quote">
    <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" type="cite">
        <div><div>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </div>
  <div>The
    examples here are intended to motivate why the design is as it is,
    and illustrate the sort of use cases we have in mind.  <br></div></div></blockquote><div class="gmail_quote"><br></div><div class="gmail_quote" dir="ltr">For the JSON example, it’s just an oversimplification in the example code, but, some sort of callout that the example code is oversimplified so much it’s now insecure is warranted, no? Or just remove the implementation code, given that it isn’t all that illustrative - the example works just fine without it, given that the call-site code is the key part of the example. Just a minor nit.</div><br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" type="cite"><div><div>
    <br>
    <blockquote type="cite">just call `STR.process(st)` instead of
      `st.interpolate()`</blockquote>
    <br>
    Your point here is, I think, that the `interpolate` is an
    "attractive nuisance", and will make it too easy for people to do
    the wrong thing without thinking.  A valid concern, but on the other
    hand, is the extra step going to deter those folks?  <br></div></div></blockquote><div class="gmail_quote"><br></div><div class="gmail_quote" dir="ltr">I think it’ll deter a significant amount. The obvious place to look for ‘how do I String Template Processor’ is, at least in my experience, the same place folks look for just about any other API: The methods directly available on <code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px">StringTemplate</code>. The easy action to take, once someone has decided to write a processor, is to let the IDE generate the required signature, and then auto-complete the available parameters and methods from there. By removing <code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px">interpolate()</code> from that lowest-effort flow, you <i>force</i> someone to go out and look for it, which gives them some time to think and stands at least some chance of highlighting the security implications of <code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px">st.interpolate()</code>/<code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px">STR.process(st)</code>.</div><div class="gmail_quote" dir="ltr"><br></div><div class="gmail_quote" dir="ltr">This is always a very tough discussion: How much should the language design prevent silly mistakes. On one hand, perfection is quite impossible: The universe is far too good at coming up with incompetence, there is no way to stop all foreseeable abuse of an API, and therefore, that cannot be a goal. However, making an API where the obvious way to use it is subtly but dangerously incorrect, is, and surely this requires no debate, bad API design. The trick is figuring out where to draw the line. Especially considering that <code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px">interpolate()</code> can always be added later, but if added, cannot be removed, I recommend <i>not</i> including it in the first release of this API. The javadoc of Processor and/or StringTemplate itself should explain how one can interpolate (by using <code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px">STR.process(st)</code>), with all due warnings about the dangers of doing so.</div><div class="gmail_quote" dir="ltr"><br></div><br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" type="cite"><div><div>
    <br>
    <blockquote type="cite" cite="mid:CAK6PxWMwzGjg0HJ9ym-BnrUDK4Kx6Oj_B355jMqG=GBJ+p1bMg@mail.gmail.com"><br>
      <p style="margin:0px;font-stretch:normal;font-size:12px;line-height:normal;font-family:".AppleSystemUIFontMonospaced"">...
        but while we're here, the entire of method seems pointless.
        After all, Processor is, itself, a functional interface, so we
        can just delete the `StringTemplate.Processor.of()` part of the
        above snippet and it would exactly the same way!</p>
    </blockquote>
    <br>
    This whole section seems an unnecessary detour, and kind of a big
    distraction.  <br></div></div></blockquote><div class="gmail_quote"><br></div><div class="gmail_quote" dir="ltr">I felt it necessary to explain that background in order to get to the recommendation, which is to remove the <code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px"><E extends Throwable></code> and the static <code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px">of()</code> method from ST.Processor. Whilst <code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px">of</code> can always be added later, the choice to include the throwable or not looks like one that java will have to live with once released, whichever choice is made.</div><div class="gmail_quote" dir="ltr"><br></div><div class="gmail_quote" dir="ltr">Adding <code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px"><E extends Throwable></code> here would complicate any attempt to ‘fix’ the checked exceptions+lambdas issue java has in some later java release. Possibly that ship has sailed (enough APIs have added it to their functional interfaces that, if java ever adds something to help with checked-ex-in-lambda, that feature will have to contend with it).</div><div class="gmail_quote" dir="ltr"><br></div><div class="gmail_quote" dir="ltr">The greatest (in my opinion) feat of java 1.5’s generics is that the existing <code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px">java.util.</code> APIs all survived 100% unscathed: Somebody designing the API of <code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px">j.u.ArrayList</code> immediately after the release of generics would come up with the exact same API that ArrayList has today. That’s great, given that AL was designed well before 1.5. Generics thus weren’t just “entirely backwards compatible” in the sense that the term ‘backwards compatible’ is commonly used, but it was even more backwards compatible than that: It was <i>culturally</i> backwards compatible.<br></div><div class="gmail_quote" dir="ltr"><br></div><div class="gmail_quote" dir="ltr">In that sense, records were very slightly non-culture-compatible: <code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px">LocalDate.getYear()</code> now stands out as somewhat weird: <code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px">LocalDate</code> feels like a record (and may one day be a record, certainly it’ll get a deconstructor in the same release of java that introduces that concept formally) - and ‘year’ feels like a property. Nevertheless, unlike records would suggest, the method to retrieve this property is called <code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px">getYear()</code> and not <code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px">year()</code>. This is a very minor nit - there were vastly more important factors to decide between <code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px">getX()</code> and <code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px">x()</code> style getters for records than this.</div><div class="gmail_quote" dir="ltr"><br></div><div class="gmail_quote" dir="ltr">In that sense, it is odd that string processors have checked-exception-as-a-type-var when <code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px">j.u.Function</code> interfaces don’t. Removing it from Processor is the most obvious way to tackle that incongruence.</div><div class="gmail_quote" dir="ltr"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" type="cite"><div><div>Including a "Processor Writer's Guide" here would be out of
    scope, and interfere with the primary role of the JEP.  <br></div></div></blockquote><div class="gmail_quote"><br></div><div class="gmail_quote" dir="ltr">Yes, a full tutorial on how to use the feature is well beyond scope. However, explaining what the JEP does to make something possible that it claims is possible - that should be in scope, and what I’m interested in. Even a simple throwaway line such as:</div><div class="gmail_quote" dir="ltr"><br></div><div class="gmail_quote" dir="ltr">The <code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px">List<String></code> returned by <code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px">fragments()</code> is, per lexical node in the AST, constant, as in, same ref every time. The list of values obviously wouldn’t be.</div><div class="gmail_quote" dir="ltr"><br></div><div class="gmail_quote" dir="ltr">is all that is needed (if indeed that is how string templates are going to work).</div><br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" type="cite"><div><div><br>
    But, I'm having a hard time distilling your actual concern here.  Is
    it that you think the language feature is flawed in that it cannot
    express what you think is the right way to do it, or are you simply
    worried that people will take the examples as blessing of "here's a
    good way to do something in XYZ domain", and blindly follow it?<br></div></div></blockquote><div class="gmail_quote"><br></div><div class="gmail_quote" dir="ltr">The proposal as written would be better if it uses examples that don’t require a bevy of caveats, but whether its worthwhile to spend the time on coming up with better ones - that’s not for me to say. Probably not - that role is better served by separate feedback. As was written at the top, pretty much all of the feedback is more or less at ’nitpick’ level.</div><div class="gmail_quote" dir="ltr"><br></div><div class="gmail_quote" dir="ltr">String templates are great for the JSON use case, that much is clear. I’m pretty sure string templates will be a boon in some form to SQL-in-java, but it’s less clear precisely how much of a boon it will be. It's a common enough usecase, and one rife with the problems this proposal tries to tackle (keeping the intermixing of java expressions and the SQL readable without introducing SQL injection attacks), that ensuring that the proposal as written will be suitable for that particular job is important. If e.g. Lukas Eder (leads the JOOQ project) starts the work on figuring out how JOOQ could be improved with string templates, and reports back - that seems like extremely useful feedback. Trying to figure out how one would go about it in his stead, I got stuck due to the lack of details on how the caching feature works.</div><div class="gmail_quote" dir="ltr"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" type="cite"><div><div><blockquote type="cite" cite="mid:CAK6PxWMwzGjg0HJ9ym-BnrUDK4Kx6Oj_B355jMqG=GBJ+p1bMg@mail.gmail.com"><p style="margin:0px;font-stretch:normal;font-size:12px;line-height:normal;font-family:".AppleSystemUIFontMonospaced""><br>
      </p>
      <p style="margin:0px;font-stretch:normal;font-size:12px;line-height:normal;font-family:".AppleSystemUIFontMonospaced"">##
        Compile time checking</p>
    </blockquote>
    <br>
    Definitely a different topic :)<br><br>
  </div>
</div>

    </blockquote><br>
</div><div class="gmail_quote" dir="ltr">The idea that I can type <code style="border:1px solid rgb(206,206,206);background-color:rgb(244,244,244);padding:0px 2px;border-radius:2px">REGEX.”(foo)+bar”</code> and get compile-time validation of the regex, and perhaps even compile-time construction of a thompson-NFA style tree so that the regex loads and runs faster at runtime (shift some of the ‘work’ to compile-time) is <i>very</i> exciting, though 😉 - I don’t see anything fundamental in the proposed design of string templates that would complicate work on compile-time constants / processing, so perhaps I shouldn’t have raised the point in the first place.</div><div class="gmail_quote" dir="ltr"><br></div><div class="gmail_quote" dir="ltr">— Reinier Zwitserloot</div><div class="gmail_quote" dir="ltr"><br></div><div class="gmail_quote" dir="ltr"><br></div><div class="gmail_quote" dir="ltr"><br></div></body></html>