32

I was reading some code here and saw that an enum is used to store names of html tags. Why do we ever need to do this? What benefit do I get using this strategy?

I know that how useful enums are in compiled or statically typed languages but when I see enums in dynamically typed languages I get curious, like the example code I showed above. So, the question basically boils down to why do we need enums in dynamically typed language or do we need them at all?

  • 38
    This question is basically "Why do we need types". – user11153 May 9 '16 at 19:22
  • 1
    Did you search the repo to see how it's called? That would likely give you a better understanding of the answers you received. – RubberDuck May 9 '16 at 22:28
  • if you have: enum People { YOU, NPC, FOO, BAR } and a function that wants a (People)int, you can plug whatever, instead of using a number. – Evan Carslake May 9 '16 at 22:58
  • 3
    Are you asking about the purpose of this particular "enum" or about the purpose of enums in general, in any language? I'd assume the former, but all current answers seem to think the latter ... – meriton May 9 '16 at 23:06
56

A benefit is that the compiler can let you know if you accidentally type "ADRESS" or "FEILDSET", and letting you fix it immediately instead of behaving in a nonsensical way at runtime.

While the benefit is much more useful in statically typed languages than dynamic, it is still useful even if it is a runtime error as you will get message indicating a problem with your case statement rather than your data.

  • 4
    @amon: you could, but enums gives you a handy mechanism to ensure you don't have collisions. – whatsisname May 9 '16 at 16:40
  • 75
    A place I used to work for once spent a month chasing a bug caused by someone's bright idea to use string constants instead of enums, poor editor fonts, and a field accidentally named "PROF1LE_" – Steven Burnap May 9 '16 at 17:03
  • 8
    @amon Go does exactly this. One nice thing about enums, however, is that the compiler can check that your switch statement has a case for every possible enum value. – weberc2 May 9 '16 at 20:00
  • 15
    This code was written in the 80s. You may not realize this, but this was in an era when some developers learned to develop on physical typewriters, which may not have had a one key. Though actually I realize that the string in question was "Profi1e"...it's been twenty-five years, so my memory is obviously not perfect. – Steven Burnap May 9 '16 at 22:21
  • 4
    @DarrelHoffman: I'm surprised that you're surprised. In Perl, I frequently find myself typing $1 when I mean $i. (Granted, I never type f1le instead of file -- the $1 mistake is primed by the fact that $1 is very common in Perl -- but still, mistakes of all sorts are common. Maybe the dev had a password with prof1le in it, thereby priming them to mistype profile in non-password contexts.) – ruakh May 9 '16 at 23:45
22

Enums are useful for situations where you have a fixed set of values/entities that are sensible. They are self-documenting and allow the compiler validate things that would otherwise be left to run-time. They should never be used if the set of meaningful values is not known or not strictly limited.

A more useful example would be something like HTTP response codes. Instead of having a method that takes a number and provides the name and/or description of the error, you can have a set of enums with meaningful names, a code and a description etc. in one clean package that is authoritative in what values are allowed and need to be handled.

  • 1
    "Self-documenting" is the most important part. I'd much rather check if status === GEOLOCATION_ACQUIRED than status === 3, so that the person who maintains that software understands what's going on. As you said, it also prevents invalid values. – Nicolas Bouliane May 18 '16 at 8:55
11

Enums have nothing to do with OOP, and JavaScript doesn't have enums. Instead, enums are used whenever there is a choice between a fixed set of values. For example, a boolean is a choice between true and false, which could be implemented as enum Bool { False, True }. In a GUI library, we might have an enum for alignments: enum HAlignment { LEFT = -1, CENTER = 0, RIGHT = 1 }.

It is usually irrelevant how the enum is implemented, the important part is that each possible value is distinct. Many languages use integers for enums, though some like Java support arbitrary objects.

Until now, we could just as well have used constants, e.g. const int LEFT = -1, CENTER = 0, RIGHT = 1. However, a compiler knows that the enum values belong together. So when I switch over the enum values switch(value) {case LEFT: ...; case RIGHT: ...;}, the compiler can warn me that I have forgotten the CENTER case. This can be a substantial time saver. In languages without enums or without a switch-case construct, this can be simulated with the Visitor Pattern, though that is more helpful in the presence of static typing.

The other advantage is that enums can be treated as a separate type. E.g. I can declare that a method takes an HAlignment parameter, rather than any integer. The code will then fail to compile if I provide anything but one of the three possible HAlignment values. However, C's enums aren't well encapsulated and the enum constants can be used interchangeably with integers. Other languages are stricter here.

In JavaScript, we get none of these benefits. The given example declares an object that is treated as an enum. This does have some advantages for the programmer, e.g. it makes documentation easier, groups all the “constants” into a single object, …. However, it is just a convention that such an object is enum-like.

The point here is that HTML only has a finite and known set of tags. You can look at the HTML5 specification and put those element names as an enum into your code, and therefore make it more difficult to sneak a <blink> tag into your program. It is better to encode this knowledge in one place that to litter your code with special string literals (or worse, magic numbers).

  • In that case if I pass <blink> to some method in javascript nothing could stop me right? but in java hello breaks loose :) – CodeYogi May 9 '16 at 17:13
  • @CodeYogi yes, because JS does not have a static type system, and in particular has no concept of enum types. However, I can document a method parameter as “takes a TagName”, which would lead a programmer to invoke it as foo(TagName.STRONG) which is a bit better. It would be even better if JS would complain if the field does not exist, but here we only get an undefined if I try TagName.BLINK. It's not worth much in JS, but it's a start. – amon May 9 '16 at 17:18
  • Hmm, the code link I mentioned above uses closure compiler hence makes sense there. – CodeYogi May 9 '16 at 17:24
  • Clojure is a functional language so I'm not sure how OOP is relevant to the question but that aside, it's important to distinguish between enums which are generally just a set of integers (not OO) and the 'Typesafe enum' pattern which is OO and what Java supports. – JimmyJames May 9 '16 at 17:31
  • @JimmyJames I'm talking about JS, not about Clojure (which, running on the Java platform, also supports OOP to some degree). The question was tagged with oop, which is why I mention it in the beginning. I don't really see how typesafe enums are connected to OOP, that's just a type system feature (many non-OOP languages have type systems :-) ) – amon May 9 '16 at 17:36
3

Even if your language doesn't require compilation, you'll probably use some kind of IDE or development tools, that can give much better support for something like an enum than just for strings.

If you use an enum like object literal in javascript for example, your editor will give you code completion and your code checker like JSHint or JSLint will warn you, if you accidentally use the wrong value.

  • I think a lot of the other responses either miss or beat around this point. Using an 'emum' in a dynamic language may not do anything for a compiler, but it can really help certain IDEs, documentation tools, and also don't forget humans who are attempting to understand the code. – Robert May 10 '16 at 18:19
2

The point of such enum might be to provide Js Api (goog) a set/bundle of allowed tags. Which ones? The ones defined by W3C HTML 4.01 (check out enum's documentation). So it's settings boundaries.

Might or might not be this the real goal, however it would works fine for such purpose.

If you know how Javascript works, what code is doing is defining an array indexed by strings :-). Which value is a string, but it could be any other component with attributes, functions, etc... Let your imagination run free and you will see benefits everywhere.

Javascript aside, I use enums a lot for modeling and managing state machines.

START > IN_PROGRESS > CONFIRMED > FINISHED > ...

In java switch allows enums so is quite easy to validate states into a state machine, to loop all over the enum, to define priorities by doing complexed enums, ...

I also use them to define typed and unmodoficable constants:

  • Yes, No

Also complex enums (which allows to do secure transforms/parsers)

  • Yes(1,true), No(0,false)

Due to enums often belongs to my model layer (core), its features are accessible to all over the system, so it becomes a functional model and I keep a low coupling.

What enums gives (among other things) is boundaries and typification

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.