Are templated string embedded expressions "method parameters" or "lambdas"?

Brian Goetz brian.goetz at oracle.com
Fri Oct 29 17:20:20 UTC 2021


> For me, "deferred execution" is not the right way to think about the 
> sub expressions of a templated string.

I think there really are two (related) cases here.

The first (and more common) case is when you provide a formatter object 
directly:

     Foo f = F."Hello \{name()}"

Here, there are several interesting constraints:

  - The template is formatted exactly once, consuming each parameter 
expression exactly once (*)
  - The timing of consuming the parameter expressions is the same as the 
timing of formatting

Under these constraints, the eager-vs-lazy interpretation doesn't really 
matter, because there's no difference in the timing or arity of 
expression evaluation.

The second case is when you are capturing an "unprocessed" template for 
later use:

     TemplatedString ts = "Hello \{name()}";

Now, there's no guarantee as to whether the template will be processed 
at all, or once, or more than once.  Again, this only makes a difference 
if (a) the expressions have side-effects or (b) the expressions are 
"stateful", acting on state that might have changed since capture time, 
such as static state, current time, etc.  (Which sounds very much like 
the things that Streams tells you not to do in behavioral parameters.)  
The sad thing is we would rather people not do these things at all, in 
which case it makes less of a difference.

Treating expressions as lazy offers real performance benefits for the 
case where the template will not be processed at all (as in logging 
frameworks); it minimizes the cost of capturing the TS. Treating 
expressions as eager is simpler to reason about (though, in the absence 
of side effects, doesn't really matter), but creates a two-stage 
evaluation where the expressions are evaluated at one point and combined 
at another.  Performance is a side-effect too.



*It may not actually be the case that all are consumed exactly once.  
Imagine a framework where you can specifiy localized messages in a way 
that lets them reorder / reuse parameters; its possible some parameters 
need not be evaluated at all.  Again, lazy evaluation defers the costs 
until they are needed.


More information about the amber-spec-experts mailing list