<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body><div style="font-family: sans-serif;"><div class="markdown" style="white-space: normal;">
<p dir="auto">Logging is a good use case (but not at all the only one) for this move of “quoting” an expression (for later “unquoting”) with a nullary lambda prefix.</p>
<p dir="auto">I put a discussion about this topic here:<br>
“Java supplier lambda, the Ultimate Quote”<br>
<a href="http://cr.openjdk.java.net/~jrose/jls/eta-abstraction-expr-quoting.html" style="color: #3983C4;">http://cr.openjdk.java.net/~jrose/jls/eta-abstraction-expr-quoting.html</a></p>
<p dir="auto">If we had an “auto-quote” feature (see the appendix of the above doc) logger classes could get the delayed execution as part of their API declarations, in the way that Nathan is apparently envisioning.  But in practice, adding <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">()-></code> before your logger expressions is not a huge burden.  Yeah, you’d want to say <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">LOG."template \{stuff}"</code> instead of <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">log(()->STR.”template \{stuff}”)</code>.  But it’s not so terrible as to motivate (all by itself) sugary elision of the <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">()-></code> quote.</p>
<p dir="auto">For my part, I’m really really glad that string templates did not add a hard-coded feature into their design for this sort of expression quoting.  I think such a feature deserves to be considered on its own, separately for many kinds of APIs, if at all.</p>
<p dir="auto">(Idea of the moment:  Allow the string template processor <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">apply</code> method to accept a <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">Supplier<ST></code>, instead of <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">ST</code>.  Then push an auto-quote rule into the desugaring of <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">LOG.<<ST>></code>, when <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">LOG::apply</code> takes a supplier.  This could be added compatibly to the present design, as a future feature.  Sort of like some proposals to add new rules for enhanced-for over streams, by adjusting the types around the enhanced-for.  String templates could support many, many such compatible additions, IMO, and they should be rolled out in a measured and cautious way, if at all.)</p>
<p dir="auto">On 22 Sep 2022, at 12:13, Brian Goetz wrote:</p>
</div><blockquote class="embedded" style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><div id="A8295FA9-11EB-4B24-86CA-B52D23A6EA52">

We went around on this a few times, and in the end concluded that it is easy to just wrap the whole thing with a lambda:<br>
<br>
    () -> STR."Connection from \{name} at \{time}"<br>
<br>
which is a Supplier<String>.  Lots of logging frameworks already are prepared to deal with Supplier. <br>
<br>
<div class="moz-cite-prefix">On 9/22/2022 3:09 PM, Nathan Walker wrote:<br></div>
<blockquote type="cite" cite="mid:CADM1oTkN2KrO5dsjXNFhrJwNPHmEiYiqMsEG=jdXxtVxwQFO5Q@mail.gmail.com">
<div dir="auto"><span style="word-spacing:1px;color:rgb(49,49,49)">That was all about what I expected.  And it is probably the option that will result in the fewest surprises for developers.  The log example you linked was very interesting.</span><br style="color:rgb(49,49,49);word-spacing:1px">
<br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">Has permitting lambda/method-reference syntax to insert lazy expressions been discussed before?  I would really love to be able to do something like "The time is \{Instant::now}" or "The time is \{()->Instant.now()}"</span><br></div>
<div dir="auto"><br></div>
<div dir="auto"><font style="color:rgb(49,49,49)"><span style="word-spacing:1px">I think there is a lot of potential in allowing TemplateProcessors that elect to skip processing a template for some precondition avoid the overhead of any expensive embedded expressions, and I think this would be especially true in processors that can fail by throwing a checked exception. </span></font></div>
<div dir="auto"><br></div>
<div dir="auto">Thanks,</div>
<div dir="auto">Nathan</div>
<div dir="auto"><br>
<div class="gmail_quote" dir="auto">
<div dir="ltr" class="gmail_attr">On Thu, Sep 22, 2022 at 10:17 AM Jim Laskey <<a href="mailto:james.laskey@oracle.com" moz-do-not-send="true" class="moz-txt-link-freetext">james.laskey@oracle.com</a>> wrote:<br></div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;padding-left:1ex;border-left-color:rgb(204,204,204)">
<div style="word-wrap:break-word;line-break:after-white-space"><br>
<div><br>
<blockquote type="cite">
<div>On Sep 22, 2022, at 11:08 AM, Nathan Walker <<a href="mailto:nathan.h.walker@gmail.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">nathan.h.walker@gmail.com</a>> wrote:</div>
<br>
<div>
<div>
<div dir="auto"><span style="word-spacing:1px;color:rgb(49,49,49)">Hi folks,</span><br style="color:rgb(49,49,49);word-spacing:1px">
<br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">Question regarding TemplateStrings that I could not seem to find the answer to in the JEP write up or the Javadoc for TemplateString:  Is the expression evaluation lazy, or immediate?</span><br style="color:rgb(49,49,49);word-spacing:1px">
<br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">In other words, if I do something like this:</span><br style="color:rgb(49,49,49);word-spacing:1px">
<br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">     List<Integer> list=new ArrayList<>();</span><br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">     TemplateString ts = "size = \{list.size()}"</span><br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">     list.add(1);</span><br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">     System.out.println(ts.apply(S</span><span style="word-spacing:1px;color:rgb(49,49,49)">TR));</span><br style="color:rgb(49,49,49);word-spacing:1px">
<br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">Will it print out size = 0, or size = 1?</span><br style="color:rgb(49,49,49);word-spacing:1px"></div>
</div>
</div>
</blockquote>
<div><br></div>
<div>The expression is evaluated and the value is captured when creating the <font style="color:rgb(49,49,49)"><span style="word-spacing:1px">TemplatedString instance. There is some discussion around left to right evaluation that tries to clarify this. So the answer is “size = 0”. </span></font></div>
<div><br></div>
<br>
<blockquote type="cite">
<div>
<div>
<div dir="auto"><br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">My main reason for asking is that I would love for string templates to result in logging interfaces with overloaded methods that can take TemplateStrings instead of strings, and which are only evaluated if the log level is enabled.  So that instead of something like this:</span><br style="color:rgb(49,49,49);word-spacing:1px">
<br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">     if (logger.isEnabled(Level.DEBUG)</span><span style="word-spacing:1px;color:rgb(49,49,49)">) {</span><br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">          logger.log(Level.DEBUG, "Expensive value is " + lookup() );</span><br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">     }</span><br style="color:rgb(49,49,49);word-spacing:1px">
<br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">we can just do:</span><br style="color:rgb(49,49,49);word-spacing:1px">
<br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">     log.log(Level.DEBUG, "Expensive value is \{lookup()}");</span><br style="color:rgb(49,49,49);word-spacing:1px">
<br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">And be confident that the cost of invoking lookup() will only be paid if DEBUG is enabled.</span><br style="color:rgb(49,49,49);word-spacing:1px">
<br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">Probably over 80% of the string building I have seen over my career has been related to building log messages.  And the mistakes I have most often seen are:</span><br style="color:rgb(49,49,49);word-spacing:1px">
<br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">     1. Expensive message construction not guarded by checking if logging is enabled at that level</span><br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">     2. Expensive message construction guarded, but by checking the *wrong* logging level (e.g. check INFO, log at ERROR)</span><br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">     3. Using some sort of parameterized message/string format but getting the parameters wrong (out of order, missing one, having too many, etc.)</span><br style="color:rgb(49,49,49);word-spacing:1px">
<br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">If TemplateStrings evaluate their expression fragments only when processed then every one of these problems gets addressed, and logging code becomes *a lot* simpler to read, write, and code review.</span><br style="color:rgb(49,49,49);word-spacing:1px">
<br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">(Random side note: I *love* the choice of \ instead of $.  It took some time for me to get use to the idea, but keeping the same escape character is fantastic and I wish more languages had done that instead of using $)</span><br style="color:rgb(49,49,49);word-spacing:1px"></div>
</div>
</div>
</blockquote>
<div><br></div>
<div><font style="color:rgb(49,49,49)"><span style="word-spacing:1px">You can play some tricks with Suppliers or Futures + lambdas to get lazy evaluation. I have an roughed out (i.e., old) example at </span><span style="word-spacing:1px"><a href="https://cr.openjdk.java.net/~jlaskey/templates/examples/Log.java" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">https://cr.openjdk.java.net/~jlaskey/templates/examples/Log.java</a></span></font></div>
<div><font style="color:rgb(49,49,49)"><span style="word-spacing:1px"><br></span></font></div>
<div><font style="color:rgb(49,49,49)"><span style="word-spacing:1px">Cheers,</span></font></div>
<div><font style="color:rgb(49,49,49)"><span style="word-spacing:1px"><br></span></font></div>
<div><font style="color:rgb(49,49,49)"><span style="word-spacing:1px">— Jim</span></font></div>
</div>
</div>
<div style="word-wrap:break-word;line-break:after-white-space">
<div>
<div><font style="color:rgb(49,49,49)"><span style="word-spacing:1px"><br></span></font></div>
<div><br></div>
<br>
<blockquote type="cite">
<div>
<div>
<div dir="auto"><br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">Thanks for your time,</span><br style="color:rgb(49,49,49);word-spacing:1px">
<span style="word-spacing:1px;color:rgb(49,49,49)">Nathan</span></div>
</div>
--<br>
<div dir="ltr" data-smartmail="gmail_signature">
<div>Nathan H. Walker</div>
<div><a href="mailto:nathan.h.walker@gmail.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">nathan.h.walker@gmail.com</a></div>
<div>(703) 987-8937</div>
<div><br></div>
<div><br></div>
</div>
</div>
</blockquote>
</div>
<br></div>
</blockquote>
</div>
</div>
--<br>
<div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">
<div>Nathan H. Walker</div>
<div><a href="mailto:nathan.h.walker@gmail.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">nathan.h.walker@gmail.com</a></div>
<div>(703) 987-8937</div>
<div><br></div>
<div><br></div>
</div>
</blockquote>
<br></div></blockquote>
<div class="markdown" style="white-space: normal;">

</div></div></body>

</html>