participate


Generics - A plea for a new enum capability
<<   Back to Forum  |   Give us Feedback
This topic has 20 replies on 2 pages.    « Previous | 1 | 2 |
gafter
Posts:669
Registered: 6/25/98
Re: A plea for a new enum capability   
Aug 19, 2003 12:33 PM (reply 15 of 20)  (In reply to #5 )

 
Good try, but this will crash with a null pointer exception because the "lookup" variable is not yet assigned when the enumeration constants are constructed. We're modifying the definite assignment rules to catch this at compile time.
 
gafter
Posts:669
Registered: 6/25/98
Re: A plea for a new enum capability   
Aug 19, 2003 1:06 PM (reply 16 of 20)  (In reply to #10 )

 
Yes, and some clients need specific strings, and
other need specific graphs, etc.


Some uses are much more common than others. If you
can't see that, then it is no longer worth my time
discussing this.

I agree some uses are more common than others. In my experience the uses you have in mind are rare. I've used enums many times but rarely needed the facility you describe. Look at the enums in the implementation of the compiler. Which of those uses would benefit from the facility you describe? If we add an enum for floating-point rounding modes, how will it benefit from this facility?

If you guys don't want to support it - that's fine,
some better language will eventually eclipse Java. For
now, though, I'll just get through the language
limitations like I always do. In this case, it looks
like I'll need an enum bytecode enhancing tool.

If your application domain demands it, then by all means write your own little language. If this facility is so beneficial, then perhaps your enhanced language will eclipse Java. Good luck with that.

By the way, your facility could be implemented as a single interface (which your enumeration types implement) and a single static generic method (to do the work) in some utility class. That, plus one trivial method in each of your enums that you want to support this facility. I'll explain in more detail if it isn't obvious to you how to do it. I don't believe a language change, which is a burden to everyone learning the language, is preferable to you writing this single interface and method, but perhaps there is something about your application domain that I don't understand. In general we tend to avoid language changes when a trivial support library could serve the purpose.
 
brucechapman
Posts:683
Registered: 11/24/98
Re: A plea for a new enum capability   
Aug 19, 2003 3:03 PM (reply 17 of 20)  (In reply to #15 )

 
Good try, but this will crash with a null pointer
exception because the "lookup" variable is not yet
assigned when the enumeration constants are
constructed. We're modifying the definite assignment
rules to catch this at compile time.


Neal, I presume you were talking about this
public enum Watsits {
    a(4),b(3),c(1);
    private static Watsits[] lookup = new Watsits[255];
    private byte encoding;
    Watsits(byte encoding) {
        this.encoding=encoding;
        lookup[encoding + 128] = this;
    }
    static Watsits decode(byte encoding) {
        return lookup(encoding + 128);
    }
    public byte getEncoding() {
        return encoding;
    }
}


I understand what you are saying is that the generated code to initialize the enum constants executes before the other static initializers (in the EnumBodyDeclarations).

I also understand that this is consistent with the rest of the language, where initializers are executed in the order they appear in the source.

BUT in this case the order is imposed by the syntax which says the EnumConstants come before the EnumBodyDeclarations, rather than by the programmer's choice of ordering. In fact, the programmer has no way to specify that the static initializer for the lookup field should run before the enum constants are initialized.

AND if there are static initializers in the EnumBodyDeclarations, then it will almost always be the case that the programmer wants or intends these to run before the enum constants are constructed.

I consider this is a serious flaw in the enum design.

Having the compiler tell you that you have fallen into this hole, is better than a runtime exception, but only just.

Although the EnumConstants must come before the EnumBodyDeclarations for parsing purposes (and should come first on readability grounds), it might be better to state in the spec that the enum constants are constructed AFTER all explicit static initializers. I believe this is a more natural interpretation.

Yes, I know that once I get the compiler error, I can code around this issue with something like

public enum Watsits {
    a(4),b(3),c(1);
    private static Watsits[] lookup ;
    private byte encoding;
    Watsits(byte encoding) {
        this.encoding=encoding;
        if(lookup == null) lookup = new Watsits[255];
        lookup[encoding + 128] = this;
    }
    static Watsits decode(byte encoding) {
        return lookup(encoding + 128);
    }
    public byte getEncoding() {
        return encoding;
    }
}


This is rather inelegant. Whenever programmers do static initialization in enums, they will have to remember to write some extra unusual looking code to "work around" the enum static initialization issue.

Ideally we should be able to control the order of static initializers relative to those implied by the EnumConstants.

One way to do this is to change EnumBody production from

{ EnumConstantsOpt EnumBodyDeclarationsOpt }

to

{ EarlyStaticInitBlockOpt EnumConstantsOpt EnumBodyDeclarationsOpt }

EarlyStaticInitBlock:
static block


to allow a single static initializer block before the EnumConstants declaration.

However I accept that this might be impractical, in which case I think the explicit static initializers should run BEFORE rather than AFTER the implicit static initializers generated from the EnumConstants declaration.

Bruce
 
rreyelts
Posts:568
Registered: 11/12/97
Re: A plea for a new enum capability   
Aug 19, 2003 3:08 PM (reply 18 of 20)  (In reply to #16 )

 
Arrgghhh, being pulled back in...

In my experience the uses you have in mind are rare.

Apparently our experience differs, but I find your example hardly convincing. You're writing a compiler, but not the disassembler (apparently). Since I parse the bytecode you generate, I'll need to have enums which satisfy the magic enumerated constants that go into your generated bytecode. Since you're not writing/maintaining javap, you're in the unusual situation that you're not having to read what you write.

write your own little language

How condescending.

Good luck with that.

Unfortunately, there's not enough of me to go around, because I'm already wasting too much of my time fixing things that suck about Java - i.e. JNI.

In general we tend to avoid language changes when a trivial support library could serve the purpose.

Smart in principle, not-so-smart in practice (at least when ignoring the common usecase).

As a totally off-topic rant, I'd also like to state that the verifier for Sun's virtual machine is perhaps the least informative checking mechanism I've ever seen for any language. Perhaps someone there could get it to report something more informative than "this class is invalid." ? I wish I could just fall back on BCEL's verifier, but it's too buggy and too strict to be useful.

God bless,
-Toby Reyelts
 
gafter
Posts:669
Registered: 6/25/98
Re: A plea for a new enum capability   
Aug 19, 2003 3:48 PM (reply 19 of 20)  (In reply to #17 )

 
AND if there are static initializers in the
EnumBodyDeclarations, then it will almost always be
the case that the programmer wants or intends these to
run before the enum constants are constructed.

On the contrary, I have seen many examples of exactly the opposite:

    enum Color {
        red, green, blue, ultraviolet;
 
        public static final Color DEFAULT = blue;
        public static Color[] visible = {red, green, blue};
    }


With the compiler preventing you from shooting youself in the foot, things aren't so bad. Your proposed solution isn't the most elegant, though I admit you probably copied it out of something I wrote in the compiler. I suggest the following, based on the design principle that the constructor should do no more than construct:

public enum Watsits {
    a(4),b(3),c(1);
    private byte encoding;
    Watsits(byte encoding) {
        this.encoding=encoding;
    }
 
    private static Watsits[] lookup = new Watsits[255];
    static {
        for (Watsits x : VALUES)
            lookup[x.encoding + 128] = x;
    }
    static Watsits decode(byte encoding) {
        return lookup[encoding + 128];
    }
}


Now that wasn't so bad, was it?
 
brucechapman
Posts:683
Registered: 11/24/98
Re: A plea for a new enum capability   
Aug 19, 2003 4:28 PM (reply 20 of 20)  (In reply to #19 )

 
AND if there are static initializers in the
EnumBodyDeclarations, then it will almost always be
the case that the programmer wants or intends these to
run before the enum constants are constructed.

On the contrary, I have seen many examples of exactly
the opposite:

    enum Color {
        red, green, blue, ultraviolet;
 
        public static final Color DEFAULT = blue;
public static Color[] visible = {red, green,
 green, blue};
    }

Good example - point conceded.


With the compiler preventing you from shooting youself
in the foot, things aren't so bad. Your proposed
solution isn't the most elegant, though I admit you
probably copied it out of something I wrote in the
compiler.

You flatter yourself. I don't need your help to **** things up. I need your help when I **** things up. In this case you have done just that. Thanks.


I suggest the following, based on the
design principle that the constructor should do no
more than construct:

public enum Watsits {
    a(4),b(3),c(1);
    private byte encoding;
    Watsits(byte encoding) {
        this.encoding=encoding;
    }
 
private static Watsits[] lookup = new
new Watsits[255];
    static {
        for (Watsits x : VALUES)
            lookup[x.encoding + 128] = x;
    }
    static Watsits decode(byte encoding) {
        return lookup[encoding + 128];
    }
}


Now that wasn't so bad, was it?

Not once I get my head around the fact that "in enums, all instantiation happens before any static initializers".

Thanks.

Bruce
 
This topic has 20 replies on 2 pages.    « Previous | 1 | 2 |
Back to Forum
 
Read the Developer Forums Code of Conduct

Click to email this message Email this Topic

Edit this Topic
  
 
 
Forums Statistics
    Users Online : 26
  • Guests : 129

About Sun forums
  • Sun Forums is a large collection of user generated discussions. It is here to help you ask questions, find answers, and participate in discussions.

    Check out our guide on Getting started with Sun Forums for a full walkthrough of how to best leverage the benefits of this community.

Powered by Jive Forums