On Tue, Dec 8, 2020 at 10:14 AM Larry Garfield <la...@garfieldtech.com> wrote: > > > Hi Paul. Although we're on hold for a bit while Ilija makes some changes in > direction (see previous email)
I'm looking forward to seeing the results. > > Enumerations, as a general concept, are stateless. Or rather, the idea of > state doesn't even apply to them. They're (enumerated) lists of things. You need a way to make a list, identify an item as being on the list, and differentiate it from other items on the list. > The integer 5 doesn't have any state of its own. All instances of the > integer 5 are logically identical to all other instances of the integer 5. For simple types like integers, sure. Objects however can carry additional data around without interfering with identifying or differentiating them. It doesn't matter if object 5 has my address book, is wearing a funny hat, or just cached the results from a bunch of expensive method executions - you can still identify it and distinguish it just fine. > That the PHP RFC for enums uses objects internally is incidental. This is a complete reversal from what you've otherwise written in and about the RFC. > So if you're defining, say, an enum for cardinal directions (North, South, > East, West), There are literally only 4 possible values for that type, and > those values must always be equal to themselves. Attaching "5 miles" to > "South" in one script and "2 km" to "South" in another script is nonsensical, > just like attaching "feet" to the number 5 and later changing it to "fingers" > just doesn't make any sense at all. Whether or not an object holding other data makes sense is irrelevant to enums. Take it up in code review. > It is true that, if you're attaching operations to enum cases that have no > state, a method, a static method, and a constant are often interchangeable. > A constant is strictly less capable since it cannot have logic, but a method > and static method are functionally equivalent. The reason for forbidding > static methods and constants is largely simplicity. You've significantly added to the WTF factor and edge cases when working with them. For example enums can implement interfaces. Except interfaces with constants. Or maybe you can implement interfaces with constants, you just don't inherit the constants. Wait no that'd break type declarations. Perhaps then you can inherit constants from interfaces but you still can't declare them yourself. So the way to use constants in enums is to declare them on an interface and implement that to inherit them. Maybe. This isn't simplicity. None of these options makes working with enums better. Whether you prefer constants, static methods, or instance methods isn't even relevant to enums. Again take it up in code review. > For example, the change I just discussed in my previous email about switching > to a single class with instances as constants means that static methods can > only be on the enum (Suit), because there is no per-case-class to put them on > (Diamonds). The same is true of per-instance constants. If we'd promised > that those things worked, we wouldn't be able to make this change. The thing never shipped, you can make any change you want. If you're pretending it did ship then you couldn't make that change anyway without breaking instance methods so your point is moot. > If when the dust settles there's a good reason to expand the functionality > further in ways that still don't violate "South === South," (such as adding > constants to the enum type itself, perhaps) those can be considered at that > time. As you've said elsewhere: > Because enums are based on classes, there's not really any added complexity. > They inherit the ability to have methods from being classes. It would be more > work to separate it. The same holds for constants, static methods, properties, (traits? do these even work? some of them?) This isn't about adding functionality, it's about not arbitrarily removing it. > As both Rowan and I mentioned, the long-term plan includes future RFCs for > other functionality such as tagged unions. If you want state, I want a coherent enum RFC that isn't complicated by unrelated personal preferences being shoehorned into it. If you want to make an RFC to deprecate class constants in favor of methods - fine, but at least make the RFC about that. Trying to wedge it in here half-assed only creates problems. > then what you want is not an enum but a tagged union. You're saying this as if they're necessarily different things. > For whatever reason, most languages with tagged unions seem to build them > into and onto enums. Languages that implemented enums such that they function as tagged unions saved themselves the effort of making the same thing twice. They also saved their users from dealing with whatever subtle differences would've been included to distinguish them. > I'm not entirely sure why, and I'm honestly not 100% convinced that's the > right approach in PHP, but that's a debate for a future RFC. Any debate about enums is appropriate for this RFC. > Within the scope of this RFC, enums must always obey "South === South", and > thus must be stateless. South === South can hold with or without state and isn't even required for enums. All you need is to know it's on the list and for it to be distinguishable from others on the list. > > Longer term plans are irrelevant except to avoid inadvertently > > shutting the door on something. This RFC is up for discussion, and > > will be up for voting, in isolation. It has to be able to stand on its > > own. > > This is true up to a point. The point is nothing in the RFC is contingent on the others. If this RFC passes and none of the others do, or none of the other work gets done, that has to be okay. This means treating this RFC on its own. As you said at the beginning: > The overarching plan (for context, NOT the thing to comment on right now) Yet you keep bringing it up... > Explicitly setting up a series of RFCs like we're doing is, as far as I am > aware, novel for PHP. It's the correct way to handle a larger task like > this, however, especially when there clear division points that "chunk" the > work in natural ways. Even if enums in this RFC are the only thing that > passes, that's still a major win for PHP. It's not as big a win as tagged > unions with robust pattern matching and generics on the side would be, but > it's still a big step forward. By breaking it into chunks, we make it more > likely that as much as can be done will get done, and approved, and into the > language, even if the end result is the same feature set when 8.1.0 gets > tagged. > > --Larry Garfield > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php