On 06/12/2018 16:53, fo...@univ-mlv.fr wrote:

----- Mail original -----
De: "Maurizio Cimadamore" <maurizio.cimadam...@oracle.com>
À: "Remi Forax" <fo...@univ-mlv.fr>
Cc: "amber-spec-experts" <amber-spec-experts@openjdk.java.net>
Envoyé: Jeudi 6 Décembre 2018 09:54:09
Objet: Re: enhanced enums - back from the dead?
Hi Remi, some comments inline.

On 05/12/2018 21:43, Remi Forax wrote:
Hi Maurizio,
i think you have overlook the fact that raw types and inference also doesn't
play well together.
As I said, I've played with this quite a bit and came out convinced that
usability wise it's good. Note that in the proposed model, enum
constants will have full generic types - e.g. Foo<String>; it's only
when you go to the supertype that the type system will say Enum<Foo>.
But this will only be used by APIs accepting some Enum<T> - so we're
fine, and this actually guarantees same inference results as before
generification of a given enum.
yes, i'm worried about Foo.values()

   public enum Foo<T extends Comparable<T>> implements Comparable<Foo<T>> {
     S<>(""), I<>(42);   // JEP 301 mentions the diamond syntax

     private final T t;
private Foo(T t) {
       this.t = t;
     }
@Override
     public int compareTo(Foo<T> o) {
       return t.compareTo(o.t);
     }
public static void main(String[] args) {
       Arrays.stream(Foo.values()).sorted().forEach(System.out::println);
     }
   }

Can't quite understand what you mean - the code above is flawed in different ways; first you can't implement Comparable<Foo<T>> - as Enum already does that and with Comparable<Foo> in this case (because of the new treatment).

Secondly, you can't override compareTo - which is final in enum.

So, the correct example is this:

import java.util.*;

enum Foo<T extends Comparable<T>> implements Comparable<Foo> {
    S<String>(""), I<Integer>(42);   // JEP 301 mentions the diamond syntax

    private final T t;

    private Foo(T t) {
      this.t = t;
    }

    public static void main(String[] args) {
Arrays.stream(Foo.values()).sorted().forEach(System.out::println);
    }
  }


Which compiles with no issues.


accessibility:
Widening the type is usually a big No because of the security implication. The
fact that the same code code has no security bug with version n but a security
hole with version n + 1 scares me.
What scenario do you have in mind regarding enum constant pseudo-inner classes?
any scenario that is using a Lookup object
Still not getting what is the security implication; one thing is  to say that you can reflectively inspect a class where you could not before; another is that doing so represents a vulnerability. The proposed rule says that the enum constant class gets same visibility as parent. So you are really saying that some constant class contains _security sensitive_ details, and that users relied on an *unspecified* compiler behavior that protected them, as javac made the class package-private. That seems a pretty strange argument.

source compatibility:
It's may not be a big issue because the JDK source doesn't use 'var'. If a code
uses 'var' the sharp type will propagate more, so the JDK is not perhaps the
best code to test.

friend or foe:
the rules for raw types are brutal as you said, but it's by design, it offers
maximum compatibility and doesn't allow to mix raw and generic type easily so
my students detect the missing angle brackets easily (IntelliJ still doesn't
warn about missing angle brackets by default :( )


Now about your example, instead of being functional and wanted each Option to
type their argument, you can use ugly side effects instead.
So the idea is to use a temporary class instead of a Map to store the data
associated with an option. So an Option is something that takes a chunk of the
command line arguments and do a side effect on the field of an instance of that
temporary class.
Sure, there might be other ways to get there; what I did, I did it to
test usage of generic enums in a real world code base.
it seems to be "the use case" for generics enum.

I get that you do not like the feature :-)

Other use cases have been discussed here:

http://mail.openjdk.java.net/pipermail/amber-dev/2017-April/000173.html

rest assured, the JEP might bear my name, but we're not looking into this to make javac code better.

Maurizio


Maurizio
Rémi

public class LineParsing {
    private final HashMap<String, Consumer<? super Iterator<String>>> actionMap 
=
    new HashMap<>();
public LineParsing with(String option, Consumer<? super Iterator<String>>
    action) {
      actionMap.put(option, action);
      return this;
    }
public void parse(List<String> args) {
      var it = args.iterator();
      while(it.hasNext()) {
        actionMap.get(it.next()).accept(it);
      }
    }
public static void main(String[] args) {
      var bean = new Object() {
        Path input = Path.of("input.txt");
        boolean all = false;
      };
new LineParsing()
          .with("-input", it -> bean.input = Path.of(it.next()))
          .with("-all", it -> bean.all = true)
          .parse(List.of(args));
    }
}

regards,
Rémi


----- Mail original -----
De: "Maurizio Cimadamore" <maurizio.cimadam...@oracle.com>
À: "amber-spec-experts" <amber-spec-experts@openjdk.java.net>
Envoyé: Mercredi 5 Décembre 2018 17:14:59
Objet: enhanced enums - back from the dead?
Hi,
as mentioned in [1], the work on enhanced enum stopped while ago as we
have found some interoperability issues between generic enums and
standard enum APIs such as EnumSet/EnumMap.

Recently, we have discussed a possible approach that might get us out of
the woods, which is described in greater details here:

http://cr.openjdk.java.net/~mcimadamore/amber/enhanced-enums.html

We have done some internal testing to convince ourselves that, from an
operational perspective, where we end up is indeed good. Some external
validation might also be very helpful, which is why we're also in the
process of releasing the internal patch we have tested internally in the
'enhanced-enums' amber branch (we'll need to polish it a little :-)).

Assuming that, usability-wise, our story ticks all the boxes, I think it
might be worth discussing a few points:

* Do we still like the features described in JEP 301, from an
expressiveness point of view?

* Both features described in JEP 301 require some sort of massaging. On
the one hand sharper typing of enum constants has to take care of binary
compatibility of enum constant subclasses into account (for this reason
we redefine accessibility of said subclasses along with their binary
names). On the other hand, with the newly proposed approach, generic
enums also need some language aid (treatment of raw enum constants
supertypes). Do we feel that the steps needed in order to accommodate
these sharp edges are worth the increase in expressive power delivered
by JEP 301?

* Our proposed treatment for generic enums raises an additional, more
philosophical, question: what are raw types *for* and how happy are we
in seeing more of them (in the form of raw enum types)?

Cheers
Maurizio

[1] -
http://mail.openjdk.java.net/pipermail/amber-spec-experts/2017-May/000041.html

Reply via email to