Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-02-01 Thread Bob Weinand
> Am 29.01.2021 um 18:15 schrieb Larry Garfield 
> :
> 
> And we're back again.  The RFC has been updated with a steady stream of 
> smaller improvements based on feedback and testing, and is now in its Final 
> Form(tm) (we think).  The only major change worth noting is that we renamed 
> things. :-)
> 
> An enum with no scalar backing is now called a Pure Enum, made up of Pure 
> Cases.  One that does have backing values is called a Backed Enum, made up of 
> Backed Cases.  That change is mainly to allow for future expansion to 
> non-scalar backing static values, should the use case arise.  Reflection was 
> also reworked a bit to make it more logical.
> 
> https://wiki.php.net/rfc/enumerations 
> 
> At this point, Ilija and I consider the RFC done and ready for a vote.  
> Baring any major issues being brought up, we plan to start the vote in the 
> first half of next week, probably Tuesday-ish.  If you have any other bug 
> reports or tweaks, please speak now or forever hold your patches.

Hey,

There is a single point in the RFC which is unreasonable to me, which is 
barring static properties.
I do not consider static properties to be handled the same than normal 
properties. It's perfectly reasonable to prevent normal instance properties if 
we want [pure] enums to be stateless (which makes sense).
It however does not make sense to arbitrarily restrict static properties. In 
the end a static property (on final classes at least) is mostly a nice way to 
express global state, which could be written "global 
$my_namespaced_enum_class_prop_name;" and used then. It's just that 
self::$prop_name is much more readable and user-friendly, including for types 
and static analysis.

I also agree with Nikitas note that IterableEnum is really a suboptimal name. 
If you want to highlight finiteness, maybe call it FiniteEnum. UnitEnum would 
be fine too.

Thanks,
Bob

> --Larry Garfield
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php 
> 


Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-01-25 Thread G. P. B.
On Mon, 25 Jan 2021 at 02:29, Larry Garfield  wrote:

> Aside from some nitpicking around reflection and possibly fiddling with
> the naming of "Scalar Enum" et al, we're closing in on the final version.
> It will probably go to a vote in the not too distant future.
>
> --Larry Garfield
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>

Most of this has already been communicated off list but I ought to make my
opinions on the proposal somewhat "official".

Although I do think we need enums backed into PHP, I'm really not keen on
piggy backing on objects.
I'm also aware that this would be a larger undertaking as using objects as
one would need to rewrite part of the logic objects use.
However, looking at how much of the objectness needs to be blocked and/or
modified (traits, final, no properties, etc.), IMHO, points towards a new
zval structure instead of reusing objects, at least for the simple cases as
a simple enumeration set or a scalar backed enumeration set which don't
need any methods.
Moreover, the implementation details of it leak quite a lot and I'm not
really a fan of having the reflection class of enum extend the class one.

My reasoning is that, albeit extremely clunky, one can already achieve the
kind of enumeration proposed here in userland, in a type safe fashion, in
PHP 8.0 by using union types:

final class Heart {}
final class Clubs {}
final class Spades {}
final class Diamond {}
final class Suit {
public function __construct(private Heart|Clubs|Spades|Diamond $value)
{}
public function value() { return $this->value; }
}

This form is basically reducing an ADT to an enumeration, and in any case
introducing additional syntax to alleviate the verbosity of this is a
separate concern.
(to see this somewhat in action I've written some slides for small
university talk which demonstrates how it can be used [1][2]).

The final concern, which might be non-existent as there is no mention of it
in the RFC, is OPcache.
My understanding of OPcache is fairly limited, but IIRC caching and
optimizing things around objects is extremely complicated if not at all
impossible, wouldn't this rather severe limitation also apply to enums,
even for basic lists?
Or are all the objectness restrictions placed on enums sufficient to make
this a non-issue?

As such, unless convinced otherwise, I don't think I will personally
support this proposal.

Best regards,

George P. Banyard

[1]
https://slides.com/girgias/reflection-algebraic-data-types-for-mortals#/5/5
[2]
https://slides.com/girgias/reflection-algebraic-data-types-for-mortals#/5/6


Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-01-24 Thread Larry Garfield
On Mon, Dec 28, 2020, at 2:21 PM, Larry Garfield wrote:
> Hello, Internalians!
> 
> After considerable discussion and effort, Ilija and I are ready to 
> offer you round 2 on enumerations.  This is in the spirit of the 
> previous discussion, but based on that discussion a great deal has been 
> reworked.  The main change is that Enumeration Cases are now object 
> instances of the Enumeration class rather than their own class.  Most 
> of the other changes are knock-on effects of that.
> 
> Of particular note:
> 
> * Cases may not have methods or constants on them.  They're just dumb values.
> * Enums themselves may have methods, static methods, or constants.
> * Traits are supported, as long as they don't have properties.
> * The value() method on scalar enums is now a property.
> 
> The full RFC is here, and I recommend reading it again in full given 
> how much was updated.
> 
> https://wiki.php.net/rfc/enumerations
> 
> The implementation is 98% complete; there's still a few lagging bits in 
> reflection, and some opcache bugs that Ilija is still stomping on.
> 
> There are a few outstanding questions listed that we would like 
> feedback on.  We're not entirely certain which direction to go with 
> them, for reasons explained in the RFC.  Input on those is especially 
> welcome.
> 
> Happy New Year.  May it be enumerable.

For those who would like to play the home game but haven't been able to, Tyson 
Andre has build a delightful Wasm version of the enums branch so you can run 
actual code using enums.

https://tysonandre.github.io/php-rfc-demo/enums/

100% credit to Tyson for putting that together.  It's quite slick. :-)  (It's a 
few commits behind but nothing that should impact most testing; just some edge 
formatting around print_r, reflection, and stuff like that.)

Also, while we were at it, we went with the from()/tryFrom() method pair.  No 
one seemed morally opposed to them and there wasn't really a better naming 
convention.

Aside from some nitpicking around reflection and possibly fiddling with the 
naming of "Scalar Enum" et al, we're closing in on the final version.  It will 
probably go to a vote in the not too distant future.

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-01-06 Thread Nikita Popov
On Tue, Jan 5, 2021 at 6:56 PM Larry Garfield 
wrote:

> On Tue, Jan 5, 2021, at 8:26 AM, Nikita Popov wrote:
>
> > Nice work, I like the updated proposal. Some notes:
> >
> > > Similarly, enum names and case names are both case insensitive.
> >
> > I agree that enum names should be case insensitive (like class names),
> but
> > why should case names be case insensitive? The closest analogon to a case
> > would be a class constant, and those are case sensitive.
>
> This is a left over from the earlier draft when Cases were also classes.
> I've corrected it.  Thanks for the catch.
>
> > > All Cases have a read-only property, case, that is the case-sensitive
> > name of the case itself.
> >
> > I can see how this makes sense, but it wouldn't be my first guess as to
> how
> > you access the case name. I'm wondering if using $enumValue->name or
> > $enumValue->caseName might be preferable.
>
> We'll change it to ->name.
>
> > > Scalar equivalent values must be literals. Constants and constant
> > expressions are not supported.
> >
> > Why? This seems inconsistent with the overall language. If I can use a
> > constant expression as a class constant value, why can't I use it as an
> > enum value?
>
> Mostly because it was more challenging to do.  We're fine with including
> it if Ilija can make it work. (Suggestions for him on how to do so most
> efficiently are welcome.)
>

It may be okay to retain the limitation, but in that case the RFC should
include some technical justification for that. It would also be good to
explicitly state whether something like "1 + 1" is allowed, i.e. whether
constant expressions are forbidden entirely, or only those that cannot be
evaluated at compile-time.


> > > ScalarEnum exposes an additional static method from() that is
> > automatically generated.
> >
> > I think it would be good to be slightly more explicit here and call it
> > fromValue(). (We could have fromName() to construct it from a case name,
> > and any number of custom from* named constructors.)
> >
> > > The from() method will up-cast from a scalar to its corresponding
> > Enumerated Case. Invalid scalars with no matching Case will throw a
> > ValueError. There is also a has() method, which will return boolean true
> if
> > a case with that value exists and false otherwise
> >
> > Just a thought, but rather than having has() and from(), it may make
> sense
> > to have from() (throws if invalid) and tryFrom() (returns null if
> invalid).
> > I think a has() method is pretty much useless in isolation, it will
> always
> > be used in a combination of has() and from(), in which case it is better
> to
> > combine them rather than have an implicit contract between them.
>
> Hm, maybe.  My concern is that "try" to me implies "exceptions are
> involved somewhere", since PHP doesn't have the "TryX means nullable
> return" convention that Rust or C# have.
>
> Anyone else want to weigh in?
>
> > > Manually defining a static from() or has() method on a Scalar Enum will
> > result in a fatal error.
> >
> > Or a non-static one :) You can't define a static and a non-static method
> > with the same name in PHP.
>
> Fixed.
>
> > > Enums and cases may have attributes attached to them, like any other
> > language construct. The TARGET_CLASS target filter will include Enums
> > themselves. The TARGET_CONST target filter will include Enum Cases
> >
> > TARGET_CONST should presumably be TARGET_CLASS_CONST. More generally
> > though, I wonder if there should be a separate TARGET_CASE...
>
> We had that in the spec until like 40 hours ago. :-)  We removed it mainly
> because beberlei was pushing back on it.  (And the corresponding reflection
> classes, which are still under discussion.)
>
> Personally I'd rather have the flexibility of targeting enums and cases
> specifically.  Ilija and Benjamin feel it's better to "embrace the
> object-y-ness" of enums and just use the existing targets.  It's not a hill
> I'm going to die on either way, so if you can convince them I'm happy to
> add them back in.
>

Can't say I have a particularly strong argument either way here :)


> > > Returns the scalar equivalent type of the Enum, if any. If it doesn't
> > have one, it returns a ReflectionType on null.
> >
> > Possibly I'm misunderstanding the sentence, but why does it return a
> > "ReflectionType on null" rather than just "null"? It's not like ::$value
> > will have a null value in this case, it will not exist at all.
>
> More likely I'm misunderstanding the nuances of the reflection API.  The
> ideal here is to avoid a nullable return if at all possible.  As noted
> above reflection is the shakiest part left right now, so if you have
> specific suggestions for how it would work better, please share.
>

Well, why do you want to avoid a nullable return here? We have many other
getType/getReturnType style APIs that all return null if no type is
specified, so I would expect this one to work the same way. Returning
ReflectionType("null") is 

Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-01-05 Thread Larry Garfield
On Tue, Jan 5, 2021, at 8:26 AM, Nikita Popov wrote:

> Nice work, I like the updated proposal. Some notes:
> 
> > Similarly, enum names and case names are both case insensitive.
> 
> I agree that enum names should be case insensitive (like class names), but
> why should case names be case insensitive? The closest analogon to a case
> would be a class constant, and those are case sensitive.

This is a left over from the earlier draft when Cases were also classes.  I've 
corrected it.  Thanks for the catch.

> > All Cases have a read-only property, case, that is the case-sensitive
> name of the case itself.
> 
> I can see how this makes sense, but it wouldn't be my first guess as to how
> you access the case name. I'm wondering if using $enumValue->name or
> $enumValue->caseName might be preferable.

We'll change it to ->name.

> > Scalar equivalent values must be literals. Constants and constant
> expressions are not supported.
> 
> Why? This seems inconsistent with the overall language. If I can use a
> constant expression as a class constant value, why can't I use it as an
> enum value?

Mostly because it was more challenging to do.  We're fine with including it if 
Ilija can make it work. (Suggestions for him on how to do so most efficiently 
are welcome.)

> > ScalarEnum exposes an additional static method from() that is
> automatically generated.
> 
> I think it would be good to be slightly more explicit here and call it
> fromValue(). (We could have fromName() to construct it from a case name,
> and any number of custom from* named constructors.)
> 
> > The from() method will up-cast from a scalar to its corresponding
> Enumerated Case. Invalid scalars with no matching Case will throw a
> ValueError. There is also a has() method, which will return boolean true if
> a case with that value exists and false otherwise
> 
> Just a thought, but rather than having has() and from(), it may make sense
> to have from() (throws if invalid) and tryFrom() (returns null if invalid).
> I think a has() method is pretty much useless in isolation, it will always
> be used in a combination of has() and from(), in which case it is better to
> combine them rather than have an implicit contract between them.

Hm, maybe.  My concern is that "try" to me implies "exceptions are involved 
somewhere", since PHP doesn't have the "TryX means nullable return" convention 
that Rust or C# have. 

Anyone else want to weigh in?

> > Manually defining a static from() or has() method on a Scalar Enum will
> result in a fatal error.
> 
> Or a non-static one :) You can't define a static and a non-static method
> with the same name in PHP.

Fixed.

> > Enums and cases may have attributes attached to them, like any other
> language construct. The TARGET_CLASS target filter will include Enums
> themselves. The TARGET_CONST target filter will include Enum Cases
> 
> TARGET_CONST should presumably be TARGET_CLASS_CONST. More generally
> though, I wonder if there should be a separate TARGET_CASE...

We had that in the spec until like 40 hours ago. :-)  We removed it mainly 
because beberlei was pushing back on it.  (And the corresponding reflection 
classes, which are still under discussion.)

Personally I'd rather have the flexibility of targeting enums and cases 
specifically.  Ilija and Benjamin feel it's better to "embrace the 
object-y-ness" of enums and just use the existing targets.  It's not a hill I'm 
going to die on either way, so if you can convince them I'm happy to add them 
back in. 

> > Returns the scalar equivalent type of the Enum, if any. If it doesn't
> have one, it returns a ReflectionType on null.
> 
> Possibly I'm misunderstanding the sentence, but why does it return a
> "ReflectionType on null" rather than just "null"? It's not like ::$value
> will have a null value in this case, it will not exist at all.

More likely I'm misunderstanding the nuances of the reflection API.  The ideal 
here is to avoid a nullable return if at all possible.  As noted above 
reflection is the shakiest part left right now, so if you have specific 
suggestions for how it would work better, please share.

> > Additionally, a new function is_enum(mixed): bool returns true if the
> value passed is an enum or case object.
> 
> Could you please clarify what "an enum or case object" means? Is this
> function both for checking whether an object is a case object and a
> (string) class an enum class?

It would return true if given an enum case, a variable that is assigned to an 
enum case, or a class name string that refers to a class that is an enum.  
Other than replicating the test for it I;m not sure how better to describe it. 
(Or, just use that sentence?)

> Some typo/etc notes on the text:
> 
> > All Unit Enums as implemented as instances of their enum type.
> 
> "as" -> "are" possibly?
> 
> > That is one way to determine an Enum from any other object:
> 
> "determine" -> "distinguish" possibly?
> 
> > The above hierarchy is logically 

Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-01-05 Thread Nikita Popov
On Mon, Dec 28, 2020 at 9:22 PM Larry Garfield 
wrote:

> Hello, Internalians!
>
> After considerable discussion and effort, Ilija and I are ready to offer
> you round 2 on enumerations.  This is in the spirit of the previous
> discussion, but based on that discussion a great deal has been reworked.
> The main change is that Enumeration Cases are now object instances of the
> Enumeration class rather than their own class.  Most of the other changes
> are knock-on effects of that.
>
> Of particular note:
>
> * Cases may not have methods or constants on them.  They're just dumb
> values.
> * Enums themselves may have methods, static methods, or constants.
> * Traits are supported, as long as they don't have properties.
> * The value() method on scalar enums is now a property.
>
> The full RFC is here, and I recommend reading it again in full given how
> much was updated.
>
> https://wiki.php.net/rfc/enumerations
>
> The implementation is 98% complete; there's still a few lagging bits in
> reflection, and some opcache bugs that Ilija is still stomping on.
>
> There are a few outstanding questions listed that we would like feedback
> on.  We're not entirely certain which direction to go with them, for
> reasons explained in the RFC.  Input on those is especially welcome.
>
> Happy New Year.  May it be enumerable.


Nice work, I like the updated proposal. Some notes:

> Similarly, enum names and case names are both case insensitive.

I agree that enum names should be case insensitive (like class names), but
why should case names be case insensitive? The closest analogon to a case
would be a class constant, and those are case sensitive.

> All Cases have a read-only property, case, that is the case-sensitive
name of the case itself.

I can see how this makes sense, but it wouldn't be my first guess as to how
you access the case name. I'm wondering if using $enumValue->name or
$enumValue->caseName might be preferable.

> Scalar equivalent values must be literals. Constants and constant
expressions are not supported.

Why? This seems inconsistent with the overall language. If I can use a
constant expression as a class constant value, why can't I use it as an
enum value?

> ScalarEnum exposes an additional static method from() that is
automatically generated.

I think it would be good to be slightly more explicit here and call it
fromValue(). (We could have fromName() to construct it from a case name,
and any number of custom from* named constructors.)

> The from() method will up-cast from a scalar to its corresponding
Enumerated Case. Invalid scalars with no matching Case will throw a
ValueError. There is also a has() method, which will return boolean true if
a case with that value exists and false otherwise

Just a thought, but rather than having has() and from(), it may make sense
to have from() (throws if invalid) and tryFrom() (returns null if invalid).
I think a has() method is pretty much useless in isolation, it will always
be used in a combination of has() and from(), in which case it is better to
combine them rather than have an implicit contract between them.

> Manually defining a static from() or has() method on a Scalar Enum will
result in a fatal error.

Or a non-static one :) You can't define a static and a non-static method
with the same name in PHP.

> Enums and cases may have attributes attached to them, like any other
language construct. The TARGET_CLASS target filter will include Enums
themselves. The TARGET_CONST target filter will include Enum Cases

TARGET_CONST should presumably be TARGET_CLASS_CONST. More generally
though, I wonder if there should be a separate TARGET_CASE...

> Returns the scalar equivalent type of the Enum, if any. If it doesn't
have one, it returns a ReflectionType on null.

Possibly I'm misunderstanding the sentence, but why does it return a
"ReflectionType on null" rather than just "null"? It's not like ::$value
will have a null value in this case, it will not exist at all.

> Additionally, a new function is_enum(mixed): bool returns true if the
value passed is an enum or case object.

Could you please clarify what "an enum or case object" means? Is this
function both for checking whether an object is a case object and a
(string) class an enum class?

Some typo/etc notes on the text:

> All Unit Enums as implemented as instances of their enum type.

"as" -> "are" possibly?

> That is one way to determine an Enum from any other object:

"determine" -> "distinguish" possibly?

> The above hierarchy is logically similar to the following class structure
(although this is not the actual code that runs):

You might want to change the constructor to

private function __construct(public string $case) {}

in this example. The use of "new static" for a final class is also
confusing.

Regards,
Nikita


Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-01-05 Thread Rowan Tommins

On 04/01/2021 22:04, Mike Schinkel wrote:

I don't quit get how you are thinking of with ": string"; can you give an 
example?



The current RFC requires the declaration of a Scalar Enum [1] to include 
the scalar type, so it looks like this:


enum BookingStatus: string {
  case PENDING = "PENDING";
  case CONFIRMED = "CONFIRMED";
  case CANCELLED = "CANCELLED";
}

The simplest opt-in for default scalar values would be to declare the 
type but no values, so the above could be abbreviated this way:


enum BookingStatus: string {
  case PENDING;
  case CONFIRMED;
  case CANCELLED;
}

However, it's probably better to be a bit more explicit, e.g.:

enum BookingStatus: auto string {
  case PENDING;
  case CONFIRMED;
  case CANCELLED;
}

Either way, we'd have to decide if it was allowed to specify some values 
but not all, e.g.:


enum BookingStatus: auto string {
  case PENDING;
  case CONFIRMED;
  case CANCELLED = 'TERMINATED';
}

A more verbose but possibly clearer syntax would be a token on the case 
statements themselves, such as "= auto", to mean "set the value for this 
case based on its constant name":


enum BookingStatus: string {
  case PENDING = auto;
  case CONFIRMED = auto;
  case CANCELLED = 'TERMINATED';
}


There's also the question of whether an automatic value for ints should 
also be allowed, e.g. incrementing in declaration order. This is more 
dangerous, as adding, removing, or re-arranging cases can affect the 
values of *all* the cases in the enum, but is done in some other languages.



[1] https://wiki.php.net/rfc/enumerations#scalar_enums


Regards,

--
Rowan Tommins
[IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-01-05 Thread Peter Bowyer
On Mon, 4 Jan 2021 at 15:21, Pierre R.  wrote:

> I do not agree with having values per default, this is error prone in
> most of my use cases.
>
> In most case where I need enums, I often need to replicate those in
> database too, or in message broker serialized messages: in this context,
> whenever I need to fix a typo in a enum case name, for example, if I use
> default values, I would have errors with my existing database records or
> live messages.
>
> I prefer to keep an explicit switch/match to hydrate values from
> database or elsewhere, and use a value-less enum on the PHP side. Case
> names are the only semantically important value for the developer, and
> your code should not care about having a string value. In most cases
> only exchanges with the outside world in an heterogeneous environment
> (having a database makes it heterogeneous) care about having string
> values. In this case, I highly prefer having explicitely written
> (de)hydration code than automatic magic values happening over the place.
>

I agree.

Peter


Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-01-04 Thread Mike Schinkel
> On Jan 4, 2021, at 9:05 AM, Rowan Tommins  wrote:
> 
> On 04/01/2021 11:15, Markus Fischer wrote:
>> On 03.01.21 12:01, Mike Schinkel wrote:
>>> So in my perfect world this:
>>> 
>>> enum BookingStatus {
>>>   case PENDING;
>>>   case CONFIRMED;
>>>   case CANCELLED;
>>> }
>>> 
>>> Would be equivalent to:
>>> 
>>> enum BookingStatus {
>>>   case PENDING = "PENDING";
>>>   case CONFIRMED = "CONFIRMED";
>>>   case CANCELLED = "CANCELLED";
>>> }
>> 
>> I'm with Mikes' suggesting here, see also my previous messages [1] [2].
>> 
>> I don't know how to back this up with numbers, but the way I see it the 
>> majority of use cases will have a benefit of being able to directly use the 
>> literal values derived from the lexical ones and the ability to have custom 
>> values is feature next to it.
> 
> 
> I would personally be OK with this if it was allowed but opt-in, e.g. adding 
> the ": string" would default the values in that way, or even something magic 
> like ": auto".
> 
> I'm still not a fan of having values *always* defined, because I want to be 
> able to pick case labels without worrying about whether they make sense as 
> values.

> 
> For instance, there's a similar maintenance issue to named parameters: having 
> a default value means if I write "case PENDING;" in v1.0, I can't change that 
> to "case PENDING='P';" or "case PENDING=1;" in v1.1, in case somebody is 
> relying on the value being 'PENDING', which was never intended.

You make a good point about being able to define without defaults, and for 
being opt-in instead.

A use-case I am thinking about is a long list of application-specific error 
codes where you don't want to have to come up two values for each error code 
and/or worry about keeping them the same.


I don't quit get how you are thinking of with ": string"; can you give an 
example?

Conversely, (something like) this might be a viable way to opt-in default 
values:

enum defaults BookingStatus {
  case PENDING;
  case CONFIRMED;
  case CANCELLED;
}

-Mike
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-01-04 Thread Pierre R.

Le 04/01/2021 à 16:12, Markus Fischer a écrit :


I can't say whether just `: string` is too much, but in general I like 
it.


I can follow the reasoning having no value by default and opt this in. 
The opt-in you suggested is very low-overhead (albeit a bit subtle, 
but maybe someone has a smarter idea :)


Maybe not evident, I like the enum RFC but think the most value for 
many use cases will having automatically values.


thanks!
- Markus


Hello,

I do not agree with having values per default, this is error prone in 
most of my use cases.


In most case where I need enums, I often need to replicate those in 
database too, or in message broker serialized messages: in this context, 
whenever I need to fix a typo in a enum case name, for example, if I use 
default values, I would have errors with my existing database records or 
live messages.


I prefer to keep an explicit switch/match to hydrate values from 
database or elsewhere, and use a value-less enum on the PHP side. Case 
names are the only semantically important value for the developer, and 
your code should not care about having a string value. In most cases 
only exchanges with the outside world in an heterogeneous environment 
(having a database makes it heterogeneous) care about having string 
values. In this case, I highly prefer having explicitely written 
(de)hydration code than automatic magic values happening over the place.


Cheers,

Pierre

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-01-04 Thread Markus Fischer

On 04.01.21 16:12, Markus Fischer wrote:

I can't say whether just `: string` is too much, but in general I like it.


Apologies, I meant to write "too magic" :}

- Markus

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-01-04 Thread Markus Fischer

Hi,

On 04.01.21 15:05, Rowan Tommins wrote:

On 04/01/2021 11:15, Markus Fischer wrote:

On 03.01.21 12:01, Mike Schinkel wrote:

So in my perfect world this:

enum BookingStatus {
  case PENDING;
  case CONFIRMED;
  case CANCELLED;
}

Would be equivalent to:

enum BookingStatus {
  case PENDING = "PENDING";
  case CONFIRMED = "CONFIRMED";
  case CANCELLED = "CANCELLED";
}


I'm with Mikes' suggesting here, see also my previous messages [1] [2].

I don't know how to back this up with numbers, but the way I see it 
the majority of use cases will have a benefit of being able to 
directly use the literal values derived from the lexical ones and the 
ability to have custom values is feature next to it.



I would personally be OK with this if it was allowed but opt-in, e.g. 
adding the ": string" would default the values in that way, or even 
something magic like ": auto".


I can't say whether just `: string` is too much, but in general I like it.

I can follow the reasoning having no value by default and opt this in. 
The opt-in you suggested is very low-overhead (albeit a bit subtle, but 
maybe someone has a smarter idea :)


Maybe not evident, I like the enum RFC but think the most value for many 
use cases will having automatically values.


thanks!
- Markus

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-01-04 Thread Rowan Tommins

On 04/01/2021 11:15, Markus Fischer wrote:

On 03.01.21 12:01, Mike Schinkel wrote:

So in my perfect world this:

enum BookingStatus {
  case PENDING;
  case CONFIRMED;
  case CANCELLED;
}

Would be equivalent to:

enum BookingStatus {
  case PENDING = "PENDING";
  case CONFIRMED = "CONFIRMED";
  case CANCELLED = "CANCELLED";
}


I'm with Mikes' suggesting here, see also my previous messages [1] [2].

I don't know how to back this up with numbers, but the way I see it 
the majority of use cases will have a benefit of being able to 
directly use the literal values derived from the lexical ones and the 
ability to have custom values is feature next to it.



I would personally be OK with this if it was allowed but opt-in, e.g. 
adding the ": string" would default the values in that way, or even 
something magic like ": auto".


I'm still not a fan of having values *always* defined, because I want to 
be able to pick case labels without worrying about whether they make 
sense as values.


For instance, there's a similar maintenance issue to named parameters: 
having a default value means if I write "case PENDING;" in v1.0, I can't 
change that to "case PENDING='P';" or "case PENDING=1;" in v1.1, in case 
somebody is relying on the value being 'PENDING', which was never intended.


Regards,

--
Rowan Tommins
[IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-01-04 Thread Markus Fischer

Hi,

On 03.01.21 12:01, Mike Schinkel wrote:

So in my perfect world this:

enum BookingStatus {
  case PENDING;
  case CONFIRMED;
  case CANCELLED;
}

Would be equivalent to:

enum BookingStatus {
  case PENDING = "PENDING";
  case CONFIRMED = "CONFIRMED";
  case CANCELLED = "CANCELLED";
}


I'm with Mikes' suggesting here, see also my previous messages [1] [2].

I don't know how to back this up with numbers, but the way I see it the 
majority of use cases will have a benefit of being able to directly use 
the literal values derived from the lexical ones and the ability to have 
custom values is feature next to it.


[1] https://externals.io/message/112626#112655
[2] https://externals.io/message/112626#112663

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-01-03 Thread Larry Garfield
On Sun, Jan 3, 2021, at 2:25 PM, Marc wrote:

> >> You already provide a lookup mechanism with `MyEnum::from()` - I don't
> >> see a real use-case for proving a pre build map. The main use case I see
> >> is to list all possible enum values but this doesn't require a map and a
> >> zero-indexed-array would also be more performant with packed arrays
> >> (correct me if I'm wrong).
> > I do somewhat agree with you there. We're essentially returning
> > `Array|Map` which feels
> > inconsistent. When you're calling cases() you're most likely going to
> > loop over it at which point $case->value is available at your
> > disposal.
> 
> Would you consider making `cases()` returning a simple list in all cases 
> instead of differentiate between UnitEnum and ScalarEnum given the fact 
> that mostly people just want to loop over cases and a lookup is already 
> available with ScalarEnum::from() to provide a cleaner interface?
> 
> Marc


Ilija and I talked this one over a bit more, and decided that you're right.  
Between ->value and from() we couldn't come up with a use case that would need 
the assoc array that wouldn't work just as well with ->value, and it makes the 
method type definition simpler.

I've updated the RFC to have cases() always return a packed array; Ilija will 
update the PR soon.

Thanks for your feedback!

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-01-03 Thread Marc

Hi Ilija,

On 03.01.21 12:54, Ilija Tovilo wrote:

Hi Marc


I don't have a really good use-case for float values. It just seems
weird to me that a ScalarEnum doesn't support all scalars.

Using the enum value as array key for `cases()` works with your current
proposal but if we later want to allow floats, bool whatever then we got
a food gun.

The main reason is that we're using a hashmap internally in from() to
find the given case you're looking for. This is the same hashmap PHP
arrays are based on which only supports ints/strings as keys. If we
were to allow any scalar as a value, looking up a case by value would
become a O(n) operation.w

We could do something terrible like serialize the key before storing
it in the hashmap to allow arbitrary key types. But that will require
serializing the value on each invocation of from() which will
unnecessarily slow down the 95% most common use cases (int/string) to
support the exception. Note though that it's always easier to extend
than to remove. By not offering this feature we're erring on the side
of caution.

That being said, I can see how ScalarEnum is a misleading name. We've
been thinking about a better name and only had some ideas we weren't
fully satisfied with. RawEnum, ValueEnum and ConvertibleEnum were some
of these ideas. Let us know if you have a better suggestion.


That's reasonable and makes sense at this point. Only supporting string 
and int is also fine (I don't have a personal use case for other types).


So using the same HT implementation as arrays internally totally makes 
sense but this is an implementation detail not visible for the outside 
and we shouldn't block outself for the future now as nobody knows of 
unknown possible use cases. At least if we can avoid it.




You already provide a lookup mechanism with `MyEnum::from()` - I don't
see a real use-case for proving a pre build map. The main use case I see
is to list all possible enum values but this doesn't require a map and a
zero-indexed-array would also be more performant with packed arrays
(correct me if I'm wrong).

I do somewhat agree with you there. We're essentially returning
`Array|Map` which feels
inconsistent. When you're calling cases() you're most likely going to
loop over it at which point $case->value is available at your
disposal.


Would you consider making `cases()` returning a simple list in all cases 
instead of differentiate between UnitEnum and ScalarEnum given the fact 
that mostly people just want to loop over cases and a lookup is already 
available with ScalarEnum::from() to provide a cleaner interface?


Marc


Ilija


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-01-03 Thread Ilija Tovilo
Hi Marc

> I don't have a really good use-case for float values. It just seems
> weird to me that a ScalarEnum doesn't support all scalars.
>
> Using the enum value as array key for `cases()` works with your current
> proposal but if we later want to allow floats, bool whatever then we got
> a food gun.

The main reason is that we're using a hashmap internally in from() to
find the given case you're looking for. This is the same hashmap PHP
arrays are based on which only supports ints/strings as keys. If we
were to allow any scalar as a value, looking up a case by value would
become a O(n) operation.

We could do something terrible like serialize the key before storing
it in the hashmap to allow arbitrary key types. But that will require
serializing the value on each invocation of from() which will
unnecessarily slow down the 95% most common use cases (int/string) to
support the exception. Note though that it's always easier to extend
than to remove. By not offering this feature we're erring on the side
of caution.

That being said, I can see how ScalarEnum is a misleading name. We've
been thinking about a better name and only had some ideas we weren't
fully satisfied with. RawEnum, ValueEnum and ConvertibleEnum were some
of these ideas. Let us know if you have a better suggestion.

> You already provide a lookup mechanism with `MyEnum::from()` - I don't
> see a real use-case for proving a pre build map. The main use case I see
> is to list all possible enum values but this doesn't require a map and a
> zero-indexed-array would also be more performant with packed arrays
> (correct me if I'm wrong).

I do somewhat agree with you there. We're essentially returning
`Array|Map` which feels
inconsistent. When you're calling cases() you're most likely going to
loop over it at which point $case->value is available at your
disposal.

Ilija

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-01-03 Thread Marc

On 03.01.21 11:56, Marc wrote:
> On 29.12.20 16:42, Larry Garfield wrote:
>> On Tue, Dec 29, 2020, at 2:48 AM, Marc wrote:
>>> On 28.12.20 21:21, Larry Garfield wrote:
 Hello, Internalians!

 After considerable discussion and effort, Ilija and I are ready to offer 
 you round 2 on enumerations.  This is in the spirit of the previous 
 discussion, but based on that discussion a great deal has been reworked.  
 The main change is that Enumeration Cases are now object instances of the 
 Enumeration class rather than their own class.  Most of the other changes 
 are knock-on effects of that.

 Of particular note:

 * Cases may not have methods or constants on them.  They're just dumb 
 values.
 * Enums themselves may have methods, static methods, or constants.
 * Traits are supported, as long as they don't have properties.
 * The value() method on scalar enums is now a property.

 The full RFC is here, and I recommend reading it again in full given how 
 much was updated.
>>> I did and the RFC looks really awesome :+1:
>>>
>>> I don't have time to test the implementation but I noticed one thing:
>>>
 If the enumeration is not a Scalar Enum, the array will be packed
>>> (indexed sequentially starting from 0). If the enumeration is a Scalar
>>> Enum, the keys will be the corresponding scalar for each enumeration.
>>>
>>> I don't think using the scalar values as keys is a good idea. What
>>> happens if we want to support scalar float values? (Why are they
>>> actually not supported in the first place?)
>> That's why floats are not supported, in fact, because what happens to them 
>> when they are made into an array key is non-obvious.  (PHP would say to 
>> convert to a string, but that's always fussy with possible data loss in some 
>> cases, etc.)  We decided to just avoid that problem until/unless someone 
>> found a good use case for float enums.  No all languages support them as is, 
>> so there is precedent.
>>
>>> Also I think it's more natural if both enum types return a
>>> zero-indexed-array of cases.
>> The goal is to make it easy to work with them, and having a clean lookup map 
>> readily available is very convenient.  If you don't care about the scalar 
>> equivalent then you can safely ignore them.  If you do want them, then you 
>> have a lookup table ready-made for you.  That's the logic we were working 
>> from.
> I don't have a really good use-case for float values. It just seems
> weird to me that a ScalarEnum doesn't support all scalars.
>
> Using the enum value as array key for `cases()` works with your current
> proposal but if we later want to allow floats, bool whatever then we got
> a food gun.

Forgot to mention on (virtiually) adding generics to the game the method
`cases(): array;`would be described as
`cases(): array;` on UnitEnum but `cases():
array;` on ScalarEnum which is not compatible for
reasons and I think (even if not yet possible with PHP) such things
needs to be considered on producing clean interfaces.


>
> You already provide a lookup mechanism with `MyEnum::from()` - I don't
> see a real use-case for proving a pre build map. The main use case I see
> is to list all possible enum values but this doesn't require a map and a
> zero-indexed-array would also be more performant with packed arrays
> (correct me if I'm wrong).
>

Thanks,

Marc


>> --Larry Garfield
>>


Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-01-03 Thread Mike Schinkel



> On Dec 31, 2020, at 12:15 PM, Larry Garfield  wrote:
> 
> On Thu, Dec 31, 2020, at 6:53 AM, Rowan Tommins wrote:
>> On 30/12/2020 21:24, Aleksander Machniak wrote:
>>> My argument is that, from an end-user perspective, I don't really see
>>> why Unit and Scalar enums have to have different "API" at this point.
>>> I'm talking about ":string"/":int" in the enum definiton as well as
>>> ->value and ->from().
>> 
>> 
>> My personal opinion is that for many enums, explicitly not having a 
>> scalar representation is a good thing.
>> 
>> This is basically similar to my opinion of __toString() etc: if you have 
>> *multiple* ways to convert something to/from a scalar, blessing one of 
>> them as "default" is arbitrary and confusing.
>> 
>> For example:
>> 
>> enum BookingStatus {
>>  case PENDING;
>>  case CONFIRMED;
>>  case CANCELLED;
>> 
>>  public function getId() {
>>return match($this) {
>> self::PENDING => 1,
>> self::CONFIRMED => 2,
>> self::CANCELLED => 3,
>>};
>>  }
>>  public function getCode() {
>>return match($this) {
>> self::PENDING => 'PEN',
>> self::CONFIRMED => 'CON',
>> self::CANCELLED => 'CAN',
>>};
>>  }
>>  public function getEnglishDescription() {
>>return match($this) {
>> self::PENDING => 'Pending Payment',
>> self::CONFIRMED => 'Confirmed',
>> self::CANCELLED => 'Cancelled',
>>};
>>  }
>> }
> 
> That is similar to our reasoning.  It creates a foot-gun situation where 
> someone could get in the habit of assuming that an enum always has a 
> *reasonable* and *logical* and thus *reliable* string equivalent, when not 
> all enums will have string equivalents that it's reasonable and logical to 
> use.  So, one less foot gun.

However, avoiding one foot-gun does not always mean that you avoid all 
foot-guns.

For example, when you need to create a large number of string enums where the 
name and the symbol are the same, it would be very easy to have a typo in one 
but not the other, especially as a result of copy and paste editing.

So in my perfect world this:

enum BookingStatus {
 case PENDING;
 case CONFIRMED;
 case CANCELLED;
}

Would be equivalent to:

enum BookingStatus {
 case PENDING = "PENDING";
 case CONFIRMED = "CONFIRMED";
 case CANCELLED = "CANCELLED";
}

#fwiw

> 
> Also, one of the extensions planned, as noted, is ADTs/tagged unions.  Those 
> could not have a primitive equivalent, since they're not singletons.  Keeping 
> UnitEnum and ScalarEnum separate allows us to later add TaggedEnum (or 
> similar) that also extends UnitEnum, but not ScalarEnum.
> 
> --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



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-01-03 Thread Marc


On 29.12.20 16:42, Larry Garfield wrote:
> On Tue, Dec 29, 2020, at 2:48 AM, Marc wrote:
>> On 28.12.20 21:21, Larry Garfield wrote:
>>> Hello, Internalians!
>>>
>>> After considerable discussion and effort, Ilija and I are ready to offer 
>>> you round 2 on enumerations.  This is in the spirit of the previous 
>>> discussion, but based on that discussion a great deal has been reworked.  
>>> The main change is that Enumeration Cases are now object instances of the 
>>> Enumeration class rather than their own class.  Most of the other changes 
>>> are knock-on effects of that.
>>>
>>> Of particular note:
>>>
>>> * Cases may not have methods or constants on them.  They're just dumb 
>>> values.
>>> * Enums themselves may have methods, static methods, or constants.
>>> * Traits are supported, as long as they don't have properties.
>>> * The value() method on scalar enums is now a property.
>>>
>>> The full RFC is here, and I recommend reading it again in full given how 
>>> much was updated.
>> I did and the RFC looks really awesome :+1:
>>
>> I don't have time to test the implementation but I noticed one thing:
>>
>>> If the enumeration is not a Scalar Enum, the array will be packed
>> (indexed sequentially starting from 0). If the enumeration is a Scalar
>> Enum, the keys will be the corresponding scalar for each enumeration.
>>
>> I don't think using the scalar values as keys is a good idea. What
>> happens if we want to support scalar float values? (Why are they
>> actually not supported in the first place?)
> That's why floats are not supported, in fact, because what happens to them 
> when they are made into an array key is non-obvious.  (PHP would say to 
> convert to a string, but that's always fussy with possible data loss in some 
> cases, etc.)  We decided to just avoid that problem until/unless someone 
> found a good use case for float enums.  No all languages support them as is, 
> so there is precedent.
>
>> Also I think it's more natural if both enum types return a
>> zero-indexed-array of cases.
> The goal is to make it easy to work with them, and having a clean lookup map 
> readily available is very convenient.  If you don't care about the scalar 
> equivalent then you can safely ignore them.  If you do want them, then you 
> have a lookup table ready-made for you.  That's the logic we were working 
> from.

I don't have a really good use-case for float values. It just seems
weird to me that a ScalarEnum doesn't support all scalars.

Using the enum value as array key for `cases()` works with your current
proposal but if we later want to allow floats, bool whatever then we got
a food gun.

You already provide a lookup mechanism with `MyEnum::from()` - I don't
see a real use-case for proving a pre build map. The main use case I see
is to list all possible enum values but this doesn't require a map and a
zero-indexed-array would also be more performant with packed arrays
(correct me if I'm wrong).


>
> --Larry Garfield
>

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-01-01 Thread Larry Garfield
On Fri, Jan 1, 2021, at 12:08 PM, Benjamin Eberlei wrote:
> On Mon, Dec 28, 2020 at 9:22 PM Larry Garfield 
> wrote:
> 
> > Hello, Internalians!
> >
> > After considerable discussion and effort, Ilija and I are ready to offer
> > you round 2 on enumerations.  This is in the spirit of the previous
> > discussion, but based on that discussion a great deal has been reworked.
> > The main change is that Enumeration Cases are now object instances of the
> > Enumeration class rather than their own class.  Most of the other changes
> > are knock-on effects of that.
> >
> > Of particular note:
> >
> > * Cases may not have methods or constants on them.  They're just dumb
> > values.
> > * Enums themselves may have methods, static methods, or constants.
> > * Traits are supported, as long as they don't have properties.
> > * The value() method on scalar enums is now a property.
> >
> > The full RFC is here, and I recommend reading it again in full given how
> > much was updated.
> >
> > https://wiki.php.net/rfc/enumerations
> >
> > The implementation is 98% complete; there's still a few lagging bits in
> > reflection, and some opcache bugs that Ilija is still stomping on.
> >
> > There are a few outstanding questions listed that we would like feedback
> > on.  We're not entirely certain which direction to go with them, for
> > reasons explained in the RFC.  Input on those is especially welcome.
> >
> > Happy New Year.  May it be enumerable.
> >
> 
> I think the reflection part is the weakest of this proposal, in my opinion
> there should not be a ReflectionEnum and ReflectionCase.

I'd agree that Reflection is the place we still have the most open questions.  
(The listed attribute open questions are synonyms for reflection questions, in 
a sense.)  I disagree with removing their reflection classes entirely, though.

> - ReflectionEnum extends ReflectionClass is problematic

Why?  The main alternative is making it its own thing entirely, which seemed 
redundant.

> - is hasEnum just an alias for hasConstant?

Assuming you mean hasCase(), no.  An enum can have constants now in addition to 
cases.  So for instance:

enum Foo {
  case Bar;
  const Beep = self::Bar;
}

hasCase('Beep') would return false.  hasConstant('Beep') returns true.

> - Same for getCases() for getConstants().

As above.  Not all constants are cases.  That cases are constants is an 
implementation convenience.

> - what does getConstant() or ReflectionClassConstant::getValue return for a
> non scalar enum? the instance?

ReflectionEnum::getConstant() would return the case instance object, whether or 
not it's scalar.

> In my opinion you should embrace the "desugarizing" like constructor
> promotion and just keep everything with the exsiting Reflection structure.

Enums are more than "just" sugar on objects, though.  They're built on objects, 
but they have limitations that objects don't have, and features objects don't 
have.  And ideally those will expand in future RFCs.  Having no difference at 
all between them an objects in reflection even though their functionality is 
different at a user level seems needlessly confusing and limiting to me.

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2021-01-01 Thread Benjamin Eberlei
On Mon, Dec 28, 2020 at 9:22 PM Larry Garfield 
wrote:

> Hello, Internalians!
>
> After considerable discussion and effort, Ilija and I are ready to offer
> you round 2 on enumerations.  This is in the spirit of the previous
> discussion, but based on that discussion a great deal has been reworked.
> The main change is that Enumeration Cases are now object instances of the
> Enumeration class rather than their own class.  Most of the other changes
> are knock-on effects of that.
>
> Of particular note:
>
> * Cases may not have methods or constants on them.  They're just dumb
> values.
> * Enums themselves may have methods, static methods, or constants.
> * Traits are supported, as long as they don't have properties.
> * The value() method on scalar enums is now a property.
>
> The full RFC is here, and I recommend reading it again in full given how
> much was updated.
>
> https://wiki.php.net/rfc/enumerations
>
> The implementation is 98% complete; there's still a few lagging bits in
> reflection, and some opcache bugs that Ilija is still stomping on.
>
> There are a few outstanding questions listed that we would like feedback
> on.  We're not entirely certain which direction to go with them, for
> reasons explained in the RFC.  Input on those is especially welcome.
>
> Happy New Year.  May it be enumerable.
>

I think the reflection part is the weakest of this proposal, in my opinion
there should not be a ReflectionEnum and ReflectionCase.

- ReflectionEnum extends ReflectionClass is problematic
- is hasEnum just an alias for hasConstant?
- Same for getCases() for getConstants().
- what does getConstant() or ReflectionClassConstant::getValue return for a
non scalar enum? the instance?

In my opinion you should embrace the "desugarizing" like constructor
promotion and just keep everything with the exsiting Reflection structure.

>
> --
>   Larry Garfield
>   la...@garfieldtech.com
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>


Re: [PHP-DEV] [RFC] Enumerations, Round 2

2020-12-31 Thread Larry Garfield
On Thu, Dec 31, 2020, at 4:02 AM, Michał Marcin Brzuchalski wrote:
> Hi Larry,

> I really like the shape of the current RFC.
> 
> I'd like to ask a few things:
> 
> 1. Regarding the Scalar Enums since scalar values need to be literal and
> by design they're read only why they use a spear "->value" on enumeration?
> A spear "->" in objects is dedicated to class properties and by default
> they make thinking of property which
> in most cases is read-write visible.
> 
> An example using Suit enumeration from RFC:
> // when I assign an enumeration to variable
> $var = Suit::Spades;
> // then reaching it's value using "->value"
> echo $var->value; // 'C'
> // Looks just like an object property fetch
> 
> By default if a property is visible it is write accessible as well, which
> may confuse.
> 
> Instead of using spear "->value" would it be possible to fetch the value
> just like object constants?
> 
> print Suit::Clubs::value; // 'C'
> echo $var::value; // 'C'
> 
> This mentally indicates by default that it's value is constant, simple
> scalar value and read only!

We originally used a method in the first draft.  We changed it to a property 
for three reasons.

1) There's lots of talk lately about immutable properties, so one way or 
another "it's a property so I can write to it" is an assumption that won't hold 
much longer.
2) The property has to exist internally anyway, because under the hood it's 
just a class with a property, so the name would still be reserved either way.
3) Given 1 and 2, adding a method on top just adds some micro overhead for the 
method call.

A constant-esque syntax wouldn't be possible because under the hood, the cases 
are objects now, not classes.  We could put constants on Suit, but Suit::Clubs 
is an object, and objects can't have constants independent of their class.

> 2. Regarding the Scalar Enums declaration syntax
> 
> enum Suit: string {
>   case Hearts = 'H';
> }
> 
> Would it make sense to move the part declaring enumeration value before
> enum name?
> I think it was put here to look similar to function return type, but IMHO
> it looks better and reads easier
> when moved before enum name:
> 
> enum:string Suit {
>   case Hearts = 'H';
> }
> 
> Leaving the space between enum name and bracket for further extensions in
> future.
> What do you think?

That would be a very one-off syntax.  The colon-suffix is already established 
in PHP, and i the same as the syntax used in Swift.  What you're describing 
looks a lot more like a generic.  Which... I suppose in some ways this is if 
you squint really hard?  I don't have much of an argument against it other than 
aesthetic.  I have no idea what the parser would do with it.

--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2020-12-31 Thread Larry Garfield
On Thu, Dec 31, 2020, at 6:53 AM, Rowan Tommins wrote:
> On 30/12/2020 21:24, Aleksander Machniak wrote:
> > My argument is that, from an end-user perspective, I don't really see
> > why Unit and Scalar enums have to have different "API" at this point.
> > I'm talking about ":string"/":int" in the enum definiton as well as
> > ->value and ->from().
> 
> 
> My personal opinion is that for many enums, explicitly not having a 
> scalar representation is a good thing.
> 
> This is basically similar to my opinion of __toString() etc: if you have 
> *multiple* ways to convert something to/from a scalar, blessing one of 
> them as "default" is arbitrary and confusing.
> 
> For example:
> 
> enum BookingStatus {
>   case PENDING;
>   case CONFIRMED;
>   case CANCELLED;
> 
>   public function getId() {
>     return match($this) {
>      self::PENDING => 1,
>      self::CONFIRMED => 2,
>      self::CANCELLED => 3,
>     };
>   }
>   public function getCode() {
>     return match($this) {
>      self::PENDING => 'PEN',
>      self::CONFIRMED => 'CON',
>      self::CANCELLED => 'CAN',
>     };
>   }
>   public function getEnglishDescription() {
>     return match($this) {
>      self::PENDING => 'Pending Payment',
>      self::CONFIRMED => 'Confirmed',
>      self::CANCELLED => 'Cancelled',
>     };
>   }
> }

That is similar to our reasoning.  It creates a foot-gun situation where 
someone could get in the habit of assuming that an enum always has a 
*reasonable* and *logical* and thus *reliable* string equivalent, when not all 
enums will have string equivalents that it's reasonable and logical to use.  
So, one less foot gun.

Also, one of the extensions planned, as noted, is ADTs/tagged unions.  Those 
could not have a primitive equivalent, since they're not singletons.  Keeping 
UnitEnum and ScalarEnum separate allows us to later add TaggedEnum (or similar) 
that also extends UnitEnum, but not ScalarEnum.

--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2020-12-31 Thread Rowan Tommins

On 30/12/2020 21:24, Aleksander Machniak wrote:

My argument is that, from an end-user perspective, I don't really see
why Unit and Scalar enums have to have different "API" at this point.
I'm talking about ":string"/":int" in the enum definiton as well as
->value and ->from().



My personal opinion is that for many enums, explicitly not having a 
scalar representation is a good thing.


This is basically similar to my opinion of __toString() etc: if you have 
*multiple* ways to convert something to/from a scalar, blessing one of 
them as "default" is arbitrary and confusing.


For example:

enum BookingStatus {
 case PENDING;
 case CONFIRMED;
 case CANCELLED;

 public function getId() {
   return match($this) {
    self::PENDING => 1,
    self::CONFIRMED => 2,
    self::CANCELLED => 3,
   };
 }
 public function getCode() {
   return match($this) {
    self::PENDING => 'PEN',
    self::CONFIRMED => 'CON',
    self::CANCELLED => 'CAN',
   };
 }
 public function getEnglishDescription() {
   return match($this) {
    self::PENDING => 'Pending Payment',
    self::CONFIRMED => 'Confirmed',
    self::CANCELLED => 'Cancelled',
   };
 }
}


Regards,

--
Rowan Tommins
[IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2020-12-31 Thread Rowan Tommins

On 30/12/2020 19:47, Larry Garfield wrote:

That's partially left over from when we had per-case methods, where grouping 
would be highly fugly.  However, I'm still advocating for tagged unions (in a 
future step) having per-case methods, and that would make the grouping syntax 
fugly again.  It's trivial to add later, so for now I think it's best to skip.  
If we find later on it doesn't get in the way of anything it's an easy addition.



Yes, that had occurred to me. Just to reiterate, though, the original 
justification read "it is unclear how common [cases without block 
definitions] will be in practice"; with the current implementation, we 
know for a fact that it will be extremely common - even if tagged unions 
use overlapping syntax that doesn't group nicely, every "unit enum" will 
have cases with no blocks.


Still, it's not a big deal either way, and as you say can easily be 
added later.


Regards,

--
Rowan Tommins
[IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2020-12-31 Thread Michał Marcin Brzuchalski
Hi Larry,

pon., 28 gru 2020 o 21:22 Larry Garfield 
napisał(a):

> Hello, Internalians!
>
> After considerable discussion and effort, Ilija and I are ready to offer
> you round 2 on enumerations.  This is in the spirit of the previous
> discussion, but based on that discussion a great deal has been reworked.
> The main change is that Enumeration Cases are now object instances of the
> Enumeration class rather than their own class.  Most of the other changes
> are knock-on effects of that.
>
> Of particular note:
>
> * Cases may not have methods or constants on them.  They're just dumb
> values.
> * Enums themselves may have methods, static methods, or constants.
> * Traits are supported, as long as they don't have properties.
> * The value() method on scalar enums is now a property.
>
> The full RFC is here, and I recommend reading it again in full given how
> much was updated.
>
> https://wiki.php.net/rfc/enumerations
>
> The implementation is 98% complete; there's still a few lagging bits in
> reflection, and some opcache bugs that Ilija is still stomping on.
>

I really like the shape of the current RFC.

I'd like to ask a few things:

1. Regarding the Scalar Enums since scalar values need to be literal and
by design they're read only why they use a spear "->value" on enumeration?
A spear "->" in objects is dedicated to class properties and by default
they make thinking of property which
in most cases is read-write visible.

An example using Suit enumeration from RFC:
// when I assign an enumeration to variable
$var = Suit::Spades;
// then reaching it's value using "->value"
echo $var->value; // 'C'
// Looks just like an object property fetch

By default if a property is visible it is write accessible as well, which
may confuse.

Instead of using spear "->value" would it be possible to fetch the value
just like object constants?

print Suit::Clubs::value; // 'C'
echo $var::value; // 'C'

This mentally indicates by default that it's value is constant, simple
scalar value and read only!

2. Regarding the Scalar Enums declaration syntax

enum Suit: string {
  case Hearts = 'H';
}

Would it make sense to move the part declaring enumeration value before
enum name?
I think it was put here to look similar to function return type, but IMHO
it looks better and reads easier
when moved before enum name:

enum:string Suit {
  case Hearts = 'H';
}

Leaving the space between enum name and bracket for further extensions in
future.
What do you think?


Cheers,
Michał Marcin Brzuchalski


Re: [PHP-DEV] [RFC] Enumerations, Round 2

2020-12-30 Thread Aleksander Machniak
On 30.12.2020 21:21, Larry Garfield wrote:
>> enum Suit {
>>   case Hearts = 'H';
>>   case Diamonds = 'D';
>>   case Clubs = 'C';
>>   case Spades = 'S';
>> }
>>
>> 'H' === Suit::Hearts->value; // true
>> 'Hearts' === Suit::Hearts->value; // false
> 
> That's a possibility we've been kicking around.  I'm considering it, Ilija 
> doesn't care for it. :-)  What's your argument in favor?

My argument is that, from an end-user perspective, I don't really see
why Unit and Scalar enums have to have different "API" at this point.
I'm talking about ":string"/":int" in the enum definiton as well as
->value and ->from().

-- 
Aleksander Machniak
Kolab Groupware Developer[https://kolab.org]
Roundcube Webmail Developer  [https://roundcube.net]

PGP: 19359DC1 # Blog: https://kolabian.wordpress.com

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2020-12-30 Thread Larry Garfield
On Wed, Dec 30, 2020, at 12:30 PM, Aleksander Machniak wrote:
> On 28.12.2020 21:21, Larry Garfield wrote:
> > https://wiki.php.net/rfc/enumerations
> Why can't this be simplified to:
> 
> enum Size {
>   case Small;
>   case Medium;
>   case Large;
> }
> 
> 'Small' === Size::Small->value; // true
> Size::from('Small') === Size::Small; // true
> 
> enum Suit {
>   case Hearts = 'H';
>   case Diamonds = 'D';
>   case Clubs = 'C';
>   case Spades = 'S';
> }
> 
> 'H' === Suit::Hearts->value; // true
> 'Hearts' === Suit::Hearts->value; // false

That's a possibility we've been kicking around.  I'm considering it, Ilija 
doesn't care for it. :-)  What's your argument in favor?

Related: There is an internal "case" value that is used as well.  It could be 
exposed as a normal read-only property, which would always be equal to the name 
of the case ("Hearts"), regardless of whether another "value" is defined.  
We're still undecided on that, too.

> Also, how about using a method instead of property for ->value?

We originally did.  Ilija preferred moving it to a property since there will 
need to be one anyway to store the value.  I moderately favor a method but 
don't greatly care either way.

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2020-12-30 Thread Larry Garfield
On Wed, Dec 30, 2020, at 6:27 AM, Rowan Tommins wrote:
> On 28/12/2020 20:21, Larry Garfield wrote:
> > After considerable discussion and effort, Ilija and I are ready to offer 
> > you round 2 on enumerations.
> 
> 
> Thank you both, again, for all your efforts. I'm pleased to say that I 
> like this draft even more than the last one. :)
> 
> A couple of points that occurred to me reading through:
> 
> - The magic methods section lists __call as allowed, but not 
> __callStatic; was this deliberate, or just an oversight?

More oversight; the reasons for not including it initially aren't really good 
reasons, so we'll unblock that.

> - Under Future Scope, the "Grouped Syntax" sub-section says "That would 
> only work on the simple, non-primitive-backed case with no methods 
> defined [...] it is unclear how common that will be in practice" This 
> caveat doesn't apply to the current proposed syntax, and should perhaps 
> be re-visited.
> 
> Given that this is currently a legal declaration:
> 
> class Suit {
>    const Hearts = 'H', Diamonds = 'D', Clubs = 'C', Spades = 'S';
> }
> 
> It seems fairly reasonable for the enum version to allow the same syntax:
> 
> enum Suit: string {
>    case Hearts = 'H', Diamonds = 'D', Clubs = 'C', Spades = 'S';
> }
> 
> Or, for a non-scalar enum:
> 
> enum Suit {
>    case Hearts, Diamonds, Clubs, Spades;
> }

That's partially left over from when we had per-case methods, where grouping 
would be highly fugly.  However, I'm still advocating for tagged unions (in a 
future step) having per-case methods, and that would make the grouping syntax 
fugly again.  It's trivial to add later, so for now I think it's best to skip.  
If we find later on it doesn't get in the way of anything it's an easy addition.

--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2020-12-30 Thread Larry Garfield
On Wed, Dec 30, 2020, at 4:12 AM, Alexandru Pătrănescu wrote:

> Nice evolution overall.
> 
> Few notes:
> - I think ScalarEnum::fromValue() would be more clear than just from() and
> more in sync with ->value property.

Any name would work, I suppose.  I prefer short, single-word methods where 
possible, myself.

> - For the class structure you gave an example to illustrate the 'similar'
> way it is related to class, it would be nice to also mark the class as
> final.

It would.  Added.

> - I agree with no state behavior, at least at this point. However, I would
> have liked to offer the ability for very easy creation of
> singleton/multiton patterns using enums, like in Java.

I'm not sure what you're describing here.  Do you mean tagged unions/ADTs, 
which are punted to a later RFC?  

https://wiki.php.net/rfc/tagged_unions

> - Enums evolve in time and cases are added or sometimes removed. When the
> storage of the case stays externally (as scalar values or serialized),
> there could be issues when some of them are removed in the meantime.

Possibly; though that's no different than a class evolving or going away in 
time.  Either way it's up to the developer to figure out what BC strategy makes 
sense.

>   - for ScalarEnum::from(), for missing values I would guess we will throw
> an exception, maybe a specific one? Can we mention it in the RFC?

It already says a ValueError is thrown.  It probably does make sense to 
subclass that, though.  I'll mention it to Ilija.

>   - for deserialization, how should it be handled? using an exception as
> well, same exception as in the previous case.

Ilija and I discussed this a bit, and settled on an invalid deserialiation 
issuing a warning and returning false.  An exception would probably be better, 
but right now deserialize() doesn't throw things so introducing that just for 
enums seems inconsistent.  He'll be updating the implementation shortly.

> - The allowed_classes option on unserialize() method, I'm guessing it will
> work with Enums just like every other class, putting an instance of
> __PHP_Incomplete_Class?

Enums don't have unsafe behavior in their constructors the way classes do, so 
we're not convinced there's a reason to exclude them.  For now allowed_classes 
does not include enums.

> - Inheritance would work between enums. But only by eliminating some cases.
> I can see how enum RedSuites could extend enum Suites without breaking LSP.
> Not sure if it makes sense to dig on this now.
> 
> Regards,
> Alex

Possibly as a future scope, if we see demand for it.  The RFC is ambitious 
enough as is and already has several follow-ups planned for more advanced 
cases. :-)

Cheers!

--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2020-12-30 Thread Aleksander Machniak
On 28.12.2020 21:21, Larry Garfield wrote:
> https://wiki.php.net/rfc/enumerations
Why can't this be simplified to:

enum Size {
  case Small;
  case Medium;
  case Large;
}

'Small' === Size::Small->value; // true
Size::from('Small') === Size::Small; // true

enum Suit {
  case Hearts = 'H';
  case Diamonds = 'D';
  case Clubs = 'C';
  case Spades = 'S';
}

'H' === Suit::Hearts->value; // true
'Hearts' === Suit::Hearts->value; // false

Also, how about using a method instead of property for ->value?

-- 
Aleksander Machniak
Kolab Groupware Developer[https://kolab.org]
Roundcube Webmail Developer  [https://roundcube.net]

PGP: 19359DC1 # Blog: https://kolabian.wordpress.com

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2020-12-30 Thread Larry Garfield
On Wed, Dec 30, 2020, at 2:43 AM, Markus Fischer wrote:
> Hi,
> 
> On 28.12.20 21:21, Larry Garfield wrote:
> > The full RFC is here, and I recommend reading it again in full given how 
> > much was updated.
> > 
> > https://wiki.php.net/rfc/enumerations
> 
> I tried to answer the following question but failed to do so:
> 
> What is the scalar value for a ScalarEnum if none is explicitly defined?
> 
> The RFC makes this example:
>  > enum Suit: string implements Colorful {
>  >case Hearts = 'H';
>  >case Diamonds = 'D';
> …
>  > 'D' == Suit::Diamonds->value; // true
> 
> 
> What in this case?
> 
>  > enum Suit: string {
>  >case Hearts;
>  >case Diamonds;
> …
> 
> What is the outcome of `Suit::Diamonds->value` ?

A parse error on the declaration; if it's a scalar enum, explicit values are 
required for all cases.

--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2020-12-30 Thread Benjamin Morel
>
> What's the quickest way (=less code) to have an enum represent it's
> lexical name as the literal values?
>
> So that `… case Foo; case Bar; …` results in `::Foo->value === 'Foo'` etc.?
>
> Is this possible without implementing this manually for all cases?
>
>
AFAICS, you'd need to implement the values manually. The $value property is
only defined on ScalarEnum, not UnitEnum.

- Benjamin


Re: [PHP-DEV] [RFC] Enumerations, Round 2

2020-12-30 Thread Markus Fischer

On 30.12.20 12:00, Rowan Tommins wrote:

On 30 December 2020 08:43:33 GMT+00:00, Markus Fischer  
wrote:

What is the scalar value for a ScalarEnum if none is explicitly
defined?


The question has no answer, because the declaration of the enum itself would be 
invalid:


If an enumeration is marked as having a scalar equivalent, then all cases must 
have a unique scalar equivalent defined explicitly.


enum Suit: string {
case Hearts;
case Diamonds;
}

Presumably, this would result in an Error being thrown when compiling the 
declaration.


I see.

What's the quickest way (=less code) to have an enum represent it's 
lexical name as the literal values?


So that `… case Foo; case Bar; …` results in `::Foo->value === 'Foo'` etc.?

Is this possible without implementing this manually for all cases?

thanks,
- Markus

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2020-12-30 Thread Rowan Tommins

On 28/12/2020 20:21, Larry Garfield wrote:

After considerable discussion and effort, Ilija and I are ready to offer you 
round 2 on enumerations.



Thank you both, again, for all your efforts. I'm pleased to say that I 
like this draft even more than the last one. :)


A couple of points that occurred to me reading through:

- The magic methods section lists __call as allowed, but not 
__callStatic; was this deliberate, or just an oversight?


- Under Future Scope, the "Grouped Syntax" sub-section says "That would 
only work on the simple, non-primitive-backed case with no methods 
defined [...] it is unclear how common that will be in practice" This 
caveat doesn't apply to the current proposed syntax, and should perhaps 
be re-visited.


Given that this is currently a legal declaration:

class Suit {
  const Hearts = 'H', Diamonds = 'D', Clubs = 'C', Spades = 'S';
}

It seems fairly reasonable for the enum version to allow the same syntax:

enum Suit: string {
  case Hearts = 'H', Diamonds = 'D', Clubs = 'C', Spades = 'S';
}

Or, for a non-scalar enum:

enum Suit {
  case Hearts, Diamonds, Clubs, Spades;
}


Regards,

--
Rowan Tommins
[IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2020-12-30 Thread Rowan Tommins
On 30 December 2020 08:43:33 GMT+00:00, Markus Fischer  
wrote:
>What is the scalar value for a ScalarEnum if none is explicitly
>defined?

The question has no answer, because the declaration of the enum itself would be 
invalid:

> If an enumeration is marked as having a scalar equivalent, then all cases 
> must have a unique scalar equivalent defined explicitly.

enum Suit: string { 
case Hearts; 
case Diamonds;
}

Presumably, this would result in an Error being thrown when compiling the 
declaration.

Regards,

-- 
Rowan Tommins
[IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2020-12-30 Thread Alexandru Pătrănescu
On Mon, Dec 28, 2020 at 10:22 PM Larry Garfield 
wrote:
>
> Hello, Internalians!
>
> After considerable discussion and effort, Ilija and I are ready to offer
you round 2 on enumerations.  This is in the spirit of the previous
discussion, but based on that discussion a great deal has been reworked.
The main change is that Enumeration Cases are now object instances of the
Enumeration class rather than their own class.  Most of the other changes
are knock-on effects of that.
>
> Of particular note:
>
> * Cases may not have methods or constants on them.  They're just dumb
values.
> * Enums themselves may have methods, static methods, or constants.
> * Traits are supported, as long as they don't have properties.
> * The value() method on scalar enums is now a property.
>
> The full RFC is here, and I recommend reading it again in full given how
much was updated.
>
> https://wiki.php.net/rfc/enumerations
>
> The implementation is 98% complete; there's still a few lagging bits in
reflection, and some opcache bugs that Ilija is still stomping on.
>
> There are a few outstanding questions listed that we would like feedback
on.  We're not entirely certain which direction to go with them, for
reasons explained in the RFC.  Input on those is especially welcome.
>
> Happy New Year.  May it be enumerable.
>
> --
>   Larry Garfield
>   la...@garfieldtech.com
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>

Hi!

Nice evolution overall.

Few notes:
- I think ScalarEnum::fromValue() would be more clear than just from() and
more in sync with ->value property.
- For the class structure you gave an example to illustrate the 'similar'
way it is related to class, it would be nice to also mark the class as
final.
- I agree with no state behavior, at least at this point. However, I would
have liked to offer the ability for very easy creation of
singleton/multiton patterns using enums, like in Java.
- Enums evolve in time and cases are added or sometimes removed. When the
storage of the case stays externally (as scalar values or serialized),
there could be issues when some of them are removed in the meantime.
  - for ScalarEnum::from(), for missing values I would guess we will throw
an exception, maybe a specific one? Can we mention it in the RFC?
  - for deserialization, how should it be handled? using an exception as
well, same exception as in the previous case.
- The allowed_classes option on unserialize() method, I'm guessing it will
work with Enums just like every other class, putting an instance of
__PHP_Incomplete_Class?
- Inheritance would work between enums. But only by eliminating some cases.
I can see how enum RedSuites could extend enum Suites without breaking LSP.
Not sure if it makes sense to dig on this now.

Regards,
Alex


Re: [PHP-DEV] [RFC] Enumerations, Round 2

2020-12-30 Thread Markus Fischer

Hi,

On 28.12.20 21:21, Larry Garfield wrote:

The full RFC is here, and I recommend reading it again in full given how much 
was updated.

https://wiki.php.net/rfc/enumerations


I tried to answer the following question but failed to do so:

What is the scalar value for a ScalarEnum if none is explicitly defined?

The RFC makes this example:
> enum Suit: string implements Colorful {
>case Hearts = 'H';
>case Diamonds = 'D';
…
> 'D' == Suit::Diamonds->value; // true


What in this case?

> enum Suit: string {
>case Hearts;
>case Diamonds;
…

What is the outcome of `Suit::Diamonds->value` ?

Thanks!
- Markus

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2020-12-29 Thread Larry Garfield
On Tue, Dec 29, 2020, at 2:48 AM, Marc wrote:
> 
> On 28.12.20 21:21, Larry Garfield wrote:
> > Hello, Internalians!
> >
> > After considerable discussion and effort, Ilija and I are ready to offer 
> > you round 2 on enumerations.  This is in the spirit of the previous 
> > discussion, but based on that discussion a great deal has been reworked.  
> > The main change is that Enumeration Cases are now object instances of the 
> > Enumeration class rather than their own class.  Most of the other changes 
> > are knock-on effects of that.
> >
> > Of particular note:
> >
> > * Cases may not have methods or constants on them.  They're just dumb 
> > values.
> > * Enums themselves may have methods, static methods, or constants.
> > * Traits are supported, as long as they don't have properties.
> > * The value() method on scalar enums is now a property.
> >
> > The full RFC is here, and I recommend reading it again in full given how 
> > much was updated.
> 
> I did and the RFC looks really awesome :+1:
> 
> I don't have time to test the implementation but I noticed one thing:
> 
> > If the enumeration is not a Scalar Enum, the array will be packed
> (indexed sequentially starting from 0). If the enumeration is a Scalar
> Enum, the keys will be the corresponding scalar for each enumeration.
> 
> I don't think using the scalar values as keys is a good idea. What
> happens if we want to support scalar float values? (Why are they
> actually not supported in the first place?)

That's why floats are not supported, in fact, because what happens to them when 
they are made into an array key is non-obvious.  (PHP would say to convert to a 
string, but that's always fussy with possible data loss in some cases, etc.)  
We decided to just avoid that problem until/unless someone found a good use 
case for float enums.  No all languages support them as is, so there is 
precedent.

> Also I think it's more natural if both enum types return a
> zero-indexed-array of cases.

The goal is to make it easy to work with them, and having a clean lookup map 
readily available is very convenient.  If you don't care about the scalar 
equivalent then you can safely ignore them.  If you do want them, then you have 
a lookup table ready-made for you.  That's the logic we were working from.

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2020-12-29 Thread Marc


On 28.12.20 21:21, Larry Garfield wrote:
> Hello, Internalians!
>
> After considerable discussion and effort, Ilija and I are ready to offer you 
> round 2 on enumerations.  This is in the spirit of the previous discussion, 
> but based on that discussion a great deal has been reworked.  The main change 
> is that Enumeration Cases are now object instances of the Enumeration class 
> rather than their own class.  Most of the other changes are knock-on effects 
> of that.
>
> Of particular note:
>
> * Cases may not have methods or constants on them.  They're just dumb values.
> * Enums themselves may have methods, static methods, or constants.
> * Traits are supported, as long as they don't have properties.
> * The value() method on scalar enums is now a property.
>
> The full RFC is here, and I recommend reading it again in full given how much 
> was updated.

I did and the RFC looks really awesome :+1:

I don't have time to test the implementation but I noticed one thing:

> If the enumeration is not a Scalar Enum, the array will be packed
(indexed sequentially starting from 0). If the enumeration is a Scalar
Enum, the keys will be the corresponding scalar for each enumeration.

I don't think using the scalar values as keys is a good idea. What
happens if we want to support scalar float values? (Why are they
actually not supported in the first place?)

Also I think it's more natural if both enum types return a
zero-indexed-array of cases.


>
> https://wiki.php.net/rfc/enumerations
>
> The implementation is 98% complete; there's still a few lagging bits in 
> reflection, and some opcache bugs that Ilija is still stomping on.
>
> There are a few outstanding questions listed that we would like feedback on.  
> We're not entirely certain which direction to go with them, for reasons 
> explained in the RFC.  Input on those is especially welcome.
>
> Happy New Year.  May it be enumerable.
>

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2020-12-28 Thread Larry Garfield
On Mon, Dec 28, 2020, at 6:40 PM, Benjamin Morel wrote:
> Hi Larry, thank you for the updated RFC!
> I love it, and having played with the implementation, I can say I love it
> so far as well.
> 
> I have one suggestion regarding reflection:
> Shouldn't ReflectionCase expose an additional getInstance() method, that
> would return the case instance, such as Suit::HEARTS?

I... thought we had that in there.  Did I remove the wrong method?  I know it's 
in there somewhere.  Let me double check with Ilija on what it's supposed to be 
called.  Will update when that's sorted out.

> Also, I noticed 2 typos in the code samples:
> 
> - in "Enumerated Methods", 1st code block: missing "implements Colorful"
> after "enum Suit"
> - in "Enumerated Methods", 2nd code block: missing "public function
> color()" after "private function __construct() {}"

Both fixed, thanks.

> Finally, I got a segmentation fault while trying to use what I think is an
> unsupported syntax (removing the ":string" from a scalar enum), where is
> the correct place to report this? The GitHub PR?

On the PR, please.  Sounds like we need a few more negative tests to make sure 
it fails gracefully.

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Enumerations, Round 2

2020-12-28 Thread Benjamin Morel
Hi Larry, thank you for the updated RFC!
I love it, and having played with the implementation, I can say I love it
so far as well.

I have one suggestion regarding reflection:
Shouldn't ReflectionCase expose an additional getInstance() method, that
would return the case instance, such as Suit::HEARTS?

Also, I noticed 2 typos in the code samples:

- in "Enumerated Methods", 1st code block: missing "implements Colorful"
after "enum Suit"
- in "Enumerated Methods", 2nd code block: missing "public function
color()" after "private function __construct() {}"

Finally, I got a segmentation fault while trying to use what I think is an
unsupported syntax (removing the ":string" from a scalar enum), where is
the correct place to report this? The GitHub PR?

Good luck with the RFC!

- Benjamin

On Mon, 28 Dec 2020 at 21:22, Larry Garfield  wrote:

> Hello, Internalians!
>
> After considerable discussion and effort, Ilija and I are ready to offer
> you round 2 on enumerations.  This is in the spirit of the previous
> discussion, but based on that discussion a great deal has been reworked.
> The main change is that Enumeration Cases are now object instances of the
> Enumeration class rather than their own class.  Most of the other changes
> are knock-on effects of that.
>
> Of particular note:
>
> * Cases may not have methods or constants on them.  They're just dumb
> values.
> * Enums themselves may have methods, static methods, or constants.
> * Traits are supported, as long as they don't have properties.
> * The value() method on scalar enums is now a property.
>
> The full RFC is here, and I recommend reading it again in full given how
> much was updated.
>
> https://wiki.php.net/rfc/enumerations
>
> The implementation is 98% complete; there's still a few lagging bits in
> reflection, and some opcache bugs that Ilija is still stomping on.
>
> There are a few outstanding questions listed that we would like feedback
> on.  We're not entirely certain which direction to go with them, for
> reasons explained in the RFC.  Input on those is especially welcome.
>
> Happy New Year.  May it be enumerable.
>
> --
>   Larry Garfield
>   la...@garfieldtech.com
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>