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
>
>

Reply via email to