<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p>
<blockquote type="cite">Hello!</blockquote>
</p>
<p>Thanks for the reply!</p>
<blockquote type="cite" cite="mid:CAE+3fjb-Z6vspuSycj2OX6gbxtQmy3UxHcvN706Vo1MLmqS-6Q@mail.gmail.com">
<div dir="ltr">
<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">
<div>
<p><b>1) Unusual generic types for exceptions and return
values</b></p>
</div>
</blockquote>
<div>
<p>The convenience of generic types is that you don't always
need to spell out or even publicly declare the concrete
processor type. However, I agree that generic types is not
what strictly needed to be mentioned in the specification.</p>
</div>
</div>
</div>
</blockquote>
<p>I do not see the problem with spelling out the concrete processor
type. Based on my experience, I expect it to be better for
readability to create a separate class anyway. However, I agree
that it is non-ideal that you have to do so in an exported
package. Especially considering that it is not trivial to restrict
access to the constructor when the field and the type of the
processor are in different packages. Maybe you are right.<br>
</p>
<blockquote type="cite" cite="mid:CAE+3fjb-Z6vspuSycj2OX6gbxtQmy3UxHcvN706Vo1MLmqS-6Q@mail.gmail.com">
<div dir="ltr">
<div class="gmail_quote">
<div>We can have</div>
<div><br>
</div>
<div>// This type is mentioned in the specification as the
root type of string template</div>
<div>// clients may implement it directly using more specific
return type and exception declaration</div>
<div>interface Processor {<br>
</div>
<div> Object process(StringTemplate template) throw
Throwable;</div>
<div>}</div>
<div><br>
</div>
<div>// This is just a convenient generic subtype, not
mentioned in the specification</div>
<div>// for people who don't want to publicly declare their
own types for processors</div>
<div>@FunctionalInterface<br>
</div>
<div>interface ParameterizedProcessor<R, E extends
Throwable> extends
Processor {</div>
<div> R process(StringTemplate template) throws E;</div>
<div><br>
</div>
<div> static <R, E extends Throwable>
ParameterizedProcessor<R, E> of(Function<? super
StringTemplate, ? extends T> process) {</div>
<div> return process::apply;</div>
<div> }</div>
<div>}</div>
<div><br>
</div>
<div>The problem is more with the naming: how to name these
two things to clearly show the difference between them?</div>
</div>
</div>
</blockquote>
I am reluctant about this. I would probably continue to implement
the generic interface just because it is more specific. I would like
to avoid a scenario where I did not implement a more specific
interface out of ignorance, and some other library is now expecting
that interface. I guess it is better not to open up this room for
inconsistency between processors.<br>
<blockquote type="cite" cite="mid:CAE+3fjb-Z6vspuSycj2OX6gbxtQmy3UxHcvN706Vo1MLmqS-6Q@mail.gmail.com">
<div dir="ltr">
<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">
<div>
<p>The generic types as specified by JEP 459 look like
remnants to me. Since template expressions are syntactic
sugar for method calls, we should just use the type of
the process method, as was introduced by this JEP.
However, the generic types were somehow left in the JEP.
Is there a good reason for that?</p>
<p>For example, <font face="monospace">java.lang.AutoCloseable</font>
does not have a generic type for the exception. The only
advantage I see is that you can implement processors
using Lambdas without introducing a functional
interface. How often do you have a processor that is
trivial enough that you see the benefit of using a
lambda? Even the implementation of STR takes multiple
lines. If somebody needs a functional interface, it is
trivial to create one yourself.</p>
<p>In my opinion, the noise introduced by the template
parameters greatly overshadows the advantage of lambdas
without having to declare a functional interface first.</p>
</div>
</blockquote>
<div><br>
</div>
<div>On the other hand, you may not have such noise even now,
if you declare your own concrete types that inherit the
generic processor.</div>
</div>
</div>
</blockquote>
<p>You may be right.<br>
</p>
<blockquote type="cite" cite="mid:CAE+3fjb-Z6vspuSycj2OX6gbxtQmy3UxHcvN706Vo1MLmqS-6Q@mail.gmail.com">
<div dir="ltr">
<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">
<div>
<p>For RAW, STR, and FMT, you may either introduce a
sub-interface without the generic exception or just
implement them within their own class outside <font face="monospace">java.lang</font>.<br>
</p>
<p><b>2) Generic type for embedded expressions</b></p>
<p>While I don't see the value of the existing type
parameters, I think it would be helpful to have a
generic type for the embedded expressions. In contrast
to the existing type parameters, such a type parameter
would extend the capabilities. It would be possible to
have type-safe inputs for processors, which is not
possible with the current JEP.</p>
<blockquote>
<pre>public interface StringTemplate<T>
...
public interface Processor<T> {
Object process(StringTemplate<? extends T> st) throws Throwable;
}
...
}
</pre>
</blockquote>
</div>
</blockquote>
<div><br>
</div>
<div>This covers only a limited scenario when all the embedded
expressions have the same type. Can you imagine a particular
use-case for that scenario?</div>
</div>
</div>
</blockquote>
<p>I am aware that this limitation will prevent most processors from
using a more specific type. I am mostly just reluctant to give up
type-safety. You might be able to use typed parameters in some
more advanced use cases. I could imagine to define a Swing Layout
using a template string and a DSL. The DSL might be somewhat
similar to <font face="monospace">grid-template</font> in CSS. All
the template arguments would need to be Swing components.</p>
<blockquote>
<pre>Container contentPane = ...;
contentPane.setLayout(LAYOUT."""
\{logo} \{toolbar} \{userinfo} fit-content
\{navigation} \{content} \{content} minmax(100px, auto)
\{footer} \{footer} \{footer} fit-content
100px minmax(100px, auto) fit-content
""");
</pre>
</blockquote>
<p>I would also be in favor of getting union types. I was often
struggling with this limitation independent from String Templates.
Anyway, unions are different topic. (If you are aware of any
active discussions or previous attempts, I would be happy to know.
I would also have an idea how to represent them in Bytecode, but
not sure how well the problem itself was discussed yet.)<br>
</p>
<blockquote type="cite" cite="mid:CAE+3fjb-Z6vspuSycj2OX6gbxtQmy3UxHcvN706Vo1MLmqS-6Q@mail.gmail.com">
<div dir="ltr">
<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">
<div>
<p><b>3) Let STR and FMT keep the indentation<br>
</b></p>
<p>I was wondering if STR and FMT should keep the
intention when the arguments contain line breaks. Most
usages are probably not indented or only use arguments
without line breaks. However, whenever I encountered a
situation where I wanted to insert a multiline string
into an indented line, I always wanted to keep the
intention. A potential implementation could basically
copy all the whitespace characters directly after the
most recent line break in the fragments and insert them
behind each line break of the template argument.</p>
<blockquote>
<pre>String multilineString = """
First line.
Second line.
""";
System.out.println("""
Output:
\{multilineString}
...
""");
</pre>
</blockquote>
<p>I have to say I am myself a bit skeptical as this would
noticeably increase the complexity. However, I cannot
think of a scenario where you don't want this to happen.
(I could imagine that I would otherwise implement such a
processor in almost all my projects and end up never
using STR.)<br>
</p>
</div>
</blockquote>
<div>You can use instead </div>
<div>STR."""</div>
<div>Output:</div>
<div>\{multilineString.indent(4)}</div>
<div>"""</div>
</div>
</div>
</blockquote>
Good point. I would probably still prefer to implement my own
template processor, but String.indent(int) already makes it less
annoying if you don't have one. It might still be good to have an
option or flag for FMT, but that would be out of scope of this JEP.<br>
<blockquote type="cite" cite="mid:CAE+3fjb-Z6vspuSycj2OX6gbxtQmy3UxHcvN706Vo1MLmqS-6Q@mail.gmail.com">
<div dir="ltr">
<div class="gmail_quote">
<div>Which would be more explicit, thus less magical. In
general, it's expected that a properly written program would
only rarely use STR processor (especially for multiline
output), preferring more domain-specific processors
depending on how the resulting string should be interpreted.</div>
<div> <br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div>
<p> </p>
<p><b>4) Purpose of StringTemplate.interpolate()?</b><br>
</p>
<p>And finally, although not very important, I am
wondering about the usefulness of <font face="monospace">StringTemplate.interpolate</font>. In
the rare case when you actually need this functionality,
you can also call <font face="monospace">STR.process(template)</font>.
There is also <font face="monospace">template.process(STR)</font>
for some reason.</p>
For <font face="monospace">toString()</font>-like use
cases, we already have <font face="monospace">StringTemplate.toString(StringTemplate)</font>.
I don't think that <font face="monospace">StringTemplate.interpolate()</font>
would be a good fit in such cases. And again, you can
otherwise still call <font face="monospace">STR.process(...)</font>.<br>
<p><br>
</p>
<p>That was all. I am happy for any reply.<br>
</p>
<p>PS: I find it interesting that the JEP does not mention
tagged templates of JavaScript, although the concepts
look quite similar.</p>
<p>Best Regards,<br>
Johannes<br>
</p>
</div>
</blockquote>
</div>
</div>
</blockquote>
</body>
</html>