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.

Reply via email to