Re: [PHP-DEV] Re: [RFC] Traits with interfaces

2016-03-06 Thread Rowan Collins

On 05/03/2016 23:15, Davey Shafik wrote:
You are mid-reading, none of the classes in my examples extend the 
others, they are all just using the same trait in different ways.


- Class a: use the trait with no aliases. Result: as expected
- Class b: use the trait with a simple alias, no visibility change. 
Result: both methods



Right, the reason I was looking at inheritance was this line:


... and_will_  override inherited methods of the same name.



I misunderstood that the rest of the examples were also about how inheritance 
behaved.


For the one you can't re-produce, it's class 'c', which is stand-alone
here: https://3v4l.org/K9o6Y



Right, so this is actually consistent, because the resulting "stitched 
together" class looks like this:


class C {
public function bar() {}
private function bat() {}
}

Whereas when the alias wasn't private, it looked liked this:

class B {
public function bar() {}
public function bat() {}
}


You can actually change its visibility on one line and alias it on another:

class e {
use foo {
bar as private;
bar as bat;
}
}

https://3v4l.org/80gKF Stitched togorther, that gives you:

class e {
private function bar() {}
public function bat() {}
}


So the main confusion is that "bar as private bat" != "bar as private" + 
"bar as bat". :)


Regards,

--
Rowan Collins
[IMSoP]


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



Re: [PHP-DEV] Re: [RFC] Traits with interfaces

2016-03-05 Thread Stephen Coakley

On 03/04/2016 01:17 AM, Davey Shafik wrote:

On Thu, Mar 3, 2016 at 2:19 PM, Stephen Coakley 
wrote:


On Wed, 17 Feb 2016 09:25:50 -0500, Kevin Gessner wrote:


Hello internals team!  I'd like to propose an RFC to allow traits to
implement interfaces.

I've noticed s pattern in Etsy's code and elsewhere, where a trait
provides a common implementation of an interface.  Classes that use the
trait are required to also explicitly declare the interface to benefit.
I propose that traits be permitted to declare and implement interfaces.
Classes that use such a trait would then implement the interface, as
though it were declared on the class, without declaring the interface
explicitly.

I believe this small change would be a useful improvement to the OO
system.  I've written a draft RFC, but I don't have karma to create the
wiki page for it.  Could someone please grant wiki karma to my account,
kevingessner?

I don't yet have an implementation, but I'll be starting on one once
I've posted the RFC.  I look forward to your thoughts and feedback.

Thanks in advance -- Kevin

Kevin Gessner Staff Software Engineer etsy.com


tl;dr: +1 and I really think that this language addition is useful and
makes sense.

Wow, I really want this feature. Reminds me of how powerful traits are in
some other languages, such as Rust. It is very common to use traits to
provide a common interface for something, but with some default
implementations.

Logging is a great example. Your interface might look like this (a
familiar one, eh?):

interface Logger
{
 public function log($level, $message, array $context = array());
 public function error($message, array $context = array());
 public function warning($message, array $context = array());
 // etc...
}

where the idea is that the `error()` and such methods are a convenience
for calling `log()` with a specific logging level. Obviously, these
methods will be implemented in the same fashion most of the time; a trait
would be great:

trait LoggerTrait implements Logger
{
 abstract public function log($level, $message, array $context = array
());
 public function error($message, array $context = array()) {
 return $this->log(ERROR, $message, $context);
 }
 // etc...
}

With this approach, I totally agree that allowing the `LoggerTrait` to
implement the interface makes sense; it allows implementation to be
enforced at the trait level. The second proposal that infers the interface
implementation when using the trait is nice too (though not completely
mandatory). It is pretty much the same situation where you do not have to
re-implement an interface when extending a base class that already
implements it.

--
Stephen



The aliases issue is a little more nuanced and potentially confusing,
regardless of this interface thing:

As you can see here: https://3v4l.org/L23LJ

1. If you simply alias (use foo { bar as bat; }) then you end up with an
*additional* method with the new name, the trait method as defined is still
brought in, and _will_ override inherited methods of the same name.

2. if you try to just change the visibility, you get a fatal error (Fatal
error: Trait method bar has not been applied, because there are collisions
with other trait methods), you must create an aliased name with the new
visibility

3. Doing this (visibility + name) _only_ gives you the new method, which is
_different_ behavior to #1

If the third behaved the same as the first, then this would be a non-issue.
Unfortunately, changing this behavior would be a — particularly hard to
diagnose — BC break and therefore cannot happen IMO.

Perhaps we could look at an alternative such as:

- traits can implement interfaces, which would ensure the _trait_ adheres
to it, but _not_ automatically classes use'ing it.
- Add a new syntax: "use Trait with Interface" or "use Trait implements
Interface" or "use Trait { implements Interface; }" which *explicitly*
calls out this usage

Just some off-the-top of my head thinking as an alternative.

- Davey



I freely admit; the method aliasing does pose an interesting issue, and 
may be good enough reason to simply allow enforcing interfaces at the 
trait level and simply force users of the trait to explicitly implement 
the interface themselves. That way it is easy to check compliance -- 
aliasing a method part of the interface on the trait to a different name 
simply breaks the contract.


--
Stephen

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



Re: [PHP-DEV] Re: [RFC] Traits with interfaces

2016-03-05 Thread Jesse Schalken
Your class 'c' example (last link) only shows method 'bar' (the trait
method) and not 'bat' (the aliased metod). The class has both, but 'bat' is
hidden from get_class_methods() because it is private.
On 6 Mar 2016 10:16 am, "Davey Shafik"  wrote:

> On Fri, Mar 4, 2016 at 2:06 AM, Rowan Collins 
> wrote:
>
> > Davey Shafik wrote on 04/03/2016 07:17:
> >
> >> 1. If you simply alias (use foo { bar as bat; }) then you end up with an
> >> *additional*  method with the new name, the trait method as defined is
> >> still
> >> brought in, and_will_  override inherited methods of the same name.
> >>
> >
> > Here's a clearer example of this: https://3v4l.org/RKHPt
> >
> > Unfortunately, you can't even use "insteadof" to directly bring the
> parent
> > method back in [https://3v4l.org/qOS5T], but you can stub it out with a
> > direct call to parent:: [https://3v4l.org/s9i4N].
> >
> > 3. Doing this (visibility + name)_only_  gives you the new method, which
> is
> >> _different_  behavior to #1
> >>
> >
> > I can't reproduce this: if I say "bar as private bat", the trait's bar
> > still shows up, and is public, just as in the previous example:
> > https://3v4l.org/1jH6o
> >
> > Your examples are rather confusing because they are effectively applying
> > the same trait twice, at different levels of the hierarchy; I'm not sure
> > this is a particularly likely scenario, or relevant to how interfaces
> > should behave.
> >
> > Regards,
>
>
> Rowan,
>
> You are mid-reading, none of the classes in my examples extend the others,
> they are all just using the same trait in different ways.
>
> - Class a: use the trait with no aliases. Result: as expected
> - Class b: use the trait with a simple alias, no visibility change. Result:
> both methods
> - Class c: use the trait with and alias both name, and change visibility.
> Result: ONLY the aliased method
> - Class d: use the trait and "alias" to the same name, ONLY changing
> visibility. Result: causes a Fatal error, clashing with itself o.O
>
> For the one you can't re-produce, it's class 'c', which is stand-alone
> here: https://3v4l.org/K9o6Y
>
> - Davey
>


Re: [PHP-DEV] Re: [RFC] Traits with interfaces

2016-03-05 Thread Davey Shafik
On Fri, Mar 4, 2016 at 2:06 AM, Rowan Collins 
wrote:

> Davey Shafik wrote on 04/03/2016 07:17:
>
>> 1. If you simply alias (use foo { bar as bat; }) then you end up with an
>> *additional*  method with the new name, the trait method as defined is
>> still
>> brought in, and_will_  override inherited methods of the same name.
>>
>
> Here's a clearer example of this: https://3v4l.org/RKHPt
>
> Unfortunately, you can't even use "insteadof" to directly bring the parent
> method back in [https://3v4l.org/qOS5T], but you can stub it out with a
> direct call to parent:: [https://3v4l.org/s9i4N].
>
> 3. Doing this (visibility + name)_only_  gives you the new method, which is
>> _different_  behavior to #1
>>
>
> I can't reproduce this: if I say "bar as private bat", the trait's bar
> still shows up, and is public, just as in the previous example:
> https://3v4l.org/1jH6o
>
> Your examples are rather confusing because they are effectively applying
> the same trait twice, at different levels of the hierarchy; I'm not sure
> this is a particularly likely scenario, or relevant to how interfaces
> should behave.
>
> Regards,


Rowan,

You are mid-reading, none of the classes in my examples extend the others,
they are all just using the same trait in different ways.

- Class a: use the trait with no aliases. Result: as expected
- Class b: use the trait with a simple alias, no visibility change. Result:
both methods
- Class c: use the trait with and alias both name, and change visibility.
Result: ONLY the aliased method
- Class d: use the trait and "alias" to the same name, ONLY changing
visibility. Result: causes a Fatal error, clashing with itself o.O

For the one you can't re-produce, it's class 'c', which is stand-alone
here: https://3v4l.org/K9o6Y

- Davey


Re: [PHP-DEV] Re: [RFC] Traits with interfaces

2016-03-04 Thread Rowan Collins

Davey Shafik wrote on 04/03/2016 07:17:

1. If you simply alias (use foo { bar as bat; }) then you end up with an
*additional*  method with the new name, the trait method as defined is still
brought in, and_will_  override inherited methods of the same name.


Here's a clearer example of this: https://3v4l.org/RKHPt

Unfortunately, you can't even use "insteadof" to directly bring the 
parent method back in [https://3v4l.org/qOS5T], but you can stub it out 
with a direct call to parent:: [https://3v4l.org/s9i4N].



3. Doing this (visibility + name)_only_  gives you the new method, which is
_different_  behavior to #1


I can't reproduce this: if I say "bar as private bat", the trait's bar 
still shows up, and is public, just as in the previous example: 
https://3v4l.org/1jH6o


Your examples are rather confusing because they are effectively applying 
the same trait twice, at different levels of the hierarchy; I'm not sure 
this is a particularly likely scenario, or relevant to how interfaces 
should behave.


Regards,
--
Rowan Collins
[IMSoP]


Re: [PHP-DEV] Re: [RFC] Traits with interfaces

2016-03-03 Thread Davey Shafik
On Thu, Mar 3, 2016 at 2:19 PM, Stephen Coakley 
wrote:

> On Wed, 17 Feb 2016 09:25:50 -0500, Kevin Gessner wrote:
>
> > Hello internals team!  I'd like to propose an RFC to allow traits to
> > implement interfaces.
> >
> > I've noticed s pattern in Etsy's code and elsewhere, where a trait
> > provides a common implementation of an interface.  Classes that use the
> > trait are required to also explicitly declare the interface to benefit.
> > I propose that traits be permitted to declare and implement interfaces.
> > Classes that use such a trait would then implement the interface, as
> > though it were declared on the class, without declaring the interface
> > explicitly.
> >
> > I believe this small change would be a useful improvement to the OO
> > system.  I've written a draft RFC, but I don't have karma to create the
> > wiki page for it.  Could someone please grant wiki karma to my account,
> > kevingessner?
> >
> > I don't yet have an implementation, but I'll be starting on one once
> > I've posted the RFC.  I look forward to your thoughts and feedback.
> >
> > Thanks in advance -- Kevin
> >
> > Kevin Gessner Staff Software Engineer etsy.com
>
> tl;dr: +1 and I really think that this language addition is useful and
> makes sense.
>
> Wow, I really want this feature. Reminds me of how powerful traits are in
> some other languages, such as Rust. It is very common to use traits to
> provide a common interface for something, but with some default
> implementations.
>
> Logging is a great example. Your interface might look like this (a
> familiar one, eh?):
>
> interface Logger
> {
> public function log($level, $message, array $context = array());
> public function error($message, array $context = array());
> public function warning($message, array $context = array());
> // etc...
> }
>
> where the idea is that the `error()` and such methods are a convenience
> for calling `log()` with a specific logging level. Obviously, these
> methods will be implemented in the same fashion most of the time; a trait
> would be great:
>
> trait LoggerTrait implements Logger
> {
> abstract public function log($level, $message, array $context = array
> ());
> public function error($message, array $context = array()) {
> return $this->log(ERROR, $message, $context);
> }
> // etc...
> }
>
> With this approach, I totally agree that allowing the `LoggerTrait` to
> implement the interface makes sense; it allows implementation to be
> enforced at the trait level. The second proposal that infers the interface
> implementation when using the trait is nice too (though not completely
> mandatory). It is pretty much the same situation where you do not have to
> re-implement an interface when extending a base class that already
> implements it.
>
> --
> Stephen


The aliases issue is a little more nuanced and potentially confusing,
regardless of this interface thing:

As you can see here: https://3v4l.org/L23LJ

1. If you simply alias (use foo { bar as bat; }) then you end up with an
*additional* method with the new name, the trait method as defined is still
brought in, and _will_ override inherited methods of the same name.

2. if you try to just change the visibility, you get a fatal error (Fatal
error: Trait method bar has not been applied, because there are collisions
with other trait methods), you must create an aliased name with the new
visibility

3. Doing this (visibility + name) _only_ gives you the new method, which is
_different_ behavior to #1

If the third behaved the same as the first, then this would be a non-issue.
Unfortunately, changing this behavior would be a — particularly hard to
diagnose — BC break and therefore cannot happen IMO.

Perhaps we could look at an alternative such as:

- traits can implement interfaces, which would ensure the _trait_ adheres
to it, but _not_ automatically classes use'ing it.
- Add a new syntax: "use Trait with Interface" or "use Trait implements
Interface" or "use Trait { implements Interface; }" which *explicitly*
calls out this usage

Just some off-the-top of my head thinking as an alternative.

- Davey


Re: [PHP-DEV] Re: [RFC] Traits with interfaces

2016-02-25 Thread Chris Riley
On 24 February 2016 at 22:04, Chase Peeler  wrote:

>
>
> On Wed, Feb 24, 2016 at 4:46 PM Kevin Gessner  wrote:
>
>> On Tue, Feb 23, 2016 at 4:48 AM, Chris Riley  wrote:
>>
>> > This isn't such a great idea as it will cause some of traits
>> functionality
>> > to be broken: I can currently use a trait and alias its methods and
>> change
>> > their visibility. If a trait implements an interface which is copied
>> onto
>> > my class I can no longer do this as the compiler will throw a fatal
>> error
>> > for the class not correctly implementing the interface that got copied
>> from
>> > the trait.
>> >
>>
>> This is only true under Proposal 2 of the RFC, and this is listed as an
>> open issue: https://wiki.php.net/rfc/traits-with-interfaces#proposal_2
>>
>> Proposal 1, where the engine enforces interface declarations on traits,
>> doesn't affect how traits are inserted and still allows aliasing.
>>
>>
>> > If you decide to continue pursuing this RFC, I'd like to see some
>> thought
>> > given to the above; perhaps it could be as simple as not copying the
>> > interface if aliases/visibility changes are made in the use or perhaps
>> > something more complex which allows specifying which interfaces should
>> be
>> > copied into the class from the trait.
>> >
>>
>> I agree that there are several reasonable solutions here, but I'm not sure
>> which is the best.  It does feel too aggressive to have it be a fatal
>> error
>> if aliasing undoes the interface implementation.  At the same time,
>> introducing new syntax to enable aliasing to work with interface
>> propagation defeats the purpose, which is to make it easier and simpler to
>> implement an interface via a trait.
>>
>> I'd be interested to hear if you have any ideas about how this should
>> look.  I'm mostly unfamiliar with aliasing traits in practice, so I'd be
>> curious to see how this RFC would affect your code.
>>
>> Since the class doesn't know you are using the trait to implement the
> interface, if you alias the trait method, then the class no longer
> implements the interface unless it defines the method that is now missing
> itself.
>
> Remember, the contents of the trait are just getting copy/pasted into the
> class. If you alias a method, then the method gets pasted in using the
> alias, not the original name.
>
> That being said, it should be rare that you would alias a method and then
> not implement the method yourself - as the need to redefine/expand on its
> functionality is the reason you usually alias a trait method.
>
>
>
>> Cheers
>> -- Kevin
>>
> --
> -- Chase
> chasepee...@gmail.com
>

Aliasing isn't something I use often; however changing visibility is - such
that the methods in the trait become an implementation detail for the class
in question and don't pollute it's public API. That would break if an
interface was copied onto my class.


Re: [PHP-DEV] Re: [RFC] Traits with interfaces

2016-02-24 Thread Chase Peeler
On Wed, Feb 24, 2016 at 4:46 PM Kevin Gessner  wrote:

> On Tue, Feb 23, 2016 at 4:48 AM, Chris Riley  wrote:
>
> > This isn't such a great idea as it will cause some of traits
> functionality
> > to be broken: I can currently use a trait and alias its methods and
> change
> > their visibility. If a trait implements an interface which is copied onto
> > my class I can no longer do this as the compiler will throw a fatal error
> > for the class not correctly implementing the interface that got copied
> from
> > the trait.
> >
>
> This is only true under Proposal 2 of the RFC, and this is listed as an
> open issue: https://wiki.php.net/rfc/traits-with-interfaces#proposal_2
>
> Proposal 1, where the engine enforces interface declarations on traits,
> doesn't affect how traits are inserted and still allows aliasing.
>
>
> > If you decide to continue pursuing this RFC, I'd like to see some thought
> > given to the above; perhaps it could be as simple as not copying the
> > interface if aliases/visibility changes are made in the use or perhaps
> > something more complex which allows specifying which interfaces should be
> > copied into the class from the trait.
> >
>
> I agree that there are several reasonable solutions here, but I'm not sure
> which is the best.  It does feel too aggressive to have it be a fatal error
> if aliasing undoes the interface implementation.  At the same time,
> introducing new syntax to enable aliasing to work with interface
> propagation defeats the purpose, which is to make it easier and simpler to
> implement an interface via a trait.
>
> I'd be interested to hear if you have any ideas about how this should
> look.  I'm mostly unfamiliar with aliasing traits in practice, so I'd be
> curious to see how this RFC would affect your code.
>
> Since the class doesn't know you are using the trait to implement the
interface, if you alias the trait method, then the class no longer
implements the interface unless it defines the method that is now missing
itself.

Remember, the contents of the trait are just getting copy/pasted into the
class. If you alias a method, then the method gets pasted in using the
alias, not the original name.

That being said, it should be rare that you would alias a method and then
not implement the method yourself - as the need to redefine/expand on its
functionality is the reason you usually alias a trait method.



> Cheers
> -- Kevin
>
-- 
-- Chase
chasepee...@gmail.com


Re: [PHP-DEV] Re: [RFC] Traits with interfaces

2016-02-24 Thread Kevin Gessner
On Tue, Feb 23, 2016 at 4:48 AM, Chris Riley  wrote:

> This isn't such a great idea as it will cause some of traits functionality
> to be broken: I can currently use a trait and alias its methods and change
> their visibility. If a trait implements an interface which is copied onto
> my class I can no longer do this as the compiler will throw a fatal error
> for the class not correctly implementing the interface that got copied from
> the trait.
>

This is only true under Proposal 2 of the RFC, and this is listed as an
open issue: https://wiki.php.net/rfc/traits-with-interfaces#proposal_2

Proposal 1, where the engine enforces interface declarations on traits,
doesn't affect how traits are inserted and still allows aliasing.


> If you decide to continue pursuing this RFC, I'd like to see some thought
> given to the above; perhaps it could be as simple as not copying the
> interface if aliases/visibility changes are made in the use or perhaps
> something more complex which allows specifying which interfaces should be
> copied into the class from the trait.
>

I agree that there are several reasonable solutions here, but I'm not sure
which is the best.  It does feel too aggressive to have it be a fatal error
if aliasing undoes the interface implementation.  At the same time,
introducing new syntax to enable aliasing to work with interface
propagation defeats the purpose, which is to make it easier and simpler to
implement an interface via a trait.

I'd be interested to hear if you have any ideas about how this should
look.  I'm mostly unfamiliar with aliasing traits in practice, so I'd be
curious to see how this RFC would affect your code.

Cheers
-- Kevin


Re: [PHP-DEV] Re: [RFC] Traits with interfaces

2016-02-23 Thread Chris Riley
On 23 February 2016 at 00:37, Alex Bowers  wrote:

> Would a fair solution to this be having the using class define whether to
> inherit the implementations? Perhaps a new keyword akin to 'propagated', so
> the code will read
>
> Class Foo {
>Use propagated TraitName;
> }
>
> Only then will the implementations from that trait bubble through. If it
> isn't declared then the implementations are not visible. This should keep
> all backwards compatibility and keep code readable since now we can
> immediately tell which traits being used do we want the implementations for
> in the main class.
> On 22 Feb 2016 20:19, "Kevin Gessner"  wrote:
>
> > On Thu, Feb 18, 2016 at 4:13 PM, Kevin Gessner 
> wrote:
> >
> > > On Wed, Feb 17, 2016 at 2:05 PM, Kevin Gessner 
> > wrote:
> > >
> > >> I've created a proper RFC wiki page here with the draft:
> > >> https://wiki.php.net/rfc/traits-with-interfaces
> > >>
> > >> It includes more detail and several example code snippets.  Thanks all
> > >> for your feedback so far.
> > >>
> > >
> > > I've just updated the RFC to v0.2, presenting two proposals to be voted
> > > separately: one to allow traits to declare and implement interfaces,
> and
> > a
> > > second (dependent on the first) to propagate interface declarations
> from
> > > traits to classes.
> > >
> >
> > I've created a php-src pull request for Proposal 1 of the RFC, allowing
> > traits to declare and implement interfaces:
> > https://github.com/php/php-src/pull/1773
> >
> > Reviews and feedback welcome!
> >
> > I haven't yet started on an implementation for Proposal 2.
> >
> > Cheers
> > -- Kevin
> >
>

This isn't such a great idea as it will cause some of traits functionality
to be broken: I can currently use a trait and alias its methods and change
their visibility. If a trait implements an interface which is copied onto
my class I can no longer do this as the compiler will throw a fatal error
for the class not correctly implementing the interface that got copied from
the trait.

If you decide to continue pursuing this RFC, I'd like to see some thought
given to the above; perhaps it could be as simple as not copying the
interface if aliases/visibility changes are made in the use or perhaps
something more complex which allows specifying which interfaces should be
copied into the class from the trait.

~C


Re: [PHP-DEV] Re: [RFC] Traits with interfaces

2016-02-22 Thread Alex Bowers
Would a fair solution to this be having the using class define whether to
inherit the implementations? Perhaps a new keyword akin to 'propagated', so
the code will read

Class Foo {
   Use propagated TraitName;
}

Only then will the implementations from that trait bubble through. If it
isn't declared then the implementations are not visible. This should keep
all backwards compatibility and keep code readable since now we can
immediately tell which traits being used do we want the implementations for
in the main class.
On 22 Feb 2016 20:19, "Kevin Gessner"  wrote:

> On Thu, Feb 18, 2016 at 4:13 PM, Kevin Gessner  wrote:
>
> > On Wed, Feb 17, 2016 at 2:05 PM, Kevin Gessner 
> wrote:
> >
> >> I've created a proper RFC wiki page here with the draft:
> >> https://wiki.php.net/rfc/traits-with-interfaces
> >>
> >> It includes more detail and several example code snippets.  Thanks all
> >> for your feedback so far.
> >>
> >
> > I've just updated the RFC to v0.2, presenting two proposals to be voted
> > separately: one to allow traits to declare and implement interfaces, and
> a
> > second (dependent on the first) to propagate interface declarations from
> > traits to classes.
> >
>
> I've created a php-src pull request for Proposal 1 of the RFC, allowing
> traits to declare and implement interfaces:
> https://github.com/php/php-src/pull/1773
>
> Reviews and feedback welcome!
>
> I haven't yet started on an implementation for Proposal 2.
>
> Cheers
> -- Kevin
>


Re: [PHP-DEV] Re: [RFC] Traits with interfaces

2016-02-18 Thread Fleshgrinder
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA256

First off: I like the idea of a trait being able to implement an
interface and having PHP validating that because I am like Larry and
prefer language construct over comments.

On 2/18/2016 4:11 PM, Chase Peeler wrote:
> 
> I agree, in theory, but I also think we introduce confusion. Every
> other OO rule says you get "everything*" from what you are using
> (extending a subclass gets you all the parent classes, implementing
> an interface that extends an interface gets you the parent
> interface, using a trait that uses a trait gets you both traits,
> etc). [...]
> 

I disagree on this. Traits are already special and adding interface
support to them that are not automatically inherited does not yield
confusion from my point of view. Most people will have a hard time
understanding them in the first place.

Again, traits are "reusable dead code" that don't do anything on their
own. Hence, if they suddenly start doing anything other it gets weird.
The class has to decide and only the class and it must be opt-in and
not opt-out because this becomes a conscious decision rather than:
"Dafuq, why is object A going through the method with the type hint
against interface B although it does not implement it? Oh, a trait...
Well I guess I need to **unimplement** the interface then." This is
crying out loud for unintended bugs in software.

- -- 
Richard "Fleshgrinder" Fussenegger
-BEGIN PGP SIGNATURE-
Version: GnuPG v2

iQIcBAEBCAAGBQJWxguAAAoJEOKkKcqFPVVr17QP/2iYhhv3dndfURkA/RW0lSTr
CTN6gkIxDSEoGOzxk0HXAL6D9jgXOqhfsavWFLd0bdS12+2tfbi4+tz1VSGhBGoD
fIYyvOh6gx7nnI4p8v7PTegaWPb2xuKf6D7+ogpFHH0PSi27gTV1Rgh6m/kdnH7+
wMKKybl7k1e85LEGNTs0PpXYRKNBKMK6EuoiQjbT3gPMle3ZQZYEDttOVHSKUmoO
heu0IHEkunzE7MtTMujqj6xgR2X3ce2SfXVsxLR3J0pBh7nFyfcm21tDz7a5gLE6
3qisBhjVBjAU9tAO1mbLJWzHGcyDLCBSncFJfpVgbi5I2OYyrsMCIy8fvMxAW6C3
zeP1kSVz2VHPQpG6vpwapSIPLB2bkGKxd8o2c9QM+RaF4c6gwNi6PWPYI2t/w8TH
iAq0jvQFdpRBAGpUyRpYrQ2/0clYLkl2qC/PRtA7SB19/Vsq3rROWqN0uKFtTb4K
iNHE7+9CQV8n/p0/DUm99wW42IGM+5bXGNcY7a+DWhC+eJsF7a8BohvUWay5sL4h
KZZ4VT8Khp5vbP3gpz7z8ugNMuFcIHkvJnUYR4QD9J1Ml5VpGH1pCw1uqKCN0qFX
pzmo84og2xVr+r1OJ5DjSbXQE6WDSMvuhmpayZWOfxPa7a80KqYkl9pczQRAHz6X
DvoLGPdq7s2rpknUYS84
=9OHz
-END PGP SIGNATURE-

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



Re: [PHP-DEV] Re: [RFC] Traits with interfaces

2016-02-18 Thread Kevin Gessner
Hi Chase and Larry,

On Thu, Feb 18, 2016 at 10:11 AM, Chase Peeler 
wrote:

> On Thu, Feb 18, 2016 at 5:35 AM Larry Garfield 
> wrote:
>  I'd rather the class
> > still need to self-declare the interface; that it uses a trait to
> > fulfill that contract is irrelevant to the outside world.
> >
> I agree, in theory, but I also think we introduce confusion. Every other OO
> rule says you get "everything*" from what you are using (extending a
> subclass gets you all the parent classes, implementing an interface that
> extends an interface gets you the parent interface, using a trait that uses
> a trait gets you both traits, etc). Perhaps we need a different keyword?
>

I'm wary of a new keyword, particularly because this situation isn't really
that different from what "implements" means.  I think if we wanted to go
down the route of new syntax, I'd want to expand the `use` statement for
traits to include or exclude any interfaces that a trait provides.  But I
don't think a syntax change is worth it for this feature, for the cognitive
and language overhead.


> [snip]
>
> At that point, the benefit becomes two-fold:
> >
> > 1) Communicate to users of the trait what the intent of the trait is: To
> > provide the boilerplate for some interface, or portion thereof.  This
> > could be covered by PHPDoc, potentially, and I've suggested the same for
> > PSR-5 before.
> >
> > Agreed


>
> > 2) Ask the engine to do a syntax check on the class to make sure I did
> > not forget something or screwed up in some way.  That is, not fulfilling
> > the interface on the trait would cause a parse error (or an error in my
> > IDE), forcing me to fix my bug before I even try running it.  PHPDoc
> > would NOT have this benefit.
> >
> > Thus I feel this addition does have value that a PHPDoc alternative
> > would not.
> >
> > Good point. I was of the opinion "we can just use comments to declare
> intent," but hadn't really thought of using the engine in this way. It
> makes sense.
>

That makes sense -- I like having the language enforce intent, rather than
just comments (which always rot, in my experience).


>
>
>
> > --Larry Garfield
> >
> > --
> > PHP Internals - PHP Runtime Development Mailing List
> > To unsubscribe, visit: http://www.php.net/unsub.php
> >
> > --
> -- Chase
> chasepee...@gmail.com
>


Re: [PHP-DEV] Re: [RFC] Traits with interfaces

2016-02-18 Thread Chase Peeler
On Thu, Feb 18, 2016 at 5:35 AM Larry Garfield 
wrote:

> On Wed, Feb 17, 2016, at 01:05 PM, Kevin Gessner wrote:
> > On Wed, Feb 17, 2016 at 9:25 AM, Kevin Gessner 
> wrote:
> >
> > > Hello internals team!  I'd like to propose an RFC to allow traits to
> > > implement interfaces.
> > >
> >
> > I've created a proper RFC wiki page here with the draft:
> > https://wiki.php.net/rfc/traits-with-interfaces
> >
> > It includes more detail and several example code snippets.  Thanks all
> > for
> > your feedback so far.
>
> Thanks, Kevin.
>
> At the risk of a "me too" post, I would also be in favor of allowing
> traits to declare an interface but NOT in favor of a use-ing class
> implicitly implementing the interface as a result.  I'd rather the class
> still need to self-declare the interface; that it uses a trait to
> fulfill that contract is irrelevant to the outside world.
>
I agree, in theory, but I also think we introduce confusion. Every other OO
rule says you get "everything*" from what you are using (extending a
subclass gets you all the parent classes, implementing an interface that
extends an interface gets you the parent interface, using a trait that uses
a trait gets you both traits, etc). Perhaps we need a different keyword?

trait foo providesfor myInterface {
}

I'm not sold on that keyword, it's just the first thing that came to mind.

*I know you don't get private methods and properties in subclasses, but
that's something dictated by the class itself. The class says "you can't
have these if you extend me" instead of the engine saying "you aren't
implementing that when you use the trait because it's a trait"

At that point, the benefit becomes two-fold:
>
> 1) Communicate to users of the trait what the intent of the trait is: To
> provide the boilerplate for some interface, or portion thereof.  This
> could be covered by PHPDoc, potentially, and I've suggested the same for
> PSR-5 before.
>
> Agreed


> 2) Ask the engine to do a syntax check on the class to make sure I did
> not forget something or screwed up in some way.  That is, not fulfilling
> the interface on the trait would cause a parse error (or an error in my
> IDE), forcing me to fix my bug before I even try running it.  PHPDoc
> would NOT have this benefit.
>
> Thus I feel this addition does have value that a PHPDoc alternative
> would not.
>
> Good point. I was of the opinion "we can just use comments to declare
intent," but hadn't really thought of using the engine in this way. It
makes sense.




> --Larry Garfield
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
> --
-- Chase
chasepee...@gmail.com


Re: [PHP-DEV] Re: [RFC] Traits with interfaces

2016-02-18 Thread Larry Garfield
On Wed, Feb 17, 2016, at 01:05 PM, Kevin Gessner wrote:
> On Wed, Feb 17, 2016 at 9:25 AM, Kevin Gessner  wrote:
> 
> > Hello internals team!  I'd like to propose an RFC to allow traits to
> > implement interfaces.
> >
> 
> I've created a proper RFC wiki page here with the draft:
> https://wiki.php.net/rfc/traits-with-interfaces
> 
> It includes more detail and several example code snippets.  Thanks all
> for
> your feedback so far.

Thanks, Kevin.

At the risk of a "me too" post, I would also be in favor of allowing
traits to declare an interface but NOT in favor of a use-ing class
implicitly implementing the interface as a result.  I'd rather the class
still need to self-declare the interface; that it uses a trait to
fulfill that contract is irrelevant to the outside world.  

At that point, the benefit becomes two-fold:

1) Communicate to users of the trait what the intent of the trait is: To
provide the boilerplate for some interface, or portion thereof.  This
could be covered by PHPDoc, potentially, and I've suggested the same for
PSR-5 before.

2) Ask the engine to do a syntax check on the class to make sure I did
not forget something or screwed up in some way.  That is, not fulfilling
the interface on the trait would cause a parse error (or an error in my
IDE), forcing me to fix my bug before I even try running it.  PHPDoc
would NOT have this benefit.

Thus I feel this addition does have value that a PHPDoc alternative
would not.

--Larry Garfield

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