
On Fri, Jul 29, 2011 at 6:13 AM, Steven D'Aprano <steve@pearwood.info> wrote:
I don't even know what these "enums" actually are any more. Part integer, part string, part namespace, part named constant (only not actually constant)... It seems to me that people are trying to dump a whole lot of only vaguely related functionality into a single concept. Including now a proposal to encourage monkey-patching modules by making it an official enum method.
For something that is conceptually so simple, this is becoming awfully complicated.
Yeah, until this thread reminded me, I'd actually forgotten my own reasons for objecting to standardising enums in the past and proposing named values instead. I think it mostly has to do with degrees of freedom in the design. With named values, there are only a few elements that require explicit design decisions: - ints only, or arbitrary types? (my recipe is designed to work with arbitrary types) - effect on repr() (my recipe modifies it to include a name without breaking any existing repr/eval round trip support) - effect on ascii() (inherits the repr() change, since ascii() is just repr() with a post-processing step) - effect on str() (my recipe makes sure to leave it alone to maximise compatibility) - effect on serialisation (my recipe makes sure to leave it alone to maximise compatibility) - effect on everything else (my recipe makes sure to leave it alone to maximise compatibility) If any application or library wants to name values retrieved from elsewhere (including previously pickled or serialised named values) then it is up to them to apply the transformation at the input points (e.g. a HTTP support library might create a mapping from server response codes to named values, but those values would still be serialised as ordinary integers). It's a (relatively) simple, flexible technique to improve introspection without being overly prescriptive about how to use it. Most design decisions are handled by the basic rule that named values *are* functionally the same as the bare value, they just happen to have been given a specific name that is available for introspection (and is included in the default repr output). Once you take the step up to the enum level and start dictating the *grouping* behaviour along with the naming behaviour, then a whole host of other design issues arise (in addition to the ones that arise for general purpose named values): - behaviour of identity comparisons - behaviour of equivalence comparisons - behaviour of ordering comparisons - behaviour of isinstance checks - API for explicit conversions to and from the underlying type - whether or not to support implicit conversions to and from the underlying type - how to introspect the group contents By giving up the "this is just an ordinary value with a name" design guideline, enums get into a lot of highly arguable territory. Guido *could* cut through that by BDFL fiat if he wanted to, but I'm not sure he *should* - depending on the use case, the preferred answers to some of the design decisions mentioned above are going to legitimately vary. Regards, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia