[Correction] Re: [string-templates] Covariant signature of 'process' method
Remi Forax
forax at univ-mlv.fr
Thu Aug 3 15:35:16 UTC 2023
----- Original Message -----
> From: "Tagir Valeev" <amaembo at gmail.com>
> To: "amber-spec-experts" <amber-spec-experts at openjdk.org>
> Sent: Thursday, August 3, 2023 1:51:55 PM
> Subject: Re: [Correction] Re: [string-templates] Covariant signature of 'process' method
Hi Tagir,
> Additional thoughts on this topic.
>
> 1. Currently, it looks impossible for the processor to declare several
> disjoin exceptions. E.g., I cannot do this:
>
> static class CovariantException implements
> StringTemplate.Processor<Integer, Exception> {
> @Override
> public Integer process(StringTemplate stringTemplate) throws
> IOException, SQLException {
> return 123;
> }
> }
>
> public static void main(String[] args) {
> CovariantException proc = new CovariantException();
> try {
> Integer i = proc."hello";
> } catch (IOException e) {
> // handle
> } catch (SQLException e) {
> // handle
> }
> }
>
> I must declare and handle the closest supertype exception (which is
> simply java.lang.Exception), which makes the exception handling much
> more clumsy, as in this case I will also catch unrelated
> RuntimeExceptions. Or I can declare a separate rethrowing
> catch(RuntimeException ex), but this is very unfortunate to force
> people to do this.
Yes, sadly this is a well known limitation of the Java generics, a type variable can not represent two disjoint exception types.
BTW, this is the reason why the Stream API does not try to capture exceptions, in filter, map, etc, the Java type system is too weak for that.
>
> 2. Annotations could be added to the process() method and handled by
> third-party tools like annotation processors or static analyzers. For
> example, Checker framework provides Pure annotation to annotate
> methods that don't produce side-effects. We can do this:
>
> static class Covariant implements StringTemplate.Processor<Object,
> RuntimeException> {
> @Override
> @Pure
> public Integer process(StringTemplate stringTemplate) {
> return 123;
> }
> }
>
> public static void main(String[] args) {
> Covariant proc = new Covariant();
> Object i = proc."hello";
> }
>
> And we will assume that the static analyzer will respect the
> annotation. To do this, a static analyzer should resolve the implicit
> call in template expression into Covariant::process. However, Java
> compiler resolves it to Processor::process (as covariant return type
> is ignored). It sounds really strange to get the return type from the
> supermethod while the annotations from the most specific method. Of
> course, we cannot put our own annotations to Processor::process.
This looks like a bug of the javac implementation, the virtual call should be Covariant::process and not Processor::process in this example.
>
> With best regards,
> Tagir Valeev.
regards,
Rémi
>
> On Thu, Aug 3, 2023 at 12:10 PM Tagir Valeev <amaembo at gmail.com> wrote:
>>
>> Unfortunately, I mixed the sample code. The first code sample in my
>> previous letter should read as:
>>
>> public class Test {
>> static class MyProcessor implements
>> StringTemplate.Processor<Integer, Exception> {
>> @Override
>> public Integer process(StringTemplate stringTemplate) {
>> return 123;
>> }
>> }
>>
>> public static void main(String[] args) {
>> MyProcessor proc = new MyProcessor();
>> Integer i = proc."hello";
>> }
>> }
>>
>> The second sample should read as:
>>
>> public class Test {
>> static class MyProcessor implements
>> StringTemplate.Processor<Object, RuntimeException> {
>> @Override
>> public Integer process(StringTemplate stringTemplate) {
>> return 123;
>> }
>> }
>>
>> public static void main(String[] args) {
>> MyProcessor proc = new MyProcessor();
>> Integer i = proc."hello";
>> }
>> }
>>
>> Sorry for the confusion.
>>
>> With best regards,
>> Tagir Valeev.
>>
>> On Thu, Aug 3, 2023 at 12:07 PM Tagir Valeev <amaembo at gmail.com> wrote:
>> >
>> > Hello!
>> >
>> > It's possible to create a custom string template with covariant
>> > process() method signature. For example, we can relax the throws
>> > statement:
>> >
>> > public class Test {
>> > static class MyProcessor<T> implements
>> > StringTemplate.Processor<Integer, Exception> {
>> > @Override
>> > public Integer process(StringTemplate stringTemplate) {
>> > return 123;
>> > }
>> > }
>> >
>> > public static void main(String[] args) {
>> > MyProcessor<String> proc = new MyProcessor<>();
>> > Integer i = proc."hello";
>> > }
>> > }
>> >
>> > Now, it's not compilable:
>> > java: unreported exception java.lang.Exception; must be caught or
>> > declared to be thrown
>> >
>> > However, it's evident and can be statically checked that the exception
>> > is not possible.
>> >
>> > Covariant return type is also possible:
>> >
>> > public class Test {
>> > static class MyProcessor implements
>> > StringTemplate.Processor<Integer, Exception> {
>> > @Override
>> > public Integer process(StringTemplate stringTemplate) {
>> > return 123;
>> > }
>> > }
>> >
>> > public static void main(String[] args) {
>> > MyProcessor proc = new MyProcessor();
>> > Integer i = proc."hello";
>> > }
>> > }
>> >
>> > Now, it's not compilable:
>> > java: incompatible types: java.lang.Object cannot be converted to
>> > java.lang.Integer
>> >
>> > This requires passing exact types through the inheritance hierarchy
>> > which might be inflexible and annoying. I may probably want to declare
>> > `abstract class AbstractProcessor implements Processor<Object,
>> > Throwable>` and have any covariant signatures in subtypes without
>> > declaring new type parameters and forward them through the hierarchy.
>> >
>> > Java has another implicit way to call methods: try-with-resources and
>> > AutoCloseable interface. There we have no exception type parameter,
>> > but covariant signatures in subclass close() methods are respected at
>> > the try-with-resource use sites. Probably it would be more consistent
>> > and convenient to respect covariant signatures in string templates as
>> > well?
>> >
>> > With best regards,
> > > Tagir Valeev.
More information about the amber-spec-experts
mailing list