As others have said: the interface/contract makes available public stuff that is what the implementers will make available. So it should not matter if those are methods or properties. In the case of a public property, the difference from the method-only approach is that it's already implicit that the read and write operations are available (for non-readonly properties, of course). I like it. It can eliminate a lot of boilerplate and make things more obvious to the final user of the class that implements the interface.
-- Erick Em dom., 28 de mai. de 2023 às 14:37, David Gebler <davidgeb...@gmail.com> escreveu: > On Sun, May 28, 2023 at 5:03 PM Larry Garfield <la...@garfieldtech.com> > wrote: > > > On another level, I'd redefine properties and methods slightly. (Public) > > Properties are not "raw data" but "aspects of the object I can > manipulate" > > and methods are "behaviors I can ask the object to perform." > > > > I just wanted to pull out this sentence in particular because I think it's > very much true of the property hooks RFC where you can attach behaviours to > what are from the outside accessed as if they were fields - and yes > properties on interfaces makes at least more sense in that case...but I > don't think it's true of the RFC Nick is proposing, which would very much > allow interface designs where a property is simply a (maybe typed) public > property and does represent a "raw data" value. > > I suppose the difficulty for me is that I appreciate "people could abuse > it" isn't a reason in itself to exclude a feature, where it could prove > useful in a non-abusive way. But languages have ecosystems and frameworks > and conventions and idioms around them which go beyond what the language > strictly does and doesn't permit. People who like Laravel will say you can > write poor PHP code in any framework and good PHP code in Laravel, and > they're right, but personally I'd argue Laravel encourages you to write PHP > code in a way which is commonly and conventionally considered to not be a > best practice. And I don't like it very much for that reason. It's the same > for me with properties on interfaces; I think it will encourage people to > do things that some of the conventional wisdom out there says they probably > shouldn't. > > Anyway, apologies I'm not replying in depth to your comments; I'm just wary > of descending into a philosophical wayside about principles of programming > and "best practices". And my views on those things are probably quite > anodyne, but the margin for difference in good opinions is more than enough > that I don't want to go there. > > -Dave > > On Sun, May 28, 2023 at 5:03 PM Larry Garfield <la...@garfieldtech.com> > wrote: > > > On Sun, May 28, 2023, at 6:52 AM, David Gebler wrote: > > > On Sun, May 28, 2023 at 10:33 AM Rowan Tommins < > rowan.coll...@gmail.com> > > > wrote: > > > > > >> I don't follow. If a property is public, then code outside the class > can > > >> rely on being able to access it. That seems to me to be a contract > > between > > >> the class and its users, not an implementation detail - e.g. removing > > the > > >> property, or changing its type, would be a compatibility break. A > > property > > >> can also be inherited from a base class, at which point there is a > > contract > > >> that all descendants of that base class will have the property > > available. > > >> So it seems logical that that contract could also be included in an > > >> interface. > > >> > > >> > > > That's why you can declare constants in an interface (a static final > > > property, to use the lexicon of Java) which we can already do in PHP. > At > > > the point you want to bring mutable state into an interface, it's a > > design > > > smell that what you want, really, is an abstract class or perhaps > > > composition. > > > > Almost never is an abstract class what you want, frankly. An abstract > > class unnecessarily conflates "is a special case of" and "reuses code > from" > > into a single syntax. "Making one thing do two things" is a design flaw > in > > most of computer science, and one that PHP has been bitten by multiple > > times. > > > > cf: https://www.garfieldtech.com/blog/beyond-abstract > > > > > A couple of languages do allow mutable properties on interfaces, > > TypeScript > > > being one of them, so yes it's not an unheard of feature - but in TS/JS > > > it's a lot more idiomatic to directly access properties than it is in > > PHP. > > > I'm not too familiar with C# personally but I have a vague recall that > > the > > > idea of properties on interfaces there is more akin to the property > hooks > > > RFC than Nick's proposal here. And although I'm a little uncomfortable > > with > > > encouraging getters and setters on interfaces, I'm fully behind > property > > > hooks, I hope that RFC passes. > > > > > > PHP already has the sufficient design tools to follow SOLID principles > > and > > > established design patterns well. If this RFC was in the language > > tomorrow, > > > you wouldn't be able to do anything you can't already do and do more > > > safely, more robustly, with behavioural interfaces and traits. > > > > > > -Dave > > > > > > There's technically nothing you cannot do with any language once it has > > type definitions, functions, and closures. Everything beyond that is > > syntactic sugar; including classes themselves. It's a question of which > > syntactic sugar gives the sweetest developer experience. > > > > The core question here is a little philosophical. What exactly is an > > interface? Is it "a collection of methods", "a collection of behaviors", > > or "how I can interact with this object"? > > > > If you start from the position that an interface is "a collection of > > methods", then yes, interface properties don't fit. However, I'd that's > a > > too-restrictive understanding of interfaces. "How can I interact with > this > > object" or "what contracts, in the abstract, does this object fulfill" > are > > more accurate questions answered by an interface. > > > > There is a common but naive approach to OOP (which I have expressed > myself > > in the past, so no shade involved here) that "properties are > > implementation, methods are abstraction." Which... is not unreasonable > as > > a first-order approximation, but is incomplete. > > > > If your class has getters/setters (as is common for entities), then > > there's really no "implementation hiding" going on. There's just extra > > syntax for a public property. So the existence of those properties is > > already, de facto, a part of the interface of the object. While you can > > fake it out with a different implementation inside the get/set methods > (as > > in the various examples in the Property Hooks RFC), in practice it's > quite > > rare to do so. So that clean dividing line is already violated by common > > practice. > > > > So on one level, property hooks and interface properties together let you > > define the behavior of an object similar to how you do now, but with 1/4 > as > > much code, and without losing the ability to "fake it out" in the few > cases > > it's necessary. It's not violating any separation that isn't already > > violated in practice. > > > > Moreover, methods obviously have their own implementation details. While > > ideally those are kept fully separated from the outside world, in > practice > > that's impossible. Even if you had an Idris-level type system (with > > dependent types), you cannot completely specify all behavior in just an > > interface; If you could, it wouldn't be a type system anymore, just code. > > :-) So the separation is not perfect on that side, either. > > > > On another level, I'd redefine properties and methods slightly. (Public) > > Properties are not "raw data" but "aspects of the object I can > manipulate" > > and methods are "behaviors I can ask the object to perform." > > > > From that perspective (which seems to be increasingly common, based on > the > > listed languages that have some version of interface properties and > > hooks/accessors), of course properties belong in interfaces. It's > obvious > > that they do, because "aspect I can manipulate" is an abstract concept. > > > > $collection->isEmpty() and $collection->isEmpty are both entirely > > reasonable ways to introspect the status of the $collection object. > > There's nothing inherently superior about the former, except that > > historically it's been the only option. Once you have hooks, though, the > > latter is a natural and obvious introspection mechanism. I'm not > > suggesting it's superior or that anyone needs to switch to it, just that > > it's a reasonable approach. > > > > And in that case, you need a reasonable way to specify that mechanism for > > an interface. Hence, interface properties. > > > > A "raw data" property can and should still be protected or private, at > > which point none of this discussion matters at all as those are not and > > should not be supported by interfaces. > > > > --Larry Garfield > > > > -- > > PHP Internals - PHP Runtime Development Mailing List > > To unsubscribe, visit: https://www.php.net/unsub.php > > > > >