With "Interface Default Methods" potentially becoming a thing, it begs the 
question for the need to have Interface Properties, at least `private` ones and 
`private static` ones. 

How can we have default getters and default setters in an interface if there 
are no private interface properties to get or set? Ignoring special cases, that 
is.

Of course if the RFC for "Interface Default Methods" fails to pass then this 
point is moot.

-Mike

> On May 28, 2023, at 1:51 PM, Erick de Azevedo Lima <ericklima.c...@gmail.com> 
> wrote:
> 
> 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
>>> 
>>> 
>> 

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

Reply via email to