Hello list, 
I want to bring up a topic that has bothered me whenever I use traits. 
I don't have a solution proposal for it, yet, unfortunately. 
I was going to comment in the other thread about traits, but it seems 
better suited for a new discussion.
Traits allow to share code between classes of different inheritance chains. 
They can be used instead of composition, or they can be used to help 
with composition - e.g. a trait can expose functionality from a 
specific injected dependency.
When using base classes, we can follow a convention to always call the 
parent constructor. 
We can even make the properties in the base class private, to fully 
encapsulate them.
But: 
When using properties in traits, how can I make sure that they are 
properly initialized in the class constructor?
Also, what if I want to provide an init method with specific logic to 
set that property? How can I make sure that method will be called in 
the constructor?
I found that Psalm can detect "PropertyNotSetInConstructor", which is 
also applied to properties from traits. 
But this is not as straightforward as calling a parent constructor.
Can and should we provide a language-level solution for this? 
Or should this be left to static analysis tools and IDEs?
Cheers, 
Andreas
Hello list,
I want to bring up a topic that has bothered me whenever I use traits.
I don't have a solution proposal for it, yet, unfortunately.
I was going to comment in the other thread about traits, but it seems
better suited for a new discussion.
Traits allow to share code between classes of different inheritance chains.
They can be used instead of composition, or they can be used to help
with composition - e.g. a trait can expose functionality from a
specific injected dependency.
When using base classes, we can follow a convention to always call the
parent constructor.
We can even make the properties in the base class private, to fully
encapsulate them.But:
When using properties in traits, how can I make sure that they are
properly initialized in the class constructor?
I think I have a solution: 
abstract properties in traits!
The idea would be:
- traits can have abstract properties that are private, protected or public.
 - non-abstract classes cannot have abstract properties.
 - class properties override trait properties, with some compatibility 
requirements. - non-abstract protected or public class properties from the parent 
class also override trait properties. - (optional) abstract classes can have abstract properties that are 
protected or public. - (optional) abstract class properties from a parent class are 
overridden by the trait property, but with compatibility checks. 
This implies that abstract trait properties must be redeclared in 
the class that uses the trait,
interface X {}
interface XHaving { 
public function getX(): X; 
}
trait T { 
abstract private X $x; 
public function getX(): X {return $this->x;} 
}
class C implements XHaving { 
use T; 
public function __construct( 
private X $x, 
) {} 
}
class D implements XHaving { 
use T;  // Error, must redeclare abstract property T::$x. 
}
The benefit: 
Properties are initialized in the same file where they are declared.
I don't know if we need aliasing for properties, perhaps we should 
first go without that.
I did find a discussion about abstract properties in externals.io, but 
this was for interfaces and classes, not for traits. 
https://externals.io/message/64126#66682
Also, what if I want to provide an init method with specific logic to
set that property? How can I make sure that method will be called in
the constructor?
This part would not be solved by the abstract properties. 
But I think that's ok.
I found that Psalm can detect "PropertyNotSetInConstructor", which is
also applied to properties from traits.
But this is not as straightforward as calling a parent constructor.Can and should we provide a language-level solution for this?
Or should this be left to static analysis tools and IDEs?Cheers,
Andreas