[RFC][DISCUSSION] Object type hint, now with added variance

php.internals

Dan Ackroyd

9 years ago
Hi, This is the reintroduction of the Object Type RFC for discussion. There was previously strong feedback from people who would prefer that the inheritance checks for methods that use object types should be co/contravariant. This has been added to the RFC. https://wiki.php.net/rfc/object-typehint cheers Dan Ack

Levi Morrison

9 years ago
On Tue, Nov 22, 2016 at 5:52 PM, Dan Ackroyd <danack@basereality.com> wrote:
> Hi, > > This is the reintroduction of the Object Type RFC for discussion. > > There was previously strong feedback from people who would prefer that > the inheritance checks for methods that use object types should be > co/contravariant. This has been added to the RFC. > > https://wiki.php.net/rfc/object-typehint > > cheers > Dan > Ack > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php
I strongly oppose this additional variance on the grounds that it assumes that all types that are not statically known to the engine are objects. This is a restrictive future compatibility concern. For instance enumerations (or enums) are one possible type I can see us adding that may not be objects. Additionally if we ever add named aliases for types and union types then those types are not necessarily objects either. Giving up these options for the sake of object variance is definitely not prudent in my opinion.

Dan Ackroyd

9 years ago
Hi Levi, On 23 November 2016 at 01:25, Levi Morrison <levim@php.net> wrote:
> > it assumes that all types that are not statically known to the engine are > objects. This is a restrictive future compatibility concern.
Any RFC and/or patch can only deal with PHP as it currently is.
> Giving up these options for the sake of object > variance is definitely not prudent in my opinion.
We would not necessarily be giving them up. We are just adding a small amount of complexity that would need to be handled by future RFCs. Which is true of all RFCs.
> For instance enumerations (or enums) are one possible type I can see us > adding that may not be objects.
I very much look forward to the RFC for enums, and have for some time. When are you thinking of submitting it for discussion and voting? cheers Dan Ack

Niklas Keller

9 years ago
2016-11-24 9:58 GMT+01:00 Dan Ackroyd <danack@basereality.com>:
> Hi Levi, > > On 23 November 2016 at 01:25, Levi Morrison <levim@php.net> wrote: > > > > it assumes that all types that are not statically known to the engine are > > objects. This is a restrictive future compatibility concern. > > Any RFC and/or patch can only deal with PHP as it currently is.
No. We had a similar discussion for the context sensitive lexer RFC and didn't allow some things to make future features easier.
> > Giving up these options for the sake of object > > variance is definitely not prudent in my opinion. > > We would not necessarily be giving them up. We are just adding a small > amount of complexity that would need to be handled by future RFCs. >
It's not a small amount of complexity, otherwise we'd already have contra / covariance. Regards, Niklas

Dan Ackroyd

9 years ago
(resurrecting the thread....) On 24 November 2016 at 09:35, Niklas Keller <me@kelunik.com> wrote:
> It's not a small amount of complexity,
So that other people can understand the tradeoff, please could you detail the complexity as you understand it?
> otherwise we'd already have contra / covariance.
My understanding is that we already allow this where possible. For example your type-widening RFC https://wiki.php.net/rfc/parameter-no-type-variance What is the problem with allowing it here? cheers Dan

Dan Ackroyd

9 years ago
Hi Levi, On 24 November 2016 at 08:58, Dan Ackroyd <danack@basereality.com> wrote:
> Hi Levi, > > On 23 November 2016 at 01:25, Levi Morrison <levim@php.net> wrote: > >> For instance enumerations (or enums) are one possible type I can see us >> adding that may not be objects. > > I very much look forward to the RFC for enums, and have for some time. > When are you thinking of submitting it for discussion and voting?
I can understand your concerns. At the same time, I hope you can understand that people won't want to put off introducing features that they want in the meantime. I think if you were able to give a timeline for when an Enum RFC could be introduced, before the PHP 7.2 release, we could talk about whether it would be right to hold off on this RFC for now. Otherwise I suggest Michał updates the voting options, and we open the voting in a week or so. cheers Dan

Levi Morrison

9 years ago
On Tue, Feb 14, 2017 at 11:55 AM, Dan Ackroyd <danack@basereality.com> wrote:
> Hi Levi, > > On 24 November 2016 at 08:58, Dan Ackroyd <danack@basereality.com> wrote: >> Hi Levi, >> >> On 23 November 2016 at 01:25, Levi Morrison <levim@php.net> wrote: >> >>> For instance enumerations (or enums) are one possible type I can see us >>> adding that may not be objects. >> >> I very much look forward to the RFC for enums, and have for some time. >> When are you thinking of submitting it for discussion and voting? > > I can understand your concerns. At the same time, I hope you can > understand that people won't want to put off introducing features that > they want in the meantime. > > I think if you were able to give a timeline for when an Enum RFC could > be introduced, before the PHP 7.2 release, we could talk about whether > it would be right to hold off on this RFC for now. > > Otherwise I suggest Michał updates the voting options, and we open the > voting in a week or so. > > cheers > Dan
Let me clarify that I'm not against this object variance; there is nothing intrinsic about object variance that prevents enums (or typedefs/type aliases). Rather it's *how* it is achieving that variance that is an issue. This is something that should ship along with full covariance/contravariance and not be a special case which may unintended side-effects later (such as preventing enums without breaking BC). Does that make sense?

Levi Morrison

9 years ago
On Tue, Feb 14, 2017 at 2:14 PM, Levi Morrison <levim@php.net> wrote:
> On Tue, Feb 14, 2017 at 11:55 AM, Dan Ackroyd <danack@basereality.com> wrote: >> Hi Levi, >> >> On 24 November 2016 at 08:58, Dan Ackroyd <danack@basereality.com> wrote: >>> Hi Levi, >>> >>> On 23 November 2016 at 01:25, Levi Morrison <levim@php.net> wrote: >>> >>>> For instance enumerations (or enums) are one possible type I can see us >>>> adding that may not be objects. >>> >>> I very much look forward to the RFC for enums, and have for some time. >>> When are you thinking of submitting it for discussion and voting? >> >> I can understand your concerns. At the same time, I hope you can >> understand that people won't want to put off introducing features that >> they want in the meantime. >> >> I think if you were able to give a timeline for when an Enum RFC could >> be introduced, before the PHP 7.2 release, we could talk about whether >> it would be right to hold off on this RFC for now. >> >> Otherwise I suggest Michał updates the voting options, and we open the >> voting in a week or so. >> >> cheers >> Dan > > Let me clarify that I'm not against this object variance; there is > nothing intrinsic about object variance that prevents enums (or > typedefs/type aliases). Rather it's *how* it is achieving that > variance that is an issue. This is something that should ship along > with full covariance/contravariance and not be a special case which > may unintended side-effects later (such as preventing enums without > breaking BC). Does that make sense?
Here's a concrete compatibility concern. Let's assume we have the following code: interface Factory { function make(...$args): object; } class FooFactory { function make(...$args): Foo; } Currently the engine would not have to know anything about Foo to know if it is a sub-type of object. It would not need to require it to even be defined. However, if at some point in the future we add non-object types it may now error or autoload. The way to avoid the compatibility concern is to implement this feature the same way we wold implement full covariance, which would similarly need to know about the types involved. Does that make more sense as to why the assumption that unknown types are object types is an issue?

Levi Morrison

9 years ago
(Oops, I forgot to inherit the interface: interface Factory { function make(...$args): object; } class FooFactory implements Factory { function make(...$args): Foo; } sorry for the noise)

Marco Pivetta

9 years ago
Hi Levi, On 14 Feb 2017 10:20 p.m., "Levi Morrison" <levim@php.net> wrote: On Tue, Feb 14, 2017 at 2:14 PM, Levi Morrison <levim@php.net> wrote:
> On Tue, Feb 14, 2017 at 11:55 AM, Dan Ackroyd <danack@basereality.com>
wrote:
>> Hi Levi, >> >> On 24 November 2016 at 08:58, Dan Ackroyd <danack@basereality.com> wrote: >>> Hi Levi, >>> >>> On 23 November 2016 at 01:25, Levi Morrison <levim@php.net> wrote: >>> >>>> For instance enumerations (or enums) are one possible type I can see us >>>> adding that may not be objects. >>> >>> I very much look forward to the RFC for enums, and have for some time. >>> When are you thinking of submitting it for discussion and voting? >> >> I can understand your concerns. At the same time, I hope you can >> understand that people won't want to put off introducing features that >> they want in the meantime. >> >> I think if you were able to give a timeline for when an Enum RFC could >> be introduced, before the PHP 7.2 release, we could talk about whether >> it would be right to hold off on this RFC for now. >> >> Otherwise I suggest Michał updates the voting options, and we open the >> voting in a week or so. >> >> cheers >> Dan > > Let me clarify that I'm not against this object variance; there is > nothing intrinsic about object variance that prevents enums (or > typedefs/type aliases). Rather it's *how* it is achieving that > variance that is an issue. This is something that should ship along > with full covariance/contravariance and not be a special case which > may unintended side-effects later (such as preventing enums without > breaking BC). Does that make sense?
Here's a concrete compatibility concern. Let's assume we have the following code: interface Factory { function make(...$args): object; } class FooFactory { function make(...$args): Foo; } Currently the engine would not have to know anything about Foo to know if it is a sub-type of object. It would not need to require it to even be defined. However, if at some point in the future we add non-object types it may now error or autoload. Since the engine is clueless about types until autoloading happens, this is easily solvable by providing a marker syntax for non-object hints. For instance `function foo() : enym:MyEnum {}` The current (and valid) assumption by both the engine and userland reflectors is that anything after the `:` in a return type declaration is one of: * bool * array * int * float * string * callable * void * $classOrInterfaceName Regardless of this RFC, and considered that `object` is an already reserved keyword, you can't use the same syntax for enum types anyway, since you're going to break a crapton of userland code. The way to avoid the compatibility concern is to implement this feature the same way we wold implement full covariance, which would similarly need to know about the types involved. Does that make more sense as to why the assumption that unknown types are object types is an issue?
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php Given inline comments above, can we archive the enum discussion?

Andrew Faulds

9 years ago
Hi Marco, Marco Pivetta wrote:
> > Since the engine is clueless about types until autoloading happens, this is > easily solvable by providing a marker syntax for non-object hints. For > instance `function foo() : enym:MyEnum {}`
If we're going to do prefixes for non-classes, we might as well copy C outright: `enum MyEnum`. Thanks.
-- Andrea Faulds https://ajf.me/

Rasmus Schultz

9 years ago
In the light of this, maybe enums (assuming this feature comes first) should be implemented as immutable objects rather than values? Type-checking for enums would be important, so in PHP terms, an enum "instance" would likely be closer to an object than a value in nature anyway. The way I look at it, this feature doesn't prevent enums from happening, it just changes the design parameters. Just a thought. On Wed, Feb 15, 2017 at 4:34 PM, Andrea Faulds <ajf@ajf.me> wrote:

Michał Brzuchalski

9 years ago
Assumming they would be closer to immutable objects they may have some usefull... I was gonna say methods but the term doesn't fit to enums. But using one of my favourite userland implementation such as `esky\enum` package there are ways to create enumeration from value or from name. Those methods are quite usefull when converting user data passed in request from string to enumeration. Given the example: enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY } When using passed from request data proper enumeration could be restored for eg. $_GET['day'] = 'MONDAY'; $day = Day::fromName($_GET['day']); // Day.MONDAY or by value $day = Day::fromValue(0); // Day.MONDAY Think of it as possible way of restoring from primitive types because then enums would really be closer to classes than values. And also then could even utilise `object 2017-02-15 20:53 GMT+01:00 Rasmus Schultz <rasmus@mindplay.dk>:
> In the light of this, maybe enums (assuming this feature comes first) > should be implemented as immutable objects rather than values? > > Type-checking for enums would be important, so in PHP terms, an enum > "instance" would likely be closer to an object than a value in nature > anyway. > > The way I look at it, this feature doesn't prevent enums from happening, it > just changes the design parameters. > > Just a thought. > > > On Wed, Feb 15, 2017 at 4:34 PM, Andrea Faulds <ajf@ajf.me> wrote: > > > Hi Marco, > > > > Marco Pivetta wrote: > > > >> > >> Since the engine is clueless about types until autoloading happens, this > >> is > >> easily solvable by providing a marker syntax for non-object hints. For > >> instance `function foo() : enym:MyEnum {}` > >> > > > > If we're going to do prefixes for non-classes, we might as well copy C > > outright: `enum MyEnum`. > > > > Thanks. > > -- > > Andrea Faulds > > https://ajf.me/ > > > > > > -- > > PHP Internals - PHP Runtime Development Mailing List > > To unsubscribe, visit: http://www.php.net/unsub.php > > > > >
-- regards / pozdrawiam, -- Michał Brzuchalski about.me/brzuchal brzuchalski.com

Nikita Popov

9 years ago
On Tue, Feb 14, 2017 at 10:20 PM, Levi Morrison <levim@php.net> wrote:
> On Tue, Feb 14, 2017 at 2:14 PM, Levi Morrison <levim@php.net> wrote: > > On Tue, Feb 14, 2017 at 11:55 AM, Dan Ackroyd <danack@basereality.com> > wrote: > >> Hi Levi, > >> > >> On 24 November 2016 at 08:58, Dan Ackroyd <danack@basereality.com> > wrote: > >>> Hi Levi, > >>> > >>> On 23 November 2016 at 01:25, Levi Morrison <levim@php.net> wrote: > >>> > >>>> For instance enumerations (or enums) are one possible type I can see > us > >>>> adding that may not be objects. > >>> > >>> I very much look forward to the RFC for enums, and have for some time. > >>> When are you thinking of submitting it for discussion and voting? > >> > >> I can understand your concerns. At the same time, I hope you can > >> understand that people won't want to put off introducing features that > >> they want in the meantime. > >> > >> I think if you were able to give a timeline for when an Enum RFC could > >> be introduced, before the PHP 7.2 release, we could talk about whether > >> it would be right to hold off on this RFC for now. > >> > >> Otherwise I suggest Michał updates the voting options, and we open the > >> voting in a week or so. > >> > >> cheers > >> Dan > > > > Let me clarify that I'm not against this object variance; there is > > nothing intrinsic about object variance that prevents enums (or > > typedefs/type aliases). Rather it's *how* it is achieving that > > variance that is an issue. This is something that should ship along > > with full covariance/contravariance and not be a special case which > > may unintended side-effects later (such as preventing enums without > > breaking BC). Does that make sense? > > Here's a concrete compatibility concern. Let's assume we have the > following code: > > interface Factory { > function make(...$args): object; > } > > class FooFactory { > function make(...$args): Foo; > } > > Currently the engine would not have to know anything about Foo to know > if it is a sub-type of object. It would not need to require it to even > be defined. > > However, if at some point in the future we add non-object types it may > now error or autoload. > > The way to avoid the compatibility concern is to implement this > feature the same way we wold implement full covariance, which would > similarly need to know about the types involved. > > Does that make more sense as to why the assumption that unknown types > are object types is an issue? >
Thanks, this argument is convincing. Overall, I think the utility of the object typehint is very limited. If introducing an object typehint now will pose issues for an enum implementation later (which I consider significantly more important), I would prefer to defer its introduction until a later time. People have pointed out that there will still be ways to implement enums without breaking BC, either by prefixing enum type annotations with "enum", or by making enum values objects. These suggestions may have merit, but they should be evaluated on their *own* merit when the proposal comes up. We should avoid being forced into a corner where we have to chose a specific implementation due to BC concerns. Nikita

Marco Pivetta

9 years ago
This looks awesome to me: nicely cleaned up! 👍 On 23 Nov 2016 01:52, "Dan Ackroyd" <danack@basereality.com> wrote:

Joe Watkins

9 years ago
Morning Dan, I took the liberty of removing the old voting doodle, updating the status on the RFC, and moving to appropriate place on /rfc index. Also, I corrected a typo. LGTM. Cheers Joe On Wed, Nov 23, 2016 at 1:42 AM, Marco Pivetta <ocramius@gmail.com> wrote:

Michał Brzuchalski

9 years ago
Hi All, I've added link to 3v4l.org at the bootom of RFC document so it is possible to execute code online on compiled patch at https://3v4l.org/ results are presented on tab "RFC Branches" Cheers, Michał 2016-11-23 6:47 GMT+01:00 Joe Watkins <pthreads@pthreads.org>:
> Morning Dan, > > I took the liberty of removing the old voting doodle, updating the status > on the RFC, and moving to appropriate place on /rfc index. > > Also, I corrected a typo. > > LGTM. > > Cheers > Joe > > On Wed, Nov 23, 2016 at 1:42 AM, Marco Pivetta <ocramius@gmail.com> wrote: > > > This looks awesome to me: nicely cleaned up! 👍 > > > > On 23 Nov 2016 01:52, "Dan Ackroyd" <danack@basereality.com> wrote: > > > > > Hi, > > > > > > This is the reintroduction of the Object Type RFC for discussion. > > > > > > There was previously strong feedback from people who would prefer that > > > the inheritance checks for methods that use object types should be > > > co/contravariant. This has been added to the RFC. > > > > > > https://wiki.php.net/rfc/object-typehint > > > > > > cheers > > > Dan > > > Ack > > > > > > -- > > > PHP Internals - PHP Runtime Development Mailing List > > > To unsubscribe, visit: http://www.php.net/unsub.php > > > > > > > > >
-- regards / pozdrawiam, -- Michał Brzuchalski about.me/brzuchal brzuchalski.com

Marc Bennewitz

9 years ago
Am 23.11.2016 um 01:52 schrieb Dan Ackroyd:
> Hi, > > This is the reintroduction of the Object Type RFC for discussion. > > There was previously strong feedback from people who would prefer that > the inheritance checks for methods that use object types should be > co/contravariant. This has been added to the RFC. > > https://wiki.php.net/rfc/object-typehint
I like this RFC :) And I have a question where I'm not sure if that should be catched by this RFC, too: If I declare a return type of "object" and extends that to return "static" it doesn't compile because "static" is not a valid return type yet. https://3v4l.org/lp3AB/rfc#version=rfc-typed-properties class Test { public static function factory() : object { return new static(); } } class Test2 extends Test { public static function factory() : static { return parent::factory(); } }

David Rodrigues

9 years ago
Marc Bennewitz wrote:
> If I declare a return type of "object" and extends that to return "static" it doesn't compile because "static" is not a valid return type yet. > https://3v4l.org/lp3AB/rfc#version=rfc-typed-properties
I think that it is need too, because it will avoid reference the class by name when you need return it - but not is a biiig problem too. 2016-11-23 9:07 GMT-02:00 Marc Bennewitz <dev@mabe.berlin>:
> > > Am 23.11.2016 um 01:52 schrieb Dan Ackroyd: >> >> Hi, >> >> This is the reintroduction of the Object Type RFC for discussion. >> >> There was previously strong feedback from people who would prefer that >> the inheritance checks for methods that use object types should be >> co/contravariant. This has been added to the RFC. >> >> https://wiki.php.net/rfc/object-typehint > > > I like this RFC :) > > And I have a question where I'm not sure if that should be catched by this > RFC, too: > > If I declare a return type of "object" and extends that to return "static" > it doesn't compile because "static" is not a valid return type yet. > > https://3v4l.org/lp3AB/rfc#version=rfc-typed-properties > > class Test { > public static function factory() : object { > return new static(); > } > } > > class Test2 extends Test { > public static function factory() : static { > return parent::factory(); > > } > } > > >> >> cheers >> Dan >> Ack >> > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php >
-- David Rodrigues

Dan Ackroyd

9 years ago
On 23 November 2016 at 11:07, Marc Bennewitz <dev@mabe.berlin> wrote:
> > If I declare a return type of "object" and extends that to return "static" > it doesn't compile because "static" is not a valid return type yet. >
Hi Marc, That should be part of a separate RFC, that is focused on making static a valid return type. cheers Dan