<div dir="auto"><div>Hello Maurizio,</div><div dir="auto"><br></div><div dir="auto">Since these are your words I am paraphrasing, could you really quickly skim through and let me know if I am off the mark?</div><div dir="auto"><br></div><div dir="auto">Thank you for your time and help!</div><div dir="auto">David Alayachew<br><br><div class="gmail_quote" dir="auto"><div dir="ltr" class="gmail_attr">On Wed, Mar 29, 2023, 2:02 PM David Alayachew <<a href="mailto:davidalayachew@gmail.com">davidalayachew@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div>Hello Archie,</div><div dir="auto"><br></div><div dir="auto">Thank you for your response!</div><div dir="auto"><br></div><div dir="auto">Also, ty again for all the help on the compiler-dev issue with the .class filenames with similar case! I appreciate all the help you all gave.</div><div dir="auto"><br></div><div dir="auto">> Can I say "me too"?? :) I've always wanted</div><div dir="auto">> to be able to declare an instance method</div><div dir="auto">> whose return type is the same type as the</div><div dir="auto">> instance. In fluent API's, it would</div><div dir="auto">> eliminate a bunch of override methods</div><div dir="auto">> that are only there to narrow the return</div><div dir="auto">> type.</div><div dir="auto"><br></div><div dir="auto">Oh cool, I never thought of it this way. Yes, that would make writing utilities way easier, and fluent api's like you said.</div><div dir="auto"><br></div><div dir="auto">> On the enum question...<div dir="auto">> </div><div dir="auto">> When I was programming Java before</div><div dir="auto">> there were enums, I would homebrew my</div><div dir="auto">> own enums.</div><div dir="auto">> </div><div dir="auto">> When enums were invented, I thought</div><div dir="auto">> "Great! The compiler will do all that stuff</div><div dir="auto">> for me". I could clearly see that it was</div><div dir="auto">> just a matter of the compiler</div><div dir="auto">> automatically doing a transformation I</div><div dir="auto">> was already doing manually.</div><div dir="auto">> </div><div dir="auto">> Today when I want a generic enum type, I</div><div dir="auto">> go back to homebrewing my own enums</div><div dir="auto">> just like before, with generic parameter(s)</div><div dir="auto">> as needed.</div><div dir="auto"><br></div><div dir="auto">Yeah, enums feel really intuitive with respect to what originally you were doing vs what the compiler enables for you. It feels very much like records do now. That's actually part of the reason that this lack of functionality with generics on the class level hurts so much for enums. It forces me to come crashing back down to normal classes. It's like going onto local roads doing 35 when I was cruising on the highway doing 70.</div><div dir="auto"><br></div><div dir="auto">> So from a practical perspective most</div><div dir="auto">> developers probably don't understand</div><div dir="auto">> why this shouldn't be "easy". If a</div><div dir="auto">> developer can do it manually, the</div><div dir="auto">> compiler should be able to do it</div><div dir="auto">> automatically.</div><div dir="auto"><br></div><div dir="auto">I've received so many great answers already, but none of them have attempted to answer the second half of the question - why was this done in the first place? I hope someone will be able to answer that eventually. Maybe it was a mistake to bundle them together in a single post.</div><div dir="auto"><br></div><div dir="auto">Maybe the original designer of that feature has since left the development team and it is currently unknown?</div><div dir="auto"><br></div><div dir="auto">> Also, it's kind of perplexing that the</div><div dir="auto">> show-stopping barrier here is not with the</div><div dir="auto">> Enum type itself, but with the</div><div dir="auto">> EnumSet/EnumMap utility classes.</div><div dir="auto"><br></div><div dir="auto">So, thanks to Tesla, Brian, and everyone else, I now feel confident enough to correct this and explain what the actual intent was. Thanks again everyone!</div><div dir="auto"><br></div><div dir="auto">Originally, yes, the concern was about a bunch of errors that popped up on EnumSet and EnumMap when adding generics to the enum. When digging into that, they realized that f bounded types in general don't play well with any collection, which they later explained with the term heterogeneous types. All this means is that, at the time, the team couldn't see a clear way for the type system to represent a Collection of a bunch of E's, each with their own, potentially different, type parameter. To my understanding, saying I have a Collection of a bunch of E's whose type parameter is ? (unknown) is basically saying that every one of those E's has a type parameter that is the exact same type, even if it is only the parent (like java.lang.Object).</div><div dir="auto"><br></div><div dir="auto">This means that you would run into a very similar issue if you tried to have a Collection of any type T, where instance of that type T has its own, separate value for its type parameter.</div><div dir="auto"><br></div><div dir="auto">Maurizio closed the original post by saying they were exploring ways to improve the type system so that they actually COULD model this functionality. However, until that happens, or the blocker is removed, Maurizio suggested shelving until then.</div><div dir="auto"><br></div><div dir="auto">The second post, however, took things in a different direction. Rather than considering raw types (and the errors that came with it) to be failure states, the team took a closer look at the rules and saw that the rules and errors thrown for generics were actually lacking in a lot places, leading to false positives and negatives. Seeing that, they then thought about trying to outright change/add rules to better represent what is and is not safe to do in generics.</div><div dir="auto"><br></div><div dir="auto">In short, the second post offered up the idea of saying that a more precise typing rule could be added that would allow the supertype to choose not to depend on its type parameter if it is not actually going to use it.</div><div dir="auto"><br></div><div dir="auto">This was a very complex idea for me to wrap my head around, but thanks to these past several comments I got it now.</div><div dir="auto"><br></div><div dir="auto">What that idea means is that - if I have a Collection of E's, each with their own type parameter, then I may not need to know the type parameter of any of the elements of my collection, at least not at that moment. So, if I have an enum where value1 has a type parameter of String, and value2 has a type parameter of Integer, and I stick both of these values in an Collection, I know that I have no way of knowing the type parameter of the value that I passed in until I can identify which value it is (like through a switch statement for an example). As a result, I actually don't care about the type parameter until I can single this out to the individual type. AND THEREFORE, if my error is complaining that about the type parameter of my bunch of E's, this new type rule would allow me to say "I give up the ability to know what the type parameter of the value is until I hammer down which enum value this is". Because of that, I have placed a constraint on myself that prevents me from hurting myself through a bad generic method call, and therefore, I don't need that restriction in this case. Hence, the sharper type checking rules allowing us to learn when and where this situation applies so that we can lift that constraint off of the programmer.</div><div dir="auto"><br></div><div dir="auto">Now, this is not a clean break, it allows some bugs that previously not possible. However, with respect to the issue of trying to represent a Collection of a generic enum, it removes the biggest issues, and the other obstacles are doable. Just the big takeaway was that, thanks to the new typing rule, we can use a raw type not only as an on-ramp for old code upgrading to generics, but go further and claim that whatever E this Collection is a Collection of can all be assumed to be heterogeneous, which allows us to say, we won't use their type parameters, so we don't need to check them at this moment.</div><div dir="auto"><br></div><div dir="auto">Maurizio closes it off by saying that the problem is no longer about trying to make enums be generic wile playing well with EnumMap and EnumSet. That problem has been thoroughly dealt with and is no longer a blocker.</div><div dir="auto"><br></div><div dir="auto">The real problem is - is this really a desirable way of doing this? Implementing the typing rules takes effort, and now, these raw types open up room for bugs in generics that weren't there before. Is giving enums generics (or more properly, allowing a generic data structure the ability to have heterogeneous E) worth the new problems that will be opened up in the generics system?</div><div dir="auto"><br></div><div dir="auto">In short, the answer ended up being no. They felt like the amount of complexity and the new issues plus level of effort to implement this. So, JEP withdrawn forthe time being.</div><div dir="auto"><br></div><div dir="auto">I could be wildly wrong here, but at least it feels like it makes sense lol.</div><div dir="auto"><br></div><div dir="auto">> Regarding that problem, would it work to</div><div dir="auto">> just add "workaround" methods like this?</div><div dir="auto">> </div><div dir="auto">> public static <T extends Enum<T>></div><div dir="auto">> EnumSet<T></div><div dir="auto">> noneOfGeneric(Class<? extends T> klass)</div><div dir="auto">> </div><div dir="auto">> Even though klass has type Class<?</div><div dir="auto">> extends T>, at compile time, you're not</div><div dir="auto">> going to be able to specify any Class</div><div dir="auto">> constant other than the top enum class,</div><div dir="auto">> so no problem there, and at runtime, this</div><div dir="auto">> method could do introspection to find the</div><div dir="auto">> top enum class (if necessary; unlikely)</div><div dir="auto">> and then use that.</div><div dir="auto"><br></div><div dir="auto">I am not sure. To my understanding, this would likely fail for the same reasons why noneOf failed. It's failing because it doesn't know how to handle heterogeneous types in a generic data structure. In this case, your enum is the heterogeneous type, and the EnumSet (or any collection) is the generic data structure.</div><div dir="auto"><br></div><div dir="auto">Thank you for your time and help!</div><div dir="auto">David Alayachew</div></div></div>
</blockquote></div></div></div>