From eliasvasylenko at gmail.com Tue Dec 11 11:13:52 2018 From: eliasvasylenko at gmail.com (elias vasylenko) Date: Tue, 11 Dec 2018 11:13:52 +0000 Subject: enhanced enums - back from the dead? In-Reply-To: References: <1970970547.807832.1544046196415.JavaMail.zimbra@u-pem.fr> <4474050b-cfca-d40b-3712-26f8109a8456@oracle.com> <1615585555.1032246.1544115212153.JavaMail.zimbra@u-pem.fr> <2092712408.1146020.1544178384809.JavaMail.zimbra@u-pem.fr> <3a831534-107d-353c-1979-906540e6a60f@oracle.com> <748617869.84460.1544273138942.JavaMail.zimbra@u-pem.fr> Message-ID: So going back a little, the suggestion of R?mi is to have the direct supertype of Foo be Enum> instead of the proposed Enum? And the problem with this is that with invocation of e.g. noneOf or allOf with a class literal we have an assignment of Class to Class, which can't satisfy the bound E <: Enum? I hope I have understood so far. Then could this not be addressed by also adjusting the signature of EnumSet, and some of the methods on it (those which mention Class), such that the type parameters are specified as >? Then I think the bound is satisfied as follows: Foo <: [E:=Foo]Enum Foo <: Enum Enum> <: Enum Foo <: Foo And the only things that can satisfy the bound on E would be E:=Foo, E:=Foo, or a capture of E, or the infinite type Enum> This does seem to create some other problems. One problem (or rather, an avoidable pitfall) is that the now-legal aforementioned infinite type would describe an enum set which accepts enum values belonging to different classes, which means losing static type safety. But since the infinite type is not denotable we just have to make sure it can never be inferred anywhere, meaning that the signatures of e.g. the Enum.of methods should retain their existing type parameter bound of >, such that we can only infer E:=Foo. Another problem is that in any existing class which extends EnumSet some of the overriding method signatures may be made incompatible. I expect this would require refining the notion of override equivalence of signatures in the JLS to a notion of override compatibility, where a little flexibility is allowed in overriding methods to have more specific bounds on type parameters (so long as the erased signature is unchanged of course). I don't know if this is feasible, but I think there's an argument that it's a sensible refinement regardless of the enhanced enums issue. It would be nice to be able to adjust the bounds on the type parameters of a method to be less specific without worrying about breaking source compatibility. I'm sure there's a lot that I've overlooked, this is quite difficult to reason about in the abstract. Eli On Mon, 10 Dec 2018 at 15:38, Maurizio Cimadamore < maurizio.cimadamore at oracle.com> wrote: > > On 08/12/2018 12:45, forax at univ-mlv.fr wrote: > > ----- Mail original ----- > >> De: "Maurizio Cimadamore" > >> ?: "Remi Forax" > >> Cc: "amber-spec-experts" > >> Envoy?: Samedi 8 D?cembre 2018 00:57:58 > >> Objet: Re: enhanced enums - back from the dead? > > [...] > > > >>> It's not that i don't like the feature, it's that for me it's a > feature you can > >>> not even put in the box of the features that we could do. We start > with "hey we > >>> could do this !" but there are some typing issues. Now, what your are > saying is > >>> that we can use raw types to not have the typing issues, but as i said > above, > >>> you are trading an error to a bunch of warnings, doesn't seems to be a > good > >>> deal*. > >> I agree that having too many warnings is bad - in my experiment, > >> although I touched a lot of code, including stream chains, I did not > >> find them; Comparator.comparing is probably one of the worst beast (and > >> doesn't work well with target typing even beside generic enums). Not > >> sure if that shifts the balance one way or another, but point taken. > >> > >> On this topic, since I was there, I tried to tweak the prototype so that > >> Enum.values() and Enum.valueOf() return wildcards Foo, but supertype > >> is Enum and this seem to work surprisingly well, both in the tests > >> I had and in the new one you suggest. Maybe that would minimize the raw > >> type usage, pushing it quite behind the curtains, and strictly as a > >> migration aid for APIs such as EnumSet/Map ? > > Using Enum> should also work ? no ? > > No, we have tried that path and that doesn't work - ultimately you get > an issue because EnumSet.of is accepting a Class, and, in case of a > class literal, you get back a Class (Foo raw). So if supertype says > Class> you get two incompatible constraints on T, namely Foo and > Foo. > > Maurizio > > > > >> Maurizio > >> > > R?mi >