Re: [RFC] Attributes v2

From: Date: Wed, 11 Mar 2020 19:12:31 +0000
Subject: Re: [RFC] Attributes v2
References: 1 2 3 4 5  Groups: php.internals 
Request: Send a blank email to internals+get-108985@lists.php.net to get a copy of this message
> On Mar 11, 2020, at 1:39 PM, Rowan Tommins <rowan.collins@gmail.com> wrote: > > On Wed, 11 Mar 2020 at 14:18, Mike Schinkel <mike@newclarity.net> wrote: > >> >> IOW, if interfaces cannot enforce the requirements of the "contract" why >> have interfaces? Why not just use method_exisits() when we need to call a >> prescribed method? >> > > > Interfaces, at least as implemented by languages such as PHP and Java, do > two things: > > * They _declare_ that a class meets a particular contract > * The _enforce_ some subset of that contract > > The implied contract is almost always more than what the language can > enforce; > > The problem is, PHP (following the lead of Java and others) doesn't really > implement interfaces as contracts, but as a limited form of multiple > inheritance - the implementing class inherits a bunch of abstract methods, > and is obliged to override them only if it's not itself abstract. > > So in order to represent "must add this attribute", I think we would need a > syntax for "abstract attributes" on the interface, then a check that a > concrete class has no abstract attributes. Correct. > That's particularly true if you want to enforce that a *method* has an attribute, > because an abstract class can implement interfaces without actually defining > their methods, so the obligation needs to be inherited until you reach a > concrete class. In my use-cases I primarily only need class attributes, not method attributess, but I certainly would not suggest this enforcement should be limited to classes. > That in turn opens up the question of whether attributes should be > inherited in general, to which the current RFC says "no" on grounds of > simplicity, and leaves it up to the userland implementation. Having an obligation to implement an attribute feels to me to be orthogonal to inheritance of attributes. My gut feeling is that attributes should be specific to the classes in which they are declared. But I see no reason a "must-add" requirement for attributes where the requirement is passed down to a concrete class needs to be coupled to a inheritance of attributes. Using an analogy out of left field, we could view an attribute as the "about me" section of your Linked In. That is about you. Your kids don't inherit it, nor should they. OTOH, you could say to your grand kids "Add a LinkedIn page with an 'about me' section or I won't get you anything for your birthday." So attribute inheritance is iffy because inheriting attributes might not apply, but *requiring* an attribute has no such potential conflict. > Maybe this is the kind of thing that can be experimented with in userland, > then added to core later if it can be made universal enough. For instance, > you could have "meta" attributes that took a class name as a parameter, > such as << Require(Table::class) >> on interfaces, and << Inherit >> on > attribute definitions. Then a checking tool could look up the inheritance > tree and identify missing attributes to complain about, or inherited > attributes to copy. It could certainly be implemented in userland by the code that consumes the interface. But not every consumer will implement it and further there would be no syntax for a static analysis tool or IDE to use to recognize the requirement. Hence why I'd love to see that ability to specify in an interface when a class must implement attributes. -Mike P.S. And while I am at it, I would also really like to be able to require static methods and constants via an interface, too.

« previous php.internals (#108985) next »