It seems to me, there's a couple of things related to traits that were missed in this implementation.
Take the following example: <?php header('Content-type: text/plain'); class Cart { public static $instance; # public function addItem(CartBehavior $item, $amount=1) // => script terminates public function addItem($item, $amount=1) { echo "Adding {$amount} {$item->getName()} to shopping cart - price = ".($amount * $item->getPrice())."\n\n"; } } Cart::$instance = new Cart; trait CartBehavior { public function addToCart($amount=1) { Cart::$instance->addItem($this, $amount); } } class Product { use CartBehavior; private $_name; private $_price; public function __construct($name, $price) { $this->_name = $name; $this->_price = $price; } public function getPrice() { return $this->_price; } public function getName() { return $this->_name; } } $test = new Product('Fish', 100); $test->addToCart(); var_dump($test instanceof CartBehavior); // => false var_dump((new ReflectionClass('Product'))->getTraits()); // CartBehavior is a ReflectionClass? The first problem is that type-hinting isn't supported... so you have this horizontal extensibility now - traits are kind of like interfaces with a built-in implementation. They're more like interfaces than classes, at least, in the sense that they can't have state, and you can't create an instance of a trait. So the first issue is, you can't use a trait as a type-hint - the addItem() method can't be type-hinted, so we can't define explicitly what to expect here. This is one of the most important reasons for having interfaces, perhaps the second-most important after the ability to enforce conformity on class implementations. Traits don't work in this case. And sure, you could add an interface too, and redeclare all your accessors again. But why? An abstract base-class with some abstract methods seems like a much stronger tool, except that you can't reuse that horizontally... Secondly, the instanceof operator doesn't complain when you test to see if an object carries a trait - if this isn't going to work, it should at least throw an exception. Although as pointed out, it seems natural to expect that this would work. Lastly, when you reflect on a trait, it comes back as an instance of ReflectionClass. As pointed out, traits are probably more similar to interfaces than they are to classes, and they definitely don't have properties, as are exposed by the ReflectionClass type. I would also point out that the examples in the documentation (which it seems were just copied from the RFC?) do not demonstrate any real purpose of this feature. Is this the most anybody has attempted to do with this feature? Trying to come up with a real example, I didn't get very far before running into these stumbling blocks. If this feature is useful in it's current form, I don't see how - and the examples in the documentation definitely do not demonstrate any real practical use for this. Here's another quick example demonstrating these problems: interface MyInterface { public function myMethod(); } trait MyTrait # implements MyInterface // fails (B) { public function myMethod() { echo "foo"; } } class MyClass implements MyInterface { use MyTrait; } $test = new MyClass; var_dump($test instanceof MyInterface); // true var_dump($test instanceof MyTrait); // false (A) If I can't use instanceof to check for a trait (A), then I would at least expect to be able to write a trait that implements an interface (B) - does that not seem reasonable or logical? Having to use both the interface and the trait as a pair, and having to explicitly apply them both to the class, feels like a work-around. I apologize if I'm somehow missing the big picture here, or maybe I set my expectations too high - but my first impression of this feature is that it's crippled and somewhat half-baked... If there was a deliberate and logical reason for not supporting these features, I would like to understand why. If not - great work so far, but perhaps this feature is not quite mature enough for release just yet? - Rasmus