Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks

2010-12-10 Thread Nathan Nobbe
On Thu, Dec 9, 2010 at 4:04 PM, Stefan Marr p...@stefan-marr.de wrote:

 Hi Nathan:


 On 09 Dec 2010, at 23:42, Nathan Nobbe wrote:
  What I'm getting at is the scenario when a trait is designed to be used
 in
  concert with the class in which it is being used.  In this case the trait
  expects certain functions to be available on the class in which it is
 used
  with.  If the methods aren't there (or checked for at runtime) a fatal
 error
  is raised.
 
  A quick example
  ?php
  class A {
   use AHelper;
 
   function blah() {}
  }
 
  trait AHelper {
   function meh() {
 // hoping we get used w/ instances of A ...
 return $this-blah() * 5;
   }
  }
 
  class B {
   use AHelper;
 
   /// waiting for a runtime error if blah() is ever called ..
  }
  ?
 
  Do you see what I mean?
 No, do not really see what you are getting at.

 How is your approach using the instanceof checks (from the first mail)
 different from changing AHelper to require blah() by stating this
 requirement using an abstract method definition?
 For the trait it is not important where that method is implemented, it just
 has to be in the final composed class.

 So, why don't you want the following trait?

 trait AHelper {
  abstract function blah();

  function meh() {
   // hoping we get used w/ instances of A ...
   return $this-blah() * 5;
  }

 }


Ahh, I see how the abstract methods are working in traits now, I didn't
catch that from your first post; thanks for showing that to me.


 You want to avoid the fatal error during runtime, right?


Yes, exactly, and the runtime check for expected interface / class / method.


 Do you prefer dynamic checks over compile time checks?


Def not :D, however, I still think this paradigm is lacking.  Don't you
think it makes more sense if I write a trait that expects a given interface
or class to be able to specify said interface/class in it's entirety with
just a single identifier rather than listing out all the methods?

For example, I think this would be ugly
?php
trait IteratorHelper{
abstract public current();
abstract public key();
abstract public next();
abstract public rewind();
abstract public valid();
}
?

essentially you're redeclaring the entire interface in the trait, the same
would be true of the public interface of an expected class.  i think it
would be much more elegant to allow a specification on the trait declaration
itself, something like

?php
trait IteratorHelper expects Iterator {
...
}
?

-nathan


Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks

2010-12-10 Thread Stefan Marr
Hi Nathan:

On 10 Dec 2010, at 17:49, Nathan Nobbe wrote:
 Def not :D, however, I still think this paradigm is lacking.  Don't you think 
 it makes more sense if I write a trait that expects a given interface or 
 class to be able to specify said interface/class in it's entirety with just a 
 single identifier rather than listing out all the methods?
 
 For example, I think this would be ugly
 ?php
 trait IteratorHelper{
 abstract public current();
 abstract public key();
 abstract public next();
 abstract public rewind();
 abstract public valid();
 }
 ?
 
 essentially you're redeclaring the entire interface in the trait, the same 
 would be true of the public interface of an expected class.  i think it would 
 be much more elegant to allow a specification on the trait declaration 
 itself, something like
 
 ?php
 trait IteratorHelper expects Iterator {
 ...
 }
 ?
:D That was exactly my thought when I was writing my first answer.
My second thought was, damn, not another keyword...

But since you also seem to see the need, we should give it a thought.

Anyone else with an opinion on that?

Best regards
Stefan


-- 
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax:   +32 2 629 3525


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



Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks

2010-12-10 Thread Martin Wernstahl
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?
Or does that seem illogical when the trait does not implement all of the
methods specified by the interface?

(Because I think expects might be a common name in APIs for some kind of
validation.)

Best Regards
Martin Wernstahl

On Fri, Dec 10, 2010 at 18:09, Stefan Marr p...@stefan-marr.de wrote:

 Hi Nathan:

 On 10 Dec 2010, at 17:49, Nathan Nobbe wrote:
  Def not :D, however, I still think this paradigm is lacking.  Don't you
 think it makes more sense if I write a trait that expects a given interface
 or class to be able to specify said interface/class in it's entirety with
 just a single identifier rather than listing out all the methods?
 
  For example, I think this would be ugly
  ?php
  trait IteratorHelper{
  abstract public current();
  abstract public key();
  abstract public next();
  abstract public rewind();
  abstract public valid();
  }
  ?
 
  essentially you're redeclaring the entire interface in the trait, the
 same would be true of the public interface of an expected class.  i think it
 would be much more elegant to allow a specification on the trait declaration
 itself, something like
 
  ?php
  trait IteratorHelper expects Iterator {
  ...
  }
  ?
 :D That was exactly my thought when I was writing my first answer.
 My second thought was, damn, not another keyword...

 But since you also seem to see the need, we should give it a thought.

 Anyone else with an opinion on that?

 Best regards
 Stefan


 --
 Stefan Marr
 Software Languages Lab
 Vrije Universiteit Brussel
 Pleinlaan 2 / B-1050 Brussels / Belgium
 http://soft.vub.ac.be/~smarr
 Phone: +32 2 629 2974
 Fax:   +32 2 629 3525


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




Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks

2010-12-10 Thread Stefan Marr
Hello Martin:

On 10 Dec 2010, at 18:15, Martin Wernstahl 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?
 Or does that seem illogical when the trait does not implement all of the
 methods specified by the interface?
Implements sounds misleading to me.  Read: trait Foo implements Bar. Sounds 
like Foo is providing Bar and not expecting the interface to be there.

But require might be a good keyword to be reused.

Best Regards
Stefan

-- 
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax:   +32 2 629 3525


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



Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks

2010-12-10 Thread Nathan Nobbe
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


Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks

2010-12-10 Thread Martin Wernstahl
Oh, sorry, should have read the RFC thoroughly before sending an email.

But yeah, require might be a good choice, provided it doesn't collide with
the specific require logic in the scanner/parser (I don't have much
knowledge on that subject, but I've peeked a few times on it as it is
interesting).

Best Regards
Martin Wernstahl

On Fri, Dec 10, 2010 at 18:29, Nathan Nobbe quickshif...@gmail.com wrote:

 On Fri, Dec 10, 2010 at 10:15 AM, Martin Wernstahl m4r...@gmail.comwrote:

 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



Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks

2010-12-10 Thread Chad Fulton
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.

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



Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks

2010-12-10 Thread Nathan Nobbe
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


Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks

2010-12-10 Thread Chad Fulton
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.

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?).

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).

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?

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



Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks

2010-12-10 Thread Matthew Weier O'Phinney
On 2010-12-10, Nathan Nobbe quickshif...@gmail.com wrote:
 --0016e6dbe7fb8861a1049712ad63
 Content-Type: text/plain; charset=UTF-8

 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.

To me, putting this into the language feels like overkill.

Unless you're using an opcode cache, the notion of compile time as a
differentiation from runtime in PHP has little relevance -- you still
only find out when the script executes.

There's already a way to mitigate this as well: write a testing suite
for your application, and exercise it often. If you write your tests
well (targeting the discrete behaviors of your application), then most
likely they'll catch such errors -- allowing you to fix them before you
deploy.

-- 
Matthew Weier O'Phinney
Project Lead| matt...@zend.com
Zend Framework  | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

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



Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks

2010-12-10 Thread Nathan Nobbe
On Fri, Dec 10, 2010 at 12:55 PM, Matthew Weier O'Phinney 
weierophin...@php.net wrote:

 On 2010-12-10, Nathan Nobbe quickshif...@gmail.com wrote:
  --0016e6dbe7fb8861a1049712ad63
  Content-Type: text/plain; charset=UTF-8
 
  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.

 To me, putting this into the language feels like overkill.

 Unless you're using an opcode cache, the notion of compile time as a
 differentiation from runtime in PHP has little relevance -- you still
 only find out when the script executes.


*Only* if you hit the line of code at runtime that would destroy your
script; often times this doesn't happen until it's too late, and the code
has made it to production.  And there is a notion of compile time in PHP,
I'm not sure what it's referred to by the internals group, but abstract
methods and interfaces definitely constitue compile time checks to me.


 There's already a way to mitigate this as well: write a testing suite
 for your application, and exercise it often. If you write your tests
 well (targeting the discrete behaviors of your application), then most
 likely they'll catch such errors -- allowing you to fix them before you
 deploy.


Right, so you have to do tons of extra work (writing unit tests) which have
to actually test every potential line of failure, when this could just
simply be caught up front w/o any second guessing whether or not you've
covered all cases in your tests.  I'm not against unit tests at all, just
saying it's much easier to guarantee you're safely using a trait w/ a
compile time check rather than deferring the application author to test
suite development.

-nathan


Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks

2010-12-10 Thread Nathan Nobbe
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 

Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks

2010-12-10 Thread Matthew Weier O'Phinney
On 2010-12-10, Nathan Nobbe quickshif...@gmail.com wrote:
 --0016e6d7e101e083a4049714bad3
 Content-Type: text/plain; charset=UTF-8

 On Fri, Dec 10, 2010 at 12:55 PM, Matthew Weier O'Phinney 
 weierophin...@php.net wrote:

 On 2010-12-10, Nathan Nobbe quickshif...@gmail.com wrote:
  --0016e6dbe7fb8861a1049712ad63
  Content-Type: text/plain; charset=UTF-8
 
  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.

 To me, putting this into the language feels like overkill.

 Unless you're using an opcode cache, the notion of compile time as a
 differentiation from runtime in PHP has little relevance -- you still
 only find out when the script executes.


 *Only* if you hit the line of code at runtime that would destroy your
 script; often times this doesn't happen until it's too late, and the code
 has made it to production.  

That's what good testing is about -- exercising all the expected
behaviors of your code. If you hit an unexpected behavior in production,
you add a test to your suite that reproduces it, fix it, and re-deploy.

 And there is a notion of compile time in PHP, I'm not sure what it's
 referred to by the internals group, but abstract methods and
 interfaces definitely constitue compile time checks to me.

 There's already a way to mitigate this as well: write a testing suite
 for your application, and exercise it often. If you write your tests
 well (targeting the discrete behaviors of your application), then most
 likely they'll catch such errors -- allowing you to fix them before you
 deploy.

 Right, so you have to do tons of extra work (writing unit tests) which have
 to actually test every potential line of failure, when this could just
 simply be caught up front w/o any second guessing whether or not you've
 covered all cases in your tests.  

Writing tests should not be considered tons of extra work; it should
be considered a basic part of development. How can you prove your code
does what it should without them? How can you insulate your code from
future changes? As long as you consider it extra work, I don't care
what the compiler offers you -- you're going to shoot yourself in the
foot some day.

 I'm not against unit tests at all, just saying it's much easier to
 guarantee you're safely using a trait w/ a compile time check rather
 than deferring the application author to test suite development.

Again, are the benefits worth it, if you're writing code where an
unexpected runtime exception could still occur because you didn't test
properly in the first place?

-- 
Matthew Weier O'Phinney
Project Lead| matt...@zend.com
Zend Framework  | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

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



Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks

2010-12-10 Thread Chad Fulton
On Fri, Dec 10, 2010 at 1:00 PM, Nathan Nobbe quickshif...@gmail.com wrote:

 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


I think that you make a convincing argument. Thinking more about your
Iterator example, this idea makes a lot of sense and could be quite
useful.

Also, I was wrong about requiring a class. It could be very useful,
especially if it is an internal class (e.g. ArrayObject) which might
have many children, and of course in this case the parent can't be
changed.

I think the require keyword works well.

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



Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks

2010-12-10 Thread Nathan Nobbe
On Fri, Dec 10, 2010 at 2:42 PM, Matthew Weier O'Phinney 
weierophin...@php.net wrote:

 On 2010-12-10, Nathan Nobbe quickshif...@gmail.com wrote:
  --0016e6d7e101e083a4049714bad3
  Content-Type: text/plain; charset=UTF-8
 
  On Fri, Dec 10, 2010 at 12:55 PM, Matthew Weier O'Phinney 
  weierophin...@php.net wrote:
 
  On 2010-12-10, Nathan Nobbe quickshif...@gmail.com wrote:
   --0016e6dbe7fb8861a1049712ad63
   Content-Type: text/plain; charset=UTF-8
  
   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.
 
  To me, putting this into the language feels like overkill.
 
  Unless you're using an opcode cache, the notion of compile time as a
  differentiation from runtime in PHP has little relevance -- you still
  only find out when the script executes.
 
 
  *Only* if you hit the line of code at runtime that would destroy your
  script; often times this doesn't happen until it's too late, and the code
  has made it to production.

 That's what good testing is about -- exercising all the expected
 behaviors of your code. If you hit an unexpected behavior in production,
 you add a test to your suite that reproduces it, fix it, and re-deploy.


Right, and implementing an interface or subclassing an abstract class does
not require a unit test in order to determine if I've at least met the
obligations set forth by the interface or abstract class.  The basic idea of
a unit test is to write meaningful tests that actually offer you some milage
for your time.  I mean sure, I could write tests for setters and getters,
but that's pretty much a waste of time compared to writing tests that
actually get into semantics the class aims to provide.


  And there is a notion of compile time in PHP, I'm not sure what it's
  referred to by the internals group, but abstract methods and
  interfaces definitely constitue compile time checks to me.
 
  There's already a way to mitigate this as well: write a testing suite
  for your application, and exercise it often. If you write your tests
  well (targeting the discrete behaviors of your application), then most
  likely they'll catch such errors -- allowing you to fix them before you
  deploy.
 
  Right, so you have to do tons of extra work (writing unit tests) which
 have
  to actually test every potential line of failure, when this could just
  simply be caught up front w/o any second guessing whether or not you've
  covered all cases in your tests.

 Writing tests should not be considered tons of extra work; it should
 be considered a basic part of development.


Shrug, taken out of context.  I'm sure you can see how writing an extra word
in the trait definition is much less work than including a unit test suite
in your project and then a test against each class that uses the trait..,
IMO, *that* is a ton of extra work.  Even in the context of unit test
writing a compile time check would eliminate the need of writing what I
would consider bolier plate unit tests for traits.  It's like, well I just
wrote a trait, now any class I write against it I should go ahead and test
that it provides all the methods for said trait .. that's just a waste of
time.