String Templates Question - are expressions within a TemplateString literal evaluated immediately, or when a template is applied?

Brian Goetz brian.goetz at oracle.com
Thu Sep 22 19:13:35 UTC 2022


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:

     () -> STR."Connection from \{name} at \{time}"

which is a Supplier<String>.  Lots of logging frameworks already are 
prepared to deal with Supplier.

On 9/22/2022 3:09 PM, Nathan Walker wrote:
> 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.
>
> 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()}"
>
> 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.
>
> Thanks,
> Nathan
>
> On Thu, Sep 22, 2022 at 10:17 AM Jim Laskey <james.laskey at oracle.com> 
> wrote:
>
>
>
>>     On Sep 22, 2022, at 11:08 AM, Nathan Walker
>>     <nathan.h.walker at gmail.com> wrote:
>>
>>     Hi folks,
>>
>>     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?
>>
>>     In other words, if I do something like this:
>>
>>        List<Integer> list=new ArrayList<>();
>>        TemplateString ts = "size = \{list.size()}"
>>        list.add(1);
>>        System.out.println(ts.apply(STR));
>>
>>     Will it print out size = 0, or size = 1?
>
>     The expression is evaluated and the value is captured when
>     creating the TemplatedString instance. There is some discussion
>     around left to right evaluation that tries to clarify this. So the
>     answer is “size = 0”.
>
>
>>
>>     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:
>>
>>        if (logger.isEnabled(Level.DEBUG)) {
>>             logger.log(Level.DEBUG, "Expensive value is " + lookup() );
>>        }
>>
>>     we can just do:
>>
>>        log.log(Level.DEBUG, "Expensive value is \{lookup()}");
>>
>>     And be confident that the cost of invoking lookup() will only be
>>     paid if DEBUG is enabled.
>>
>>     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:
>>
>>        1. Expensive message construction not guarded by checking if
>>     logging is enabled at that level
>>        2. Expensive message construction guarded, but by checking the
>>     *wrong* logging level (e.g. check INFO, log at ERROR)
>>        3. Using some sort of parameterized message/string format but
>>     getting the parameters wrong (out of order, missing one, having
>>     too many, etc.)
>>
>>     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.
>>
>>     (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 $)
>
>     You can play some tricks with Suppliers or Futures + lambdas to
>     get lazy evaluation. I have an roughed out (i.e., old) example at
>     https://cr.openjdk.java.net/~jlaskey/templates/examples/Log.java
>
>     Cheers,
>
>     — Jim
>
>
>
>>
>>     Thanks for your time,
>>     Nathan
>>     -- 
>>     Nathan H. Walker
>>     nathan.h.walker at gmail.com
>>     (703) 987-8937
>>
>>
>
> -- 
> Nathan H. Walker
> nathan.h.walker at gmail.com
> (703) 987-8937
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20220922/ce390b02/attachment-0001.htm>


More information about the amber-dev mailing list