On Fri, Dec 10, 2010 at 12:39 PM, Chad Fulton <chadful...@gmail.com> wrote:
> On Fri, Dec 10, 2010 at 10:39 AM, Nathan Nobbe <quickshif...@gmail.com> > wrote: > > On Fri, Dec 10, 2010 at 11:04 AM, Chad Fulton <chadful...@gmail.com> > wrote: > >> > >> On Fri, Dec 10, 2010 at 9:29 AM, Nathan Nobbe <quickshif...@gmail.com> > >> wrote: > >> > On Fri, Dec 10, 2010 at 10:15 AM, Martin Wernstahl <m4r...@gmail.com> > >> > wrote: > >> > > >> >> First i have to say that I am not a PHP internals developer, but as a > >> >> user > >> >> I think it would maybe be better to just let the trait use the > >> >> implements > >> >> keyword, and "copy" that to the classes utilizing the trait? > >> >> > >> > > >> > This is actually in the RFC as a rejected proposal > >> > > >> > http://wiki.php.net/rfc/traits#rejected_features > >> > > >> > But what I'm talking about is something different. We're not trying > to > >> > say > >> > 'these are the methods implemented in the trait', rather, 'this trait > >> > expects a class it is used with to be of a certain type or implement a > >> > certain interface' for the trait to do its job. > >> > > >> > -nathan > >> > > >> > >> Shouldn't the burden be on the programmer to make sure the trait works > >> with the class using it rather than on the compiler? If they try to > >> use a trait that requires methods that don't exist, it will error out > >> anyway, so it won't be difficult to debug. > > > > Well I know PHP is a dynamic language but what about all the compile time > > features that have come along over the years. The abstract keyword for > > example vs. the PHP4 way of implementing an 'abstract' method which was > > triggering an error in the default implementation in a base class. > > One of the main things a lot of PHP programmers I've worked with hate is > > waiting for code to hit production and encountering a runtime error w/ > > something that could have been caught at compile time. I know the notion > of > > compile time in a scripting language like PHP is much less removed from > that > > of C++, Java etc, however there is a notion of it there, obviously. > > Also, I would suggest this feature be optional, so there is no need to > use > > it if you don't like it. But for those of us who would like to defer as > > much type checking to the compiler as possible so we don't need runtime > > checks all over our code or prayers that we've tested every line before > > production, it would certainly be nice. > > Lastly, you may know that traits will allow PHP programmers to move away > > from the delegate pattern which is a common workaround to multiple > > inheritance at this point. However, in speaking with a colleague over > the > > concept I'm proposing yesterday we discovered the delegate model actually > > does allow you to specify which class/interface the delegate is used w/, > it > > would be sad not to see comparable support in the trait feature which > will > > mostly eliminate the need for the delegate pattern, see my quick example. > > <?php > > class MainClass { > > private $_oDelegate = null; > > function addDelegate() { > > $this->_oDelegate = new Delegate($this); > > } > > } > > class Delegate { > > private function $_oMain = null; > > /// delegate gets to say what it can be used with via type hinting > > function __construct(MainClass $oMainClass) > > { > > $this->_oMain = $oMainClass; > > } > > } > > ?> > > Imagine how much cleaner this could be w/ traits, yet just as expressive > > <?php > > class MainClass { > > use Delegate; > > } > > trait Delegate require MainClass { > > ... > > } > > ?> > > -nathan > > > > As a note, I'm not strongly opposed to this proposal, since I don't > think it would do any harm. It just seems to me like a "kitchen sink" > feature. > > The issue for me is that traits, as I understand them, are there > primarily for horizontal code re-use via compile-time "copy/paste". > With that in mind, I feel like the developer is responsible for making > sure the methods they copy into their classes make sense, just as they > would have to do if they physically copied and pasted them. > Copy & paste itself leads to duplicated unmaintainable code, so traits are introduced (among other reasons) to prohibit this practice. Why not take it a step further and let a trait definition be as expressive as possible, eliminating ambiguity, right out of the gate? > I think your example above isn't quite what you meant to show, since > you're requiring a specific class and not an interface (since PHP only > allows one class definition for a class name, you're not gaining > anything via traits, since the trait could only be used for that > specific class, in which case why not just have the code in the class > in the first place?). > In retrospect Chad, that's a good point, and perhaps there is no reason to allow marking of classes as required by traits. > If we take your example in a more general case using interfaces, I > still can't see what the benefit is. All it does is provide a more > explicit and immediate error message for developers (e.g. instead of > "method not found" error when the bad method call is made at runtime, > you get a "classes using trait <trait> must implement <interface>" at > compile time). > Exactly, catch it at compile time rather than runtime, that's all it is really, just like the benefit of discovering a given subclass doesn't implement a given abstract method so that I don't go any further and run code guaranteed not to work. > Again, I'm not against it, but maybe be too much hand holding, since > the developer should make sure using the trait makes sense first? > Couldn't the same be said for a developer extending an abstract class, or implementing an interface? And also, a developer is to look through the entire definition of a trait to know which methods it's going to depend on? I know abstract is there as Stefan showed, but as we've both observed that approach can get messy quickly. -nathan