Am 25.02.2008 um 20:33 schrieb Stefan Marr:

Hi,

there is a lot of discussion going on about how traits should actually
work in PHP.

Currently, one of the main challenges seams to be to agree on a suitable
mechanism to avoid breaking traits and there behavior.
Eventually, there seams to be a large discomfiture on the excluding of methods and the interweaving of methods from different traits.

I can agree on the opinion, that a unconditional exclude mechanism could accidentally break traits. But, I really do like the notion to be able to interweave traits and compose something new from it, which results in an overlapping construct using the appropriate methods for a concrete problem. Well, this implies traits are not units of black-boxed reuse. They do act really fine-grained and will require the knowledge about the used methods.

Yes. This is how I understood them. I really don't think we need all this complicated stuff for potential what-if situations that arise from people not understanding how to use Traits. You are completely right that Traits should not be regarded as black boxes.

I think I said it in an earlier mail - this entire discussion about conflict resolving with aliasing etc is pretty void because it's always assumed that Traits change, or developers using them don't (want to?) know the inner workings. Traits are mixed into classes statically, using an explicit syntactical facility. That means we can assume the developer in question knows what he is doing. That also means we can expect him to check for potential conflicts/breakage and resolve it up front, as you're suggesting further down in your mail.


Therefore, remove/exclude is bad, we need to get rid of it.
There are some thoughts about aliasing. It seams to be not the natural/closest solution. Renaming semantics would be more natural, but it implies an exclude of the old method, too. Thus, renaming could accidentally breaking a trait. Eventually, renaming needs to be avoided, too.

Ok, lets get a step back and recall what traits have to achieve.

Traits try to be a construct to allow the reuse of a group of semantical related methods. They do not try to replace inheritance or the delegation patter. They are still valid means to reuse "complex behavior and state" things.
Instead, the way to go with traits should be to reuse a small,
predominantly independent (but semantically related) number of methods not justifying to build a full fledged class from them. Use traits to build a class from them, which adds some additional semantics/behavior to the set of methods got from the traits and build a complete blue print for objects from it.

The main thing here seams to be that the current proposal does not fulfill the claim to combine the traits properly in the case of conflicts. Instead, there is a lot of potential to break the traits behavior.

Let's try to find a notation where the traits are combined and conflicts are solved upfront, before being applied to the class. (This is even the way the implementation works right now.)

Winner. +1.


To get rid of exclude and rename I would like to propose the following:

//Example from the RFC with the cross-over conflict to be solved
trait A {
 public function smallTalk() {
   echo 'a';
 }
 public function bigTalk() {
   echo 'A';
 }
}

trait B {
 public function smallTalk() {
   echo 'b';
 }
 public function bigTalk() {
   echo 'B';
 }
}

//here the new notion of combing traits and resolving conflicts upfront
class Talker {
 use A, B {
    B::smallTalk instead A::smallTalk;
    A::bigTalk instead B::bigTalk;
    A::bigTalk as talk;
  }
}


The new ``use`` is defined as use with a list of traits to be included into the class. Since the exclude is not appropriated, conflicts could be solved a lot more explicitly with the new ``instead`` keyword. It has be read as: use B::smallTalk instead of A::smallTalk, which solves the conflict explicitly and avoids the need for an exclude operator with the power to exclude arbitrary methods. If more traits are combined it could look like ``A:foo instead B::foo, C::foo;``

How about "B::smallTalk supersedes/replaces A::smallTalk" ?


David

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

Reply via email to