Re: [PHP-DEV] Re: [RFC] Traits with interfaces
On 05/03/2016 23:15, Davey Shafik wrote: You are mid-reading, none of the classes in my examples extend the others, they are all just using the same trait in different ways. - Class a: use the trait with no aliases. Result: as expected - Class b: use the trait with a simple alias, no visibility change. Result: both methods Right, the reason I was looking at inheritance was this line: ... and_will_ override inherited methods of the same name. I misunderstood that the rest of the examples were also about how inheritance behaved. For the one you can't re-produce, it's class 'c', which is stand-alone here: https://3v4l.org/K9o6Y Right, so this is actually consistent, because the resulting "stitched together" class looks like this: class C { public function bar() {} private function bat() {} } Whereas when the alias wasn't private, it looked liked this: class B { public function bar() {} public function bat() {} } You can actually change its visibility on one line and alias it on another: class e { use foo { bar as private; bar as bat; } } https://3v4l.org/80gKF Stitched togorther, that gives you: class e { private function bar() {} public function bat() {} } So the main confusion is that "bar as private bat" != "bar as private" + "bar as bat". :) Regards, -- Rowan Collins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Re: [RFC] Traits with interfaces
On 03/04/2016 01:17 AM, Davey Shafik wrote: On Thu, Mar 3, 2016 at 2:19 PM, Stephen Coakleywrote: On Wed, 17 Feb 2016 09:25:50 -0500, Kevin Gessner wrote: Hello internals team! I'd like to propose an RFC to allow traits to implement interfaces. I've noticed s pattern in Etsy's code and elsewhere, where a trait provides a common implementation of an interface. Classes that use the trait are required to also explicitly declare the interface to benefit. I propose that traits be permitted to declare and implement interfaces. Classes that use such a trait would then implement the interface, as though it were declared on the class, without declaring the interface explicitly. I believe this small change would be a useful improvement to the OO system. I've written a draft RFC, but I don't have karma to create the wiki page for it. Could someone please grant wiki karma to my account, kevingessner? I don't yet have an implementation, but I'll be starting on one once I've posted the RFC. I look forward to your thoughts and feedback. Thanks in advance -- Kevin Kevin Gessner Staff Software Engineer etsy.com tl;dr: +1 and I really think that this language addition is useful and makes sense. Wow, I really want this feature. Reminds me of how powerful traits are in some other languages, such as Rust. It is very common to use traits to provide a common interface for something, but with some default implementations. Logging is a great example. Your interface might look like this (a familiar one, eh?): interface Logger { public function log($level, $message, array $context = array()); public function error($message, array $context = array()); public function warning($message, array $context = array()); // etc... } where the idea is that the `error()` and such methods are a convenience for calling `log()` with a specific logging level. Obviously, these methods will be implemented in the same fashion most of the time; a trait would be great: trait LoggerTrait implements Logger { abstract public function log($level, $message, array $context = array ()); public function error($message, array $context = array()) { return $this->log(ERROR, $message, $context); } // etc... } With this approach, I totally agree that allowing the `LoggerTrait` to implement the interface makes sense; it allows implementation to be enforced at the trait level. The second proposal that infers the interface implementation when using the trait is nice too (though not completely mandatory). It is pretty much the same situation where you do not have to re-implement an interface when extending a base class that already implements it. -- Stephen The aliases issue is a little more nuanced and potentially confusing, regardless of this interface thing: As you can see here: https://3v4l.org/L23LJ 1. If you simply alias (use foo { bar as bat; }) then you end up with an *additional* method with the new name, the trait method as defined is still brought in, and _will_ override inherited methods of the same name. 2. if you try to just change the visibility, you get a fatal error (Fatal error: Trait method bar has not been applied, because there are collisions with other trait methods), you must create an aliased name with the new visibility 3. Doing this (visibility + name) _only_ gives you the new method, which is _different_ behavior to #1 If the third behaved the same as the first, then this would be a non-issue. Unfortunately, changing this behavior would be a — particularly hard to diagnose — BC break and therefore cannot happen IMO. Perhaps we could look at an alternative such as: - traits can implement interfaces, which would ensure the _trait_ adheres to it, but _not_ automatically classes use'ing it. - Add a new syntax: "use Trait with Interface" or "use Trait implements Interface" or "use Trait { implements Interface; }" which *explicitly* calls out this usage Just some off-the-top of my head thinking as an alternative. - Davey I freely admit; the method aliasing does pose an interesting issue, and may be good enough reason to simply allow enforcing interfaces at the trait level and simply force users of the trait to explicitly implement the interface themselves. That way it is easy to check compliance -- aliasing a method part of the interface on the trait to a different name simply breaks the contract. -- Stephen -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Re: [RFC] Traits with interfaces
Your class 'c' example (last link) only shows method 'bar' (the trait method) and not 'bat' (the aliased metod). The class has both, but 'bat' is hidden from get_class_methods() because it is private. On 6 Mar 2016 10:16 am, "Davey Shafik"wrote: > On Fri, Mar 4, 2016 at 2:06 AM, Rowan Collins > wrote: > > > Davey Shafik wrote on 04/03/2016 07:17: > > > >> 1. If you simply alias (use foo { bar as bat; }) then you end up with an > >> *additional* method with the new name, the trait method as defined is > >> still > >> brought in, and_will_ override inherited methods of the same name. > >> > > > > Here's a clearer example of this: https://3v4l.org/RKHPt > > > > Unfortunately, you can't even use "insteadof" to directly bring the > parent > > method back in [https://3v4l.org/qOS5T], but you can stub it out with a > > direct call to parent:: [https://3v4l.org/s9i4N]. > > > > 3. Doing this (visibility + name)_only_ gives you the new method, which > is > >> _different_ behavior to #1 > >> > > > > I can't reproduce this: if I say "bar as private bat", the trait's bar > > still shows up, and is public, just as in the previous example: > > https://3v4l.org/1jH6o > > > > Your examples are rather confusing because they are effectively applying > > the same trait twice, at different levels of the hierarchy; I'm not sure > > this is a particularly likely scenario, or relevant to how interfaces > > should behave. > > > > Regards, > > > Rowan, > > You are mid-reading, none of the classes in my examples extend the others, > they are all just using the same trait in different ways. > > - Class a: use the trait with no aliases. Result: as expected > - Class b: use the trait with a simple alias, no visibility change. Result: > both methods > - Class c: use the trait with and alias both name, and change visibility. > Result: ONLY the aliased method > - Class d: use the trait and "alias" to the same name, ONLY changing > visibility. Result: causes a Fatal error, clashing with itself o.O > > For the one you can't re-produce, it's class 'c', which is stand-alone > here: https://3v4l.org/K9o6Y > > - Davey >
Re: [PHP-DEV] Re: [RFC] Traits with interfaces
On Fri, Mar 4, 2016 at 2:06 AM, Rowan Collinswrote: > Davey Shafik wrote on 04/03/2016 07:17: > >> 1. If you simply alias (use foo { bar as bat; }) then you end up with an >> *additional* method with the new name, the trait method as defined is >> still >> brought in, and_will_ override inherited methods of the same name. >> > > Here's a clearer example of this: https://3v4l.org/RKHPt > > Unfortunately, you can't even use "insteadof" to directly bring the parent > method back in [https://3v4l.org/qOS5T], but you can stub it out with a > direct call to parent:: [https://3v4l.org/s9i4N]. > > 3. Doing this (visibility + name)_only_ gives you the new method, which is >> _different_ behavior to #1 >> > > I can't reproduce this: if I say "bar as private bat", the trait's bar > still shows up, and is public, just as in the previous example: > https://3v4l.org/1jH6o > > Your examples are rather confusing because they are effectively applying > the same trait twice, at different levels of the hierarchy; I'm not sure > this is a particularly likely scenario, or relevant to how interfaces > should behave. > > Regards, Rowan, You are mid-reading, none of the classes in my examples extend the others, they are all just using the same trait in different ways. - Class a: use the trait with no aliases. Result: as expected - Class b: use the trait with a simple alias, no visibility change. Result: both methods - Class c: use the trait with and alias both name, and change visibility. Result: ONLY the aliased method - Class d: use the trait and "alias" to the same name, ONLY changing visibility. Result: causes a Fatal error, clashing with itself o.O For the one you can't re-produce, it's class 'c', which is stand-alone here: https://3v4l.org/K9o6Y - Davey
Re: [PHP-DEV] Re: [RFC] Traits with interfaces
Davey Shafik wrote on 04/03/2016 07:17: 1. If you simply alias (use foo { bar as bat; }) then you end up with an *additional* method with the new name, the trait method as defined is still brought in, and_will_ override inherited methods of the same name. Here's a clearer example of this: https://3v4l.org/RKHPt Unfortunately, you can't even use "insteadof" to directly bring the parent method back in [https://3v4l.org/qOS5T], but you can stub it out with a direct call to parent:: [https://3v4l.org/s9i4N]. 3. Doing this (visibility + name)_only_ gives you the new method, which is _different_ behavior to #1 I can't reproduce this: if I say "bar as private bat", the trait's bar still shows up, and is public, just as in the previous example: https://3v4l.org/1jH6o Your examples are rather confusing because they are effectively applying the same trait twice, at different levels of the hierarchy; I'm not sure this is a particularly likely scenario, or relevant to how interfaces should behave. Regards, -- Rowan Collins [IMSoP]
Re: [PHP-DEV] Re: [RFC] Traits with interfaces
On Thu, Mar 3, 2016 at 2:19 PM, Stephen Coakleywrote: > On Wed, 17 Feb 2016 09:25:50 -0500, Kevin Gessner wrote: > > > Hello internals team! I'd like to propose an RFC to allow traits to > > implement interfaces. > > > > I've noticed s pattern in Etsy's code and elsewhere, where a trait > > provides a common implementation of an interface. Classes that use the > > trait are required to also explicitly declare the interface to benefit. > > I propose that traits be permitted to declare and implement interfaces. > > Classes that use such a trait would then implement the interface, as > > though it were declared on the class, without declaring the interface > > explicitly. > > > > I believe this small change would be a useful improvement to the OO > > system. I've written a draft RFC, but I don't have karma to create the > > wiki page for it. Could someone please grant wiki karma to my account, > > kevingessner? > > > > I don't yet have an implementation, but I'll be starting on one once > > I've posted the RFC. I look forward to your thoughts and feedback. > > > > Thanks in advance -- Kevin > > > > Kevin Gessner Staff Software Engineer etsy.com > > tl;dr: +1 and I really think that this language addition is useful and > makes sense. > > Wow, I really want this feature. Reminds me of how powerful traits are in > some other languages, such as Rust. It is very common to use traits to > provide a common interface for something, but with some default > implementations. > > Logging is a great example. Your interface might look like this (a > familiar one, eh?): > > interface Logger > { > public function log($level, $message, array $context = array()); > public function error($message, array $context = array()); > public function warning($message, array $context = array()); > // etc... > } > > where the idea is that the `error()` and such methods are a convenience > for calling `log()` with a specific logging level. Obviously, these > methods will be implemented in the same fashion most of the time; a trait > would be great: > > trait LoggerTrait implements Logger > { > abstract public function log($level, $message, array $context = array > ()); > public function error($message, array $context = array()) { > return $this->log(ERROR, $message, $context); > } > // etc... > } > > With this approach, I totally agree that allowing the `LoggerTrait` to > implement the interface makes sense; it allows implementation to be > enforced at the trait level. The second proposal that infers the interface > implementation when using the trait is nice too (though not completely > mandatory). It is pretty much the same situation where you do not have to > re-implement an interface when extending a base class that already > implements it. > > -- > Stephen The aliases issue is a little more nuanced and potentially confusing, regardless of this interface thing: As you can see here: https://3v4l.org/L23LJ 1. If you simply alias (use foo { bar as bat; }) then you end up with an *additional* method with the new name, the trait method as defined is still brought in, and _will_ override inherited methods of the same name. 2. if you try to just change the visibility, you get a fatal error (Fatal error: Trait method bar has not been applied, because there are collisions with other trait methods), you must create an aliased name with the new visibility 3. Doing this (visibility + name) _only_ gives you the new method, which is _different_ behavior to #1 If the third behaved the same as the first, then this would be a non-issue. Unfortunately, changing this behavior would be a — particularly hard to diagnose — BC break and therefore cannot happen IMO. Perhaps we could look at an alternative such as: - traits can implement interfaces, which would ensure the _trait_ adheres to it, but _not_ automatically classes use'ing it. - Add a new syntax: "use Trait with Interface" or "use Trait implements Interface" or "use Trait { implements Interface; }" which *explicitly* calls out this usage Just some off-the-top of my head thinking as an alternative. - Davey
Re: [PHP-DEV] Re: [RFC] Traits with interfaces
On 24 February 2016 at 22:04, Chase Peelerwrote: > > > On Wed, Feb 24, 2016 at 4:46 PM Kevin Gessner wrote: > >> On Tue, Feb 23, 2016 at 4:48 AM, Chris Riley wrote: >> >> > This isn't such a great idea as it will cause some of traits >> functionality >> > to be broken: I can currently use a trait and alias its methods and >> change >> > their visibility. If a trait implements an interface which is copied >> onto >> > my class I can no longer do this as the compiler will throw a fatal >> error >> > for the class not correctly implementing the interface that got copied >> from >> > the trait. >> > >> >> This is only true under Proposal 2 of the RFC, and this is listed as an >> open issue: https://wiki.php.net/rfc/traits-with-interfaces#proposal_2 >> >> Proposal 1, where the engine enforces interface declarations on traits, >> doesn't affect how traits are inserted and still allows aliasing. >> >> >> > If you decide to continue pursuing this RFC, I'd like to see some >> thought >> > given to the above; perhaps it could be as simple as not copying the >> > interface if aliases/visibility changes are made in the use or perhaps >> > something more complex which allows specifying which interfaces should >> be >> > copied into the class from the trait. >> > >> >> I agree that there are several reasonable solutions here, but I'm not sure >> which is the best. It does feel too aggressive to have it be a fatal >> error >> if aliasing undoes the interface implementation. At the same time, >> introducing new syntax to enable aliasing to work with interface >> propagation defeats the purpose, which is to make it easier and simpler to >> implement an interface via a trait. >> >> I'd be interested to hear if you have any ideas about how this should >> look. I'm mostly unfamiliar with aliasing traits in practice, so I'd be >> curious to see how this RFC would affect your code. >> >> Since the class doesn't know you are using the trait to implement the > interface, if you alias the trait method, then the class no longer > implements the interface unless it defines the method that is now missing > itself. > > Remember, the contents of the trait are just getting copy/pasted into the > class. If you alias a method, then the method gets pasted in using the > alias, not the original name. > > That being said, it should be rare that you would alias a method and then > not implement the method yourself - as the need to redefine/expand on its > functionality is the reason you usually alias a trait method. > > > >> Cheers >> -- Kevin >> > -- > -- Chase > chasepee...@gmail.com > Aliasing isn't something I use often; however changing visibility is - such that the methods in the trait become an implementation detail for the class in question and don't pollute it's public API. That would break if an interface was copied onto my class.
Re: [PHP-DEV] Re: [RFC] Traits with interfaces
On Wed, Feb 24, 2016 at 4:46 PM Kevin Gessnerwrote: > On Tue, Feb 23, 2016 at 4:48 AM, Chris Riley wrote: > > > This isn't such a great idea as it will cause some of traits > functionality > > to be broken: I can currently use a trait and alias its methods and > change > > their visibility. If a trait implements an interface which is copied onto > > my class I can no longer do this as the compiler will throw a fatal error > > for the class not correctly implementing the interface that got copied > from > > the trait. > > > > This is only true under Proposal 2 of the RFC, and this is listed as an > open issue: https://wiki.php.net/rfc/traits-with-interfaces#proposal_2 > > Proposal 1, where the engine enforces interface declarations on traits, > doesn't affect how traits are inserted and still allows aliasing. > > > > If you decide to continue pursuing this RFC, I'd like to see some thought > > given to the above; perhaps it could be as simple as not copying the > > interface if aliases/visibility changes are made in the use or perhaps > > something more complex which allows specifying which interfaces should be > > copied into the class from the trait. > > > > I agree that there are several reasonable solutions here, but I'm not sure > which is the best. It does feel too aggressive to have it be a fatal error > if aliasing undoes the interface implementation. At the same time, > introducing new syntax to enable aliasing to work with interface > propagation defeats the purpose, which is to make it easier and simpler to > implement an interface via a trait. > > I'd be interested to hear if you have any ideas about how this should > look. I'm mostly unfamiliar with aliasing traits in practice, so I'd be > curious to see how this RFC would affect your code. > > Since the class doesn't know you are using the trait to implement the interface, if you alias the trait method, then the class no longer implements the interface unless it defines the method that is now missing itself. Remember, the contents of the trait are just getting copy/pasted into the class. If you alias a method, then the method gets pasted in using the alias, not the original name. That being said, it should be rare that you would alias a method and then not implement the method yourself - as the need to redefine/expand on its functionality is the reason you usually alias a trait method. > Cheers > -- Kevin > -- -- Chase chasepee...@gmail.com
Re: [PHP-DEV] Re: [RFC] Traits with interfaces
On Tue, Feb 23, 2016 at 4:48 AM, Chris Rileywrote: > This isn't such a great idea as it will cause some of traits functionality > to be broken: I can currently use a trait and alias its methods and change > their visibility. If a trait implements an interface which is copied onto > my class I can no longer do this as the compiler will throw a fatal error > for the class not correctly implementing the interface that got copied from > the trait. > This is only true under Proposal 2 of the RFC, and this is listed as an open issue: https://wiki.php.net/rfc/traits-with-interfaces#proposal_2 Proposal 1, where the engine enforces interface declarations on traits, doesn't affect how traits are inserted and still allows aliasing. > If you decide to continue pursuing this RFC, I'd like to see some thought > given to the above; perhaps it could be as simple as not copying the > interface if aliases/visibility changes are made in the use or perhaps > something more complex which allows specifying which interfaces should be > copied into the class from the trait. > I agree that there are several reasonable solutions here, but I'm not sure which is the best. It does feel too aggressive to have it be a fatal error if aliasing undoes the interface implementation. At the same time, introducing new syntax to enable aliasing to work with interface propagation defeats the purpose, which is to make it easier and simpler to implement an interface via a trait. I'd be interested to hear if you have any ideas about how this should look. I'm mostly unfamiliar with aliasing traits in practice, so I'd be curious to see how this RFC would affect your code. Cheers -- Kevin
Re: [PHP-DEV] Re: [RFC] Traits with interfaces
On 23 February 2016 at 00:37, Alex Bowerswrote: > Would a fair solution to this be having the using class define whether to > inherit the implementations? Perhaps a new keyword akin to 'propagated', so > the code will read > > Class Foo { >Use propagated TraitName; > } > > Only then will the implementations from that trait bubble through. If it > isn't declared then the implementations are not visible. This should keep > all backwards compatibility and keep code readable since now we can > immediately tell which traits being used do we want the implementations for > in the main class. > On 22 Feb 2016 20:19, "Kevin Gessner" wrote: > > > On Thu, Feb 18, 2016 at 4:13 PM, Kevin Gessner > wrote: > > > > > On Wed, Feb 17, 2016 at 2:05 PM, Kevin Gessner > > wrote: > > > > > >> I've created a proper RFC wiki page here with the draft: > > >> https://wiki.php.net/rfc/traits-with-interfaces > > >> > > >> It includes more detail and several example code snippets. Thanks all > > >> for your feedback so far. > > >> > > > > > > I've just updated the RFC to v0.2, presenting two proposals to be voted > > > separately: one to allow traits to declare and implement interfaces, > and > > a > > > second (dependent on the first) to propagate interface declarations > from > > > traits to classes. > > > > > > > I've created a php-src pull request for Proposal 1 of the RFC, allowing > > traits to declare and implement interfaces: > > https://github.com/php/php-src/pull/1773 > > > > Reviews and feedback welcome! > > > > I haven't yet started on an implementation for Proposal 2. > > > > Cheers > > -- Kevin > > > This isn't such a great idea as it will cause some of traits functionality to be broken: I can currently use a trait and alias its methods and change their visibility. If a trait implements an interface which is copied onto my class I can no longer do this as the compiler will throw a fatal error for the class not correctly implementing the interface that got copied from the trait. If you decide to continue pursuing this RFC, I'd like to see some thought given to the above; perhaps it could be as simple as not copying the interface if aliases/visibility changes are made in the use or perhaps something more complex which allows specifying which interfaces should be copied into the class from the trait. ~C
Re: [PHP-DEV] Re: [RFC] Traits with interfaces
Would a fair solution to this be having the using class define whether to inherit the implementations? Perhaps a new keyword akin to 'propagated', so the code will read Class Foo { Use propagated TraitName; } Only then will the implementations from that trait bubble through. If it isn't declared then the implementations are not visible. This should keep all backwards compatibility and keep code readable since now we can immediately tell which traits being used do we want the implementations for in the main class. On 22 Feb 2016 20:19, "Kevin Gessner"wrote: > On Thu, Feb 18, 2016 at 4:13 PM, Kevin Gessner wrote: > > > On Wed, Feb 17, 2016 at 2:05 PM, Kevin Gessner > wrote: > > > >> I've created a proper RFC wiki page here with the draft: > >> https://wiki.php.net/rfc/traits-with-interfaces > >> > >> It includes more detail and several example code snippets. Thanks all > >> for your feedback so far. > >> > > > > I've just updated the RFC to v0.2, presenting two proposals to be voted > > separately: one to allow traits to declare and implement interfaces, and > a > > second (dependent on the first) to propagate interface declarations from > > traits to classes. > > > > I've created a php-src pull request for Proposal 1 of the RFC, allowing > traits to declare and implement interfaces: > https://github.com/php/php-src/pull/1773 > > Reviews and feedback welcome! > > I haven't yet started on an implementation for Proposal 2. > > Cheers > -- Kevin >
Re: [PHP-DEV] Re: [RFC] Traits with interfaces
-BEGIN PGP SIGNED MESSAGE- Hash: SHA256 First off: I like the idea of a trait being able to implement an interface and having PHP validating that because I am like Larry and prefer language construct over comments. On 2/18/2016 4:11 PM, Chase Peeler wrote: > > I agree, in theory, but I also think we introduce confusion. Every > other OO rule says you get "everything*" from what you are using > (extending a subclass gets you all the parent classes, implementing > an interface that extends an interface gets you the parent > interface, using a trait that uses a trait gets you both traits, > etc). [...] > I disagree on this. Traits are already special and adding interface support to them that are not automatically inherited does not yield confusion from my point of view. Most people will have a hard time understanding them in the first place. Again, traits are "reusable dead code" that don't do anything on their own. Hence, if they suddenly start doing anything other it gets weird. The class has to decide and only the class and it must be opt-in and not opt-out because this becomes a conscious decision rather than: "Dafuq, why is object A going through the method with the type hint against interface B although it does not implement it? Oh, a trait... Well I guess I need to **unimplement** the interface then." This is crying out loud for unintended bugs in software. - -- Richard "Fleshgrinder" Fussenegger -BEGIN PGP SIGNATURE- Version: GnuPG v2 iQIcBAEBCAAGBQJWxguAAAoJEOKkKcqFPVVr17QP/2iYhhv3dndfURkA/RW0lSTr CTN6gkIxDSEoGOzxk0HXAL6D9jgXOqhfsavWFLd0bdS12+2tfbi4+tz1VSGhBGoD fIYyvOh6gx7nnI4p8v7PTegaWPb2xuKf6D7+ogpFHH0PSi27gTV1Rgh6m/kdnH7+ wMKKybl7k1e85LEGNTs0PpXYRKNBKMK6EuoiQjbT3gPMle3ZQZYEDttOVHSKUmoO heu0IHEkunzE7MtTMujqj6xgR2X3ce2SfXVsxLR3J0pBh7nFyfcm21tDz7a5gLE6 3qisBhjVBjAU9tAO1mbLJWzHGcyDLCBSncFJfpVgbi5I2OYyrsMCIy8fvMxAW6C3 zeP1kSVz2VHPQpG6vpwapSIPLB2bkGKxd8o2c9QM+RaF4c6gwNi6PWPYI2t/w8TH iAq0jvQFdpRBAGpUyRpYrQ2/0clYLkl2qC/PRtA7SB19/Vsq3rROWqN0uKFtTb4K iNHE7+9CQV8n/p0/DUm99wW42IGM+5bXGNcY7a+DWhC+eJsF7a8BohvUWay5sL4h KZZ4VT8Khp5vbP3gpz7z8ugNMuFcIHkvJnUYR4QD9J1Ml5VpGH1pCw1uqKCN0qFX pzmo84og2xVr+r1OJ5DjSbXQE6WDSMvuhmpayZWOfxPa7a80KqYkl9pczQRAHz6X DvoLGPdq7s2rpknUYS84 =9OHz -END PGP SIGNATURE- -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Re: [RFC] Traits with interfaces
Hi Chase and Larry, On Thu, Feb 18, 2016 at 10:11 AM, Chase Peelerwrote: > On Thu, Feb 18, 2016 at 5:35 AM Larry Garfield > wrote: > I'd rather the class > > still need to self-declare the interface; that it uses a trait to > > fulfill that contract is irrelevant to the outside world. > > > I agree, in theory, but I also think we introduce confusion. Every other OO > rule says you get "everything*" from what you are using (extending a > subclass gets you all the parent classes, implementing an interface that > extends an interface gets you the parent interface, using a trait that uses > a trait gets you both traits, etc). Perhaps we need a different keyword? > I'm wary of a new keyword, particularly because this situation isn't really that different from what "implements" means. I think if we wanted to go down the route of new syntax, I'd want to expand the `use` statement for traits to include or exclude any interfaces that a trait provides. But I don't think a syntax change is worth it for this feature, for the cognitive and language overhead. > [snip] > > At that point, the benefit becomes two-fold: > > > > 1) Communicate to users of the trait what the intent of the trait is: To > > provide the boilerplate for some interface, or portion thereof. This > > could be covered by PHPDoc, potentially, and I've suggested the same for > > PSR-5 before. > > > > Agreed > > > 2) Ask the engine to do a syntax check on the class to make sure I did > > not forget something or screwed up in some way. That is, not fulfilling > > the interface on the trait would cause a parse error (or an error in my > > IDE), forcing me to fix my bug before I even try running it. PHPDoc > > would NOT have this benefit. > > > > Thus I feel this addition does have value that a PHPDoc alternative > > would not. > > > > Good point. I was of the opinion "we can just use comments to declare > intent," but hadn't really thought of using the engine in this way. It > makes sense. > That makes sense -- I like having the language enforce intent, rather than just comments (which always rot, in my experience). > > > > > --Larry Garfield > > > > -- > > PHP Internals - PHP Runtime Development Mailing List > > To unsubscribe, visit: http://www.php.net/unsub.php > > > > -- > -- Chase > chasepee...@gmail.com >
Re: [PHP-DEV] Re: [RFC] Traits with interfaces
On Thu, Feb 18, 2016 at 5:35 AM Larry Garfieldwrote: > On Wed, Feb 17, 2016, at 01:05 PM, Kevin Gessner wrote: > > On Wed, Feb 17, 2016 at 9:25 AM, Kevin Gessner > wrote: > > > > > Hello internals team! I'd like to propose an RFC to allow traits to > > > implement interfaces. > > > > > > > I've created a proper RFC wiki page here with the draft: > > https://wiki.php.net/rfc/traits-with-interfaces > > > > It includes more detail and several example code snippets. Thanks all > > for > > your feedback so far. > > Thanks, Kevin. > > At the risk of a "me too" post, I would also be in favor of allowing > traits to declare an interface but NOT in favor of a use-ing class > implicitly implementing the interface as a result. I'd rather the class > still need to self-declare the interface; that it uses a trait to > fulfill that contract is irrelevant to the outside world. > I agree, in theory, but I also think we introduce confusion. Every other OO rule says you get "everything*" from what you are using (extending a subclass gets you all the parent classes, implementing an interface that extends an interface gets you the parent interface, using a trait that uses a trait gets you both traits, etc). Perhaps we need a different keyword? trait foo providesfor myInterface { } I'm not sold on that keyword, it's just the first thing that came to mind. *I know you don't get private methods and properties in subclasses, but that's something dictated by the class itself. The class says "you can't have these if you extend me" instead of the engine saying "you aren't implementing that when you use the trait because it's a trait" At that point, the benefit becomes two-fold: > > 1) Communicate to users of the trait what the intent of the trait is: To > provide the boilerplate for some interface, or portion thereof. This > could be covered by PHPDoc, potentially, and I've suggested the same for > PSR-5 before. > > Agreed > 2) Ask the engine to do a syntax check on the class to make sure I did > not forget something or screwed up in some way. That is, not fulfilling > the interface on the trait would cause a parse error (or an error in my > IDE), forcing me to fix my bug before I even try running it. PHPDoc > would NOT have this benefit. > > Thus I feel this addition does have value that a PHPDoc alternative > would not. > > Good point. I was of the opinion "we can just use comments to declare intent," but hadn't really thought of using the engine in this way. It makes sense. > --Larry Garfield > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > > -- -- Chase chasepee...@gmail.com
Re: [PHP-DEV] Re: [RFC] Traits with interfaces
On Wed, Feb 17, 2016, at 01:05 PM, Kevin Gessner wrote: > On Wed, Feb 17, 2016 at 9:25 AM, Kevin Gessnerwrote: > > > Hello internals team! I'd like to propose an RFC to allow traits to > > implement interfaces. > > > > I've created a proper RFC wiki page here with the draft: > https://wiki.php.net/rfc/traits-with-interfaces > > It includes more detail and several example code snippets. Thanks all > for > your feedback so far. Thanks, Kevin. At the risk of a "me too" post, I would also be in favor of allowing traits to declare an interface but NOT in favor of a use-ing class implicitly implementing the interface as a result. I'd rather the class still need to self-declare the interface; that it uses a trait to fulfill that contract is irrelevant to the outside world. At that point, the benefit becomes two-fold: 1) Communicate to users of the trait what the intent of the trait is: To provide the boilerplate for some interface, or portion thereof. This could be covered by PHPDoc, potentially, and I've suggested the same for PSR-5 before. 2) Ask the engine to do a syntax check on the class to make sure I did not forget something or screwed up in some way. That is, not fulfilling the interface on the trait would cause a parse error (or an error in my IDE), forcing me to fix my bug before I even try running it. PHPDoc would NOT have this benefit. Thus I feel this addition does have value that a PHPDoc alternative would not. --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php