ramblings on PHP, SQL, the web, politics, ultimate frisbee and what else is on in my life
back

Horizontal Reuse aka Traits Reloaded

We have had a few RFC's pass through internals ever since the creation of the wiki, but embarrassingly enough the very first one is still up in the air: Traits. Actually Stefan has since tweaked the proposal and in the latest version it includes an alternative approach called Grafts along with the original Traits idea, which is essentially language level delegation pattern support. I am absolutely sure that we will either see Traits or Grafts in the next non patch release of PHP (aka 5.4 or 6.0). So I rather want to see this patch make it into trunk sooner than later (btw since my last post the old 6.0 has been moved to a branch, Jani's 5.4 branch has been deleted and trunk has been recreated from 5.3 using the version 5.3.99-dev). However for that we need as many people as possible to review the RFC and better yet try out the patch. Right now Grafts look like the better approach to me. So either leave your comments on this blog, which I will then take into account when providing additional feedback on the mailinglist, send a mail to Stefan or participate in the discussion in the internals mailinglist.

Comments



Re: Horizontal Reuse aka Triats Reloaded

You got a typo in the headline. Should read "traits" not "triats".

Re: Horizontal Reuse aka Triats Reloaded

Just from a quick once-over I think Grafts seem way more complicated than traits.

traits remind me a lot of what would happen if I did something like

class Foo {
include "foo_methods";
function blah() {}
}

Which is way simpler than the Grafts methodology which reminds me a lot of multiple inheritance.

Re: Horizontal Reuse aka Triats Reloaded

I can see use cases for _both_ traits and grafts. One thing unanswered in the RFC is whether classes using grafts would inherit from the grafted class for purposes of typehinting (e.g., if a class "Foo" is grafted into class "Bar", would "Bar" satisfy the typehint "Foo"?). My inclination is that it wouldn't as you can selectively choose which methods to accept, but I'd like to see a definitive answer.

Regardless -- I want them both *now*. :)

Re: Horizontal Reuse aka Traits Reloaded

I am pretty sure that you cannot detect usage of a Graft/Trait from the outside, nor would it make sense, since you do not know how the methods are named.

As such I expect even interfaces that were implemented by the Graft to not show up in the Graft using class unless they are explicitly defined there as well. Its just a way to import logic, this is clarified by the introduction where Stefan explains that this all is a method to get back to the original idea behind inheritance and that is to express an "is a" relationship.

Re: Horizontal Reuse aka Traits Reloaded

I can see use cases, but I think they are not worth it comparing to complexity these proposals add. Features like these move PHP more and more to object oriented world. And personally I don't see PHP as a great object oriented language. If you want one, just use Java, Ruby, Python or something more object oriented.

PHP mainly just needs a new good extensions. Extension for openid, nosql dbs, social networks, etc. Then we just glue these together with simple PHP constructs. No Traits/Grafts needed. If you want to use PHP more as a general purpose language than web gluing language, I think you are using a wrong language.

Re: Horizontal Reuse aka Traits Reloaded

I much prefer Traits, as Grafts seem confusing to me (haven't heard of the concept before, so that might be the reason).
After reading somewhat through the discussion, I still can't figure out what happens to class members in a grafted classes context. Do they need to be "imported", are they accessible from other grafts?

To me it seems that Traits create more complete objects, but I might be wrong.
I'd prefer semi-automatic resolution in case of duplicate methods, just like in other languages that use traits. Just based on the order the Traits are applied/listed.

Re: Horizontal Reuse aka Traits Reloaded

Hmm for me Grafts are much clearer. Essentially a Graft is just like delegation. As in the Graft object is totally encapsulated and you explicitly expose methods from the Graft. As a result properties of the Graft are not exposed at all to the outside.

The concept of Traits is also easily understood: its just language supported copy&paste. But it brings with it surprises during use, like what happens with overlapping properties? Answer: its the job of the trait user to prevent that, and there is no way to fix things if the overlap is in Traits you are using.

Re: Horizontal Reuse aka Traits Reloaded

I like the original traits concept as per your first link. It is clear, concise and understandable. I had to read the grafts one twice before I had a basic idea what it was trying to accomplish.

Re: Horizontal Reuse aka Traits Reloaded

I prefer the semantics of grafts over traits. I agree they are cleaner and avoid a number of surprises that appear to crop up with traits.

The name 'grafts' does seem uninviting though. I was predisposed to traits on the basis that they sound more familiar and easier to understand. In actuality, it turns out they are more complicated.

If grafts are truly just like delegation, should they be called delegates instead?