<div dir="ltr"><div style="font-family:monospace" class="gmail_default">Hello Brian,<br><br>Thanks for the clarification, that's helpful!<br><br>> I'm kind of surprised no one has pointed this out yet :)<br><br>Maybe not this thread specifically, but a LOT of people have been confused about this. Multiple times on amber-dev even, let alone reddit (before the whole spez thing). A lot of people (me included) pretty stopped asking about that example because we never got any definitive responses. Up until now, I haven't seen a definitive answer as to why that example was left in. This definitely suffices though.<br><br>> The spirit here is that the template processor is a<br>> *function*, taking some template-shaped ingredients and<br>> turning it into a useful *thing*, that you can then<br>> further use or manipulate.  It should have the effect of<br>> a factory, whether producing a String or a JsonDocument<br>> or a ResultSet.  The latter is interesting in that the<br>> factory has to make a connection to produce the result<br>> set, but what the processor is doing is *making a result<br>> set*. A constructor or "factory" that produced nothing<br>> and operated primarily through side-effects would rightly<br>> be declared to be a poor API.<br><br>Ok, fair enough. I think the missing detail though is that, you need to understand JDBC in order for that to answer follow up questions.<br><br>I am not very familiar with JDBC. So when I see a template processor called DB, my first thought is that I can do DB stuff, including updates and deletes. I was not aware that a ResultSet is more or less the output of a SELECT. By all means, after doing a decent amount of reading, I understand that now, but a lot of us never touch JDBC since we spend all our time in Hibernate/JPA, so this example probably flew over a lot of heads.<br><br>I see the nuance in the example now, but I guarantee I am not the only one who got lost in that example and thought that it was supporting side-effects *because I saw DB*.<br><br>> What this whole thread reinforces for me is that we need<br>> to have a document (like "Programmers Guide to Text<br>> Blocks") that spells out the principles.  In the<br>> meantime, hopefully my words shall suffice :)<br><br>100%, no question. I would have definitely thought that the JDBC example is bad, so spelling out what is or isn't useful behaviour would behoove everyone.<br><br>Thank you for the insight!<br>David Alayachew<br></div><br><div dir="ltr"><div class="gmail_default" style="font-family:monospace"><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Jul 24, 2023 at 11:31 AM Brian Goetz <<a href="mailto:brian.goetz@oracle.com">brian.goetz@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
<br>
> One observation I’d make here is that the JEP presents an example in the form of a QueryBuilder template processor to produce a PreparedStatement. Per the Javadoc of Connection, this may well result in a side-effect by sending the query to the server for precompilation / validation.<br>
><br>
> I think it’s worth having a consistent story to people when presenting the feature - in the JEP example, it would feel a little unwieldy for QueryBuilder to return its own thunky DeferredPreparedStatement, or similar, for the caller to work with.<br>
<br>
<br>
I'm kind of surprised no one has pointed this out yet :)<br>
<br>
The naive interpretation here is "Wait, on one hand you say side effects <br>
are bad, on the other you given an example with side effects.  <br>
Inconsistant!"  But as always, the reality is more subtle.<br>
<br>
The spirit here is that the template processor is a *function*, taking <br>
some template-shaped ingredients and turning it into a useful *thing*, <br>
that you can then further use or manipulate.  It should have the effect <br>
of a factory, whether producing a String or a JsonDocument or a <br>
ResultSet.  The latter is interesting in that the factory has to make a <br>
connection to produce the result set, but what the processor is doing is <br>
*making a result set*.   A constructor or "factory" that produced <br>
nothing and operated primarily through side-effects would rightly be <br>
declared to be a poor API.<br>
<br>
The ResultSet example is fine, because it's not confusing what is going <br>
on -- I describe my query with a template, and I get back a ResultSet, <br>
which is then my responsibility to iterate or not, and close when done.  <br>
It is a factory for result sets.  Whereas the LOG example is not, <br>
because it it is intrinsically confusing.  "Derive an X from a Y" is <br>
behavior one can generally intuit purely from the type Function<X,Y> <br>
(and knowledge of what X and Y are).  "Do an arbitrary side effect" is <br>
not.  If you want to do arbitrary side effects, write methods whose <br>
names clearly describe the behavior of the method.<br>
<br>
(I think everyone pretty much knows this, but then gets distracted by <br>
"but performance" or "but its more characters".  Again, we can't save <br>
people from themselves, but we can set good examples.)<br>
<br>
What this whole thread reinforces for me is that we need to have a <br>
document (like "Programmers Guide to Text Blocks") that spells out the <br>
principles.  In the meantime, hopefully my words shall suffice :)<br>
</blockquote></div></div>