> On Mar 11, 2020, at 1:39 PM, Rowan Tommins <rowan.coll...@gmail.com> wrote:
> 
> On Wed, 11 Mar 2020 at 14:18, Mike Schinkel <m...@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.

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

Reply via email to