Am 05.12.20, 16:08 schrieb "Larry Garfield" <la...@garfieldtech.com>:

    On Sat, Dec 5, 2020, at 8:21 AM, Marc Bennewitz wrote:
    > 
    > * How can you access a defined case value? 
    >   Something like `Suit::Spades->value()`

    At the moment it's only accessible via the ::cases() method.  It may be 
appropriate to yoink the ->value() or ->value name to access it another way.  
We're debating that right now.

    The primitive equivalent case is tricky, because other languages have about 
14 different ways to think about it, all of them in the end incompatible. :-)  
We know we don't want to just have "fancy constants," but for those cases you 
do want/need a primitive instead (mainly writing to a DB or screen) it needs to 
be easy enough to get that.  There's a number of competing priorities we're 
trying to balance here to make the DX as clean as possible.

For me it doesn't really matter how to get the primitive value as long as there 
is a simple way to do so.

As you wrote
> Passing a Primitive Case to a primitive-typed parameter or return will 
> produce the primitive value in weak-typing mode, and produce a TypeError in 
> strict-typing mode.
This would already break simple function calls like the following on strlen

enum Suit: string {
  case Hearts = 'H';
  ...
  public function label(): string { return 'Label of ' . $this . ' with  length 
' . strlen($this); }
  // or more clear in my opinion
  public function label(): string { return 'Label of ' . $this->value . ' with  
length ' . strlen($this->value); }
}

    To also respond to Pierre here, at present the primitives must be unique.  
We want to minimize the boilerplate that people have to write on every enum for 
common cases, and the cases() method is part of that.  It won't capture 
everything, obviously, but if the common cases can be made trivial and the rare 
cases possible, that's a win.

I agree here that the defined primitives needs to be unique as well.


    > * Do cases have a stable ordinal number / position and is that 
    > accessible?
    >   This would be very interesting on implementing an optimized EnumSet 
    > using bit-array / bit-set internally

    The order returned from cases() is stable as lexical order, but there's no 
ordinal number to access.  If you want a bit set, you could do:

    enum Permissions: int {
      case Read = 0x1,
      case Write = 0x10,
      case Exec = 0x100,
    }

    Right now there's no support for case ReadWrite = self::Read | self::Write. 
 I don't know if that would be easy to add in the future, but I'd be OK with it 
if so.  Mainly this runs into the same tricky questions around primitive 
equivalent handling (and what we can coax the lexer to do).

    > * Is it possible to detect / type-hint if something is any enum?
    >   ` Suit::Spades instanceof Enum`
    > 
    >   This basically means that all enumerations would to based on a 
    > general enum.
    >   This would be very helpful on providing functionalities especially 
    > for enumerations thinking about a doctrine enumeration type or again an 
    > EnumSet / EnumMap.

    Not at the moment.  We're discussing the implications of adding that.

    What exactly are EnumSet and EnumMap, in your mind?

An EnumSet is a set (unique cases) of the same enumeration type.
An EnumMap maps cases of the same enumeration type to another value.

The interesting part here is that this can be done in a very efficient way 
without the need to iterate over it.
Like you have defined an enumeration of 200 countries

enum Country: string {
    case USA = 'US',
    case Germany = 'DE',
    case Australia = 'AU',
    ...
}

$set1 = Country::USA | Country::Germany; // EnumSet<Country> of [Country::USA, 
Country::Germany]
$set2 = Country::USA | Country:: Australia; // EnumSet<Country> of 
[Country::USA, Country::Australia]
$set3 = $set1 & $set2; // EnumSet<Country> of [Country::USA]
$set4 = $set1 & ~$set2; // EnumSet<Country> of [Country:: Germany]

This could of course also be done without operator overloading but it looks 
very clean with them __
All done internally using bit operations __


Greetings Marc


    --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

Reply via email to