News for hackers. Stuff that matters.
Re:Using Enumerated Types in Python by elcomet on Saturday June 06, 2020 @01:53PM (#23440972)
Enums are best when combined with a language that does pattern matching and that can warn you if you forgot a value in your case statement. Python lacks this, so there is no spectacular benefit of using enums over just a list of strings.
Re:Using Enumerated Types in Python by silviogutierrez on Saturday June 06, 2020 @01:58PM (#23441023)
Agreed on pattern matching, though mypy can help a lot here with exhaustive checks at the very least. They do work on enums and discriminated unions. They should document it:

https://github.com/python/mypy/issues/6366

https://github.com/python/mypy/issues/5818

Re:Using Enumerated Types in Python by zo1 on Saturday June 06, 2020 @02:24PM (#23441243)
The article is incredibly misleading. Python Enums are way more powerful than what is showcased there.

First, rudimentary/basic enums are as simple as instance variables on a class and allow super-helpful IDE "auto-completion" that doesn't necessitate the use of magic-strings to at least "set" the enum. I've been using this ridiculously simple trick since 2.5 ten years ago. Magic-strings are bad, and even worse when you have a disparate code-base in a dynamically typed language. Example:

    class MyEnum(object):
        Pass = 1
        Fail = 2

    my_value = MyEnum. <-- at this point, the IDE gives you code-completion.

Second, real Enums added as a language-feature along with type-hinting are almost 100% on-par with statically typed languages. See:

    class MyEnum(Enum):
        Pass = 1
        Fail = 2

    def my_func(did_they_pass: MyEnum):
        if did_they_pass.Something:   # IDE / type-checker will go nuts here.
            print("Something")
Edit: Forgot the main point. Switch/case uses are only a small sub-set of the uses of Enums. So even basic/crappy enums are better than magic strings in a dynamically-typed language. Also, please don't use "list of strings" for enums in Python, there are much better ways to do that sort of thing that preclude unnecessary bugs popping up.
Re:Using Enumerated Types in Python by BiteCode_dev on Saturday June 06, 2020 @03:18PM (#23441577)
So, you don't use open("w"), do you ? You use the non magic open(os.O_WRONLY) of course.

Because magic strings are bad.

Re:Using Enumerated Types in Python by MikeTheGreat on Saturday June 06, 2020 @03:42PM (#23441718)
I will now - thanks for the tip! :)

And, moreover, this will inspire me to ask "How many other traditional magic numbers/strings/etc have I gotten used to that might be defined more readably?" strcmp, I'm looking at you!

I know your post was sarcastic/snarky but it was genuinely helpful

Re:Using Enumerated Types in Python by 1wd on Saturday June 06, 2020 @05:19PM (#23442311)
f.tell(offset, os.SEEK_CUR) over f.tell(offset, 1)

https://docs.python.org/3/library/os.html#os.SEEK_CUR

I wish the docs on f.tell at least mentioned the option

https://docs.python.org/3/tutorial/inputoutput.html#methods-...

Re:Using Enumerated Types in Python by remram on Saturday June 06, 2020 @10:25PM (#23444267)
Except it wasn't, os.O_WRONLY is for os.open() (equivalent of open syscall, takes numeric flags), not the built-in open() (equivalent of C fopen, takes "w" and similar strings).
Re:Using Enumerated Types in Python by comfydragon on Saturday June 06, 2020 @03:36PM (#23441687)
Python 3.8 has typing.Literal for this.
Re:Using Enumerated Types in Python by zo1 on Sunday June 07, 2020 @07:20AM (#23446577)
That's a fair point, and I'll be sure to keep an eye out for that type of magic-string usage going forward. Though most "magic string" usages are not nearly as official as the one you mention and usually occur in business-level code written by ordinary developers that may not be disciplined or experienced. Those spots most certainly need all the assistance they can get instead of relying on magic-strings, hence my comment of magic strings being bad.
Re:Using Enumerated Types in Python by 1wd on Saturday June 06, 2020 @05:23PM (#23442342)
You would have to use os.open
Re:Using Enumerated Types in Python by BiteCode_dev on Sunday June 07, 2020 @03:46AM (#23445555)
I would also have to pass the path as a first param. This was not meant to be correct, just teasy.
Re:Using Enumerated Types in Python by andrepd on Saturday June 06, 2020 @05:07PM (#23442231)
>Second, real Enums added as a language-feature along with type-hinting are almost 100% on-par with statically typed languages

This is conclusive proof that you're not actually aware of the capabilities of enums and sum types in "statically typed languages". Where's pattern matching? Exhaustivity checking? Sum types? GADTs?

Re:Using Enumerated Types in Python by rumanator on Saturday June 06, 2020 @07:50PM (#23443401)
C and C++ don't have some features in that list like pattern matching and there is no question that they represent one of the most popular statically typed languages in history.
Re:Using Enumerated Types in Python by zo1 on Sunday June 07, 2020 @07:27AM (#23446613)
Honestly, over my nearly 20 year period of programming experience (half of which was not spent on python), I can't recall ever having encountered those terms/concepts. But on the plus side, I guess I have now and I'll be sure to read up on them. Maybe I know the concepts but haven't linked them to the terms.
Re:Using Enumerated Types in Python by guest2143 on Monday June 08, 2020 @05:43PM (#23461141)
Python 4... It's just going to be Haskell.
Re:Using Enumerated Types in Python by throwgeorge on Saturday June 06, 2020 @02:27PM (#23441257)
>real Enums added as a language-feature along with type-hinting are almost 100% on-par with statically typed languages

sorry i don't understand this. i'm not trying to be pedantic but: statically typed (and type-checked) language will fail to compile ... not just warn you. that's not a 1% difference that's the entire difference (because lots of people will miss or flat out ignore ide hints).

Re:Using Enumerated Types in Python by rumanator on Saturday June 06, 2020 @07:47PM (#23443375)
> Python lacks this, so there is no spectacular benefit of using enums over just a list of strings.

Enums represent a discrete set of constant values. They are extremely helpful to communicate to developers what to expect from a component. Lists of strings do not come near to offer the same functionality.

Re:Using Enumerated Types in Python by zem on Saturday June 06, 2020 @04:25PM (#23441974)
there are several benefits to using named constants over literal strings, and enums give you namespaced named constants
Re:Using Enumerated Types in Python by nerdponx on Saturday June 06, 2020 @05:41PM (#23442461)
Not only that, but both static type-checking (with appropriate tooling) and convenient runtime membership checks.
Re:Using Enumerated Types in Python by oflannabhra on Saturday June 06, 2020 @04:53PM (#23442135)
Agreed. I’ve currently switched from Swift to Python and keep reaching for Swifts expressive enums and awesome pattern matching.
Re:Using Enumerated Types in Python by BerislavLopac on Sunday June 07, 2020 @04:09AM (#23445661)
I disagree. A list of strings requires manual validation whether a value is actually in the list; enums have that built in. Additionally, enums (at least in Python) can have behaviour associated with each value, which can be useful in many contexts.

There are also good reasons why Python does not have switch/case statements, which are generally an anti-pattern; they work fine for a quick fix, but what they do is better solved with proper polymorphism.

Re:Using Enumerated Types in Python by crimsonalucard1 on Saturday June 06, 2020 @02:03PM (#23441051)
There's a benefit in the cardinality during type checking when you use an external type checker. Strings have infinite possibilities an enum type is strictly defined.

Also I'm sure with reflection you can actually implement a simple enum pattern matching function on an enum that is exhaustive and throws a runtime error immediately if every possible enum case is not covered.

Re:Using Enumerated Types in Python by zo1 on Saturday June 06, 2020 @02:30PM (#23441284)
I'm not following this thread at all. What "exhaustive search" are you guys referring to? In a switch/case block? Python doesn't have that, unless I missed it while living under a rock.

I.e. if you're working with python Enums, you type-check for that Enum, and then the IDE does it all for you. If you want to "check" for a specific enum, then you cast to it and the runtime Enum implementation does that checking for you by throwing an error if you try create that Enum with an invalid string value. And if you've got a raw string, before it goes too-far into your code base, you cast it into the specific Enum type, and when serializing you serialize it to the string value. Easy-peasy.

Re:Using Enumerated Types in Python by tobywf on Saturday June 06, 2020 @02:59PM (#23441480)
AFAIK, they're talking about languages like Rust, or C/C++ with `-Wswitch` (also implied by `-Werror`, which will warn you if you haven't handled all enum cases in a match/switch statement.

as someone else in this thread pointed out [0], it's possible with MyPy when using if/elif/else, or if you did it with a dictionary lookup, you could write a very simple test that checks that the set of enum values is equal to the dictionary key members. I've done this before, it works well [1].

[0] https://news.ycombinator.com/item?id=23441023 [1] https://github.com/aws-cloudformation/cloudformation-cli/blo...

Re:Using Enumerated Types in Python by icegreentea2 on Saturday June 06, 2020 @03:01PM (#23441489)
In some typed/compiled languages, a substantial benefit of using enums is that it provides some way to automatically determine if you've handled every eventuality. That's super not a part of normal Python as you've mentioned.

The second part of crimsonalucard1's post was referring to somehow hacking in that type of functionality into Python.

I think you could somehow do that with nested context managers - something like:

  with EnumChecker(e) as checker:
    with checker(enum_type.A):
      # do thing
    with checker(enum_type.B):
      # do thing
    ...
Where `e` is an instance of `enum_type`, and the inner context managers acting as if/case statements, then you could on any single execution of the code block (so you only need a single test case) ensure that you covered all states.
Re:Using Enumerated Types in Python by crimsonalucard1 on Saturday June 06, 2020 @04:14PM (#23441912)
imagine an enum called bool with two values: True and False.

  switch(value: bool):
     case True:
         // do something
     case False:
         // do something else
  end

The above code is exhaustive in the sense that the logic covers all possible values of the enum type. The "exhaustive matching" we're talking about is similar to a pre runtime type check.

So imagine where someone writes this code:

  switch(value):
     case True:
         // do something
  end
The user did not handle the False case in his logic. Exhaustive pattern matching will catch this before the program runs and throw an error similar to a syntax or type check error. It will say that your switch function needs to handle all possible cases of bool. It needs to handle True AND False not just True.

The power of this basically allows you to encode safety of if else logic into a type and pass that safety throughout your program. It's pretty incredible, so much so that whenever this feature is part of a language I have stopped using if else statements almost completely.

Keep in mind the power of pattern matching extends beyond just exhaustive enums. An int is a form of enum as well:

     switch(value: int):
        case 0:
           // do something
        case >0:
           // do something else
     end
with powerful pattern matching features the compiler should immediately let you know that your switch statement did not handle the case "<0".