Thanks Alex - I’ve tweaked the spec accordingly. Gavin
> On 31 Mar 2023, at 18:19, Alex Buckley <[email protected]> wrote: > > Hi Gavin, > > Re: "The type of the TemplateProcessor expression must be a subtype of a type > StringTemplate.Processor<R,E>, for some types R and E ..." > > I think this clause can be improved to ensure that the {Class,Interface} vs. > Type police don't come after us. The term `StringTemplate.Processor<R,E>` > looks like a generic interface, not a parameterized interface type, but then > "for some types R and E" suggests type arguments, which means the term > denotes a parameterized interface type after all. > > The JLS has a so-so record of handling must-be-a-parameterized-type in the > past. Grepping ch.14 for "subtype", we find: > > ----- > Otherwise, if the Expression has a type that is a subtype of Iterable<X>, for > some type X, then R is X. > ... > If the type of Expression is a subtype of Iterable<X> for some type argument > X, then I is the type java.util.Iterator<X> > ----- > > There's also verbiage in ch.14 about the raw type `Iterable`, which makes me > wonder if the type of the TemplateProcessor expression can be the raw type > `StringTemplate.Processor`. > > Can we improve the presentation of the required type to prevent it looking > like a generic interface? I pondered saying that the type of the expression > _must implement_ <something>, but _must be a subtype_ is more common. Here's > an idea: > > ----- > The type TP of the TemplateProcessor expression must be a subtype of > StringTemplate.Processor, or a compile-time error occurs. [That opens the > door to a raw supertype.] If TP implements the parameterized type > StringTemplate.Processor<Result,Exc>, then the type of the template > expression is Result. If TP implements the raw type StringTemplate.Processor, > then the type of the template expression is Object. > > StringTemplate.Processor<R,E> is a generic functional interface (9.8) > whose single abstract method takes a StringTemplate, returns R, and > throws E. > ----- > > Alex > > On 3/31/2023 9:44 AM, Gavin Bierman wrote: >> I’ve updated the spec change document to reflect this change: >> https://cr.openjdk.org/~gbierman/jep430/latest/ >> <https://cr.openjdk.org/~gbierman/jep430/latest/> >> Thanks, >> Gavin >>> On 27 Mar 2023, at 14:07, Jim Laskey <[email protected]> wrote: >>> >>> After the string template interface name changes, i.e., |TemplateProcessor| >>> becoming |Processor|, the rationale for the existence of |SimpleProcessor >>> |and |StringProcessor| has lessened to the point where they should be >>> dropped. >>> >>> |SimpleProcessor| owed its existence to the long-winded name >>> |TemplateProcessor| and that ugly second parameter, |E|, in |Processor<R, >>> E>| (in a many of cases |E| will be the unchecked |RuntimeException|). >>> |StringProcessor| existed because most template processors will produce >>> strings. >>> >>> |TemplateProcessor<JSONObject, RuntimeException> JSON = st-> new >>> JSONObject(st.interpolate()); TemplateProcessor<String, RuntimeException> >>> INTER = StringTemplate::interpolate;| >>> >>> vs. >>> >>> |SimpleProcessor<JSONObject> JSON = st-> new JSONObject(st.interpolate()); >>> StringProcessor INTER = StringTemplate::interpolate;| >>> >>> It was thought that having the friendlier interfaces would provide clarity, >>> hide |RuntimeException| and simplify explanation. The reality is that most >>> developers will define template processors using full class declarations. >>> Furthermore, developers will learn to use |RuntimeException| regularly due >>> to the abundance of template processor examples. >>> >>> |public class InterpolateProcessor implements Processor<String, >>> RuntimeException> { @Override public String process(StringTemplate st) { >>> return st.interpolate(); } } SimpleProcessor<String> INTER = new >>> InterpolateProcessor(); | >>> >>> Even after |SimpleProcessor| and |StringProcessor| go away, developers can >>> still use the functional interface shorthand. >>> >>> |Processor<JSONObject, RuntimeException> JSON = st-> new >>> JSONObject(st.interpolate()); Processor<String, RuntimeException> INTER = >>> StringTemplate::interpolate;| >>> >>> And, a new factory method, |Processor.of|, will be added for fans of |var|. >>> >>> |var JSON = Processor.of(st-> new JSONObject(st.interpolate())); var INTER >>> = Processor.of(StringTemplate::interpolate);| >>> >>> For those developers that like the notion of |SimpleProcessor| and >>> |StringProcessor|, these interfaces can be trivially defined per project; >>> >>> |@FunctionalInterface public interface SimpleProcessor<R> extends >>> Processor<R, RuntimeException> {} @FunctionalInterface public interface >>> StringProcessor extends SimpleProcessor<String> {}| >>> >>> >>> >>> >>> >>> >>>> On Mar 17, 2023, at 10:24 AM, Jim Laskey <[email protected]> wrote: >>>> >>>> This is a heads up about some name changes coming to the string template >>>> feature with the intent of eliminating the “java.lang.template” package >>>> along with clarifying the processor hierarchy, >>>> >>>> _Old_ _New_ >>>> java.lang.template.Carriers* java.lang.runtime.Carriers* >>>> java.lang.template.ReferencedKeyMap* java.lang.runtime.ReferencedKeyMap* >>>> java.lang.template.ReferenceKey* java.lang.runtime.ReferenceKey* >>>> java.lang.template.StringTemplateImpl* >>>> java.lang.runtime.StringTemplateImpl* >>>> java.lang.template.StringTemplateImplFactory* >>>> java.lang.runtime.StringTemplateImplFactory* >>>> java.lang.runtime.TemplateRuntime java.lang.runtime.TemplateRuntime >>>> java.lang.template.TemplateSupport* >>>> java.lang.runtime.TemplateSupport >>>> java.lang.template.StringTemplate java.lang.StringTemplate >>>> java.lang.template.ValidatingProcessor java.lang.StringTemplate.Processor >>>> java.lang.template.ProcessorLinkage >>>> java.lang.StringTemplate.Processor.Linkage >>>> java.lang.template.TemplateProcessor >>>> java.lang.StringTemplate.SimpleProcessor >>>> java.lang.template.StringProcessor java.lang.StringTemplate.StringProcessor >>>> >>>> >>>> (*) - package private >>>> >>>> >>>> The new processor hierarchy will be; >>>> >>>> interface Processor<R, E> >>>> interface SimpleProcessor<R> extends Processor<R, RuntimeException> >>>> interface StringProcessor extends SimpleProcessor<String> >>>> >>>> It will take me a few days to update the JEP, CSRs, PR and JLS, so stay >>>> tuned. As always, comments are welcome. >>>> >>>> Cheers, >>>> >>>> — Jim >>>> >>>
