On Wed, Jan 5, 2022 at 6:05 PM Larry Garfield <la...@garfieldtech.com>
wrote:

> On Wed, Jan 5, 2022, at 2:35 PM, Chase Peeler wrote:
>
> > First, I'm someone that mainly uses traits to implement the functionality
> > defined in an interface. I think that's one of the best uses for them.
> > However, I'm personally not a huge fan of overly restrictive things. For
> > instance, while there are definitely some use cases for them, I need a
> > REALLY good reason to justify making a property/method private instead of
> > protected, or making a class final.
>
> I am much the same.
>
> > As such, I think this would be better if it didn't throw a fatal error.
> > When you make it optional, however, I think you are left with something
> > that can be handled with an attribute just as well as a new keyword:
> > #[Expects('MyInterface')]
> > trait foo { }
> >
> > However, there might be value in generating a notice/warning, and I think
> > that would require a keyword, correct? (Not that up to speed on
> > annotations). Another option might be two support two new keywords:
> > requires and expects. The former would throw an error if the interface
> > isn't implemented while the latter will throw a warning/notice/nothing.
> >
> > Another option (and I haven't thought about this one enough to decide if
> I
> > like it) would be to have the expected interface automatically
> implemented
> > in the using class. This would allow the trait to be written under the
> > assumption it has access to the methods defined in the interface, and
> will
> > then throw an error if any of the methods are not implemented in the
> using
> > class:
> >
> > interface foo {
> >   function a();
> >   function b();
> > }
> >
> > trait bar expects foo {
> >    function c(){
> >        return $this->a() + $this->b();
> >    }
> > }
> >
> > class baz {
> >   use foo;
> > }
> >
> > The above would throw an error since a() and b() are never implemented
> and
> > baz is implementing the foo interface. You can currently get the same
> > behavior if you define a() and b() as abstract in the trait. However,
> this
> > doesn't give you the added benefit of utilizing the interface
> automatically
> > within the type system. The more I think about it, the less I like this
> > idea, since it doesn't require that much additional work to make the code
> > clearer by explicitly implementing the interface on the class if you want
> > it implemented. However, I'll go ahead and leave it here because it might
> > help generate some other ideas.
>
> I... still don't see any use in this annotation.
>
> Stepping back and ignoring the syntax for a moment, there's two different
> things here:
>
> 1. "This trait expects to be used in a class that has these other methods
> on it".
> 2. "This trait mostly/fully fulfills interface X, because it has methods
> a, b, and c."
>
> For point 1, we already have that.  It's called abstract methods in
> traits.  This is a solved problem that requires no further resolution.  At
> best it would be a shorthand to copying a few methods from an interface
> into the trait and sticking "abstract" in front of them.  I really don't
> see a need for that.
>
>
Agreed. It would also allow IDEs and what not to determine the trait has
access to the interface methods that you didn't explicitly define as
abstract, but I still agree that it would just be shorthand that isn't
really needed.


> For point 2, that's mainly useful as a way to signal to other developers
> "hey, this trait has all but one method of the LoggerInterface, that's how
> you'd use it", and to signal static analyzers and refactoring tools the
> same thing so that they can be auto-updated if you tweak the interface.  I
> can see a use for point 2, and it would make my life a bit easier, but it's
> overall not high priority.
>
>
I also agree.

I was focusing more on fleshing out the idea in general. I think the idea
is interesting enough that it's worth discussing even if it doesn't seem
like it's worth pursuing in its current form.


> --Larry Garfield
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>

-- 
Chase Peeler
chasepee...@gmail.com

Reply via email to