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

Reply via email to