I did not expect nor intend to go down the rabbit hole regarding this topic, so 
this will likely be my last reply on this thread.

> On Apr 25, 2021, at 4:51 PM, David Gebler <davidgeb...@gmail.com> wrote:
> 
> On Sun, Apr 25, 2021 at 8:52 PM Mike Schinkel <m...@newclarity.net> wrote:
> 
>>> On Apr 25, 2021, at 1:52 PM, David Gebler <davidgeb...@gmail.com> wrote:
>>> 
>>> Still, all these problems are solved to the same degree if you add a
>>> #[Sealed] attribute to a class which has no functional impact. You have
>>> sufficiently indicated to any user that extending this class is not a
>>> designed feature and may cause backwards-incompatible breaks with future
>>> releases - in a way that both a programmer and IDE can reason about,
>> which
>>> in PHP's context is what matters. Attributes arguably even have a greater
>>> qualitative advantage that they can be applied right down as far as
>>> individual method parameters.
>> 
>> In my experience, if a developer needs access to a feature that is easily
>> available via the use of a method that is merely documented as internal-use
>> only, the developer will use it rather anyway than spend a lot more time
>> trying to work around what that method makes easily available.  Especially
>> if that documented internal-use only is about not subclassing.
>> 
>> And if many other developers do that, the original developer will still
>> have the same problem as if they didn't document it as internal-use only.
>> 
>> But I do acknowledge your experience might be different.  FWIW.
>> 
> 
> You're answering a different point to the one I'm making, which is that in
> contrast to a language like Java, where the compiler gets a benefit out of
> reasoning about virtual vs non-virtual methods, the use of sealed as a
> language construct in an interpreted language like PHP can do nothing which
> isn't already achieved by annotation - the expression of intent.

Assuming the annotation is only advisory and the keyword is actionable then of 
course PHP can do something not already achieved by annotation; it can throw an 
error when it comes across a class that attempts to extend a sealed class that 
has not named it as an exception.  

> 
>>> In Java the idea of final and sealed classes makes more sense, since we
>>> actually to some extent need the compiler to be able to reason about
>> these
>>> types and can gain optimization and code generation benefits from its
>> being
>>> able to do so. PHP's concept of typing and implementation of type
>> checking
>>> as an interpreted language is completely different.
>>> 
>>> I wonder, if final and sealed as language constructs really offer the
>>> guarantees about intent and safety their advocates say they do, why are
>>> they not the default? Why can no one point me to a language where I have
>> to
>>> write something like
>>> 
>>> extendable class Foo permits all { .... }
>>> 
>>> (and there are people who would be in favour of making inheritability
>> this
>>> explicit, but I'm not one of them)
>> 
>> Well, I can't point you to a language that works that way because I don't
>> know more than a handful of languages in depth — although there may be one
>> — but I can point you to a language that does not even allow you to
>> subclass: Go.
>> 
>> The Go designers wanted to get away from the fragile base class problem so
>> they provided embedding instead:
>> 
>> 
>> https://medium.com/@simplyianm/why-gos-structs-are-superior-to-class-based-inheritance-b661ba897c67
>> 
>> I program more in Go now than in PHP, and I can confirm that its approach
>> works brilliantly. Better IMO than what PHP currently offers in that
>> respect.
>> 
> 
> Again, this doesn't seem relevant to the discussion in respect of PHP or
> the RFC we're talking about. I don't have a Go background but I'm learning
> it at the moment and I like it a lot. Nonetheless it's neither comparable
> to PHP nor object oriented in a conventional sense so any direct comparison
> here is probably not too useful.

If you are going to equivocate and add more limiting criteria to your claim 
post hoc then of course the example I provided won't be too useful.


>>> It's one thing as an author of code to say "I only intended and support
>>> this finite set of use-cases", it's quite another to say "and you should
>> be
>>> impeded from proceeding with any legitimate use-case I didn't imagine or
>>> foresee"
>> 
>> I do respect that as a user of other developer's code you might view it
>> that way.
>> 
>> But then I also can respect the library or framework developer who chooses
>> to make their own job less difficult by (wanting to) mark a class to be
>> sealed.
>> 
>> You claim "it's quite another thing to say" but I don't think a developer
>> of library or framework code should be required to offer features to their
>> users they do not want to offer.  It is the developer's prerogative; if
>> they want to be able to mark their classes as sealed they should be
>> empowered to do so. IMHO, anyway.
>> 
> 
> My argument is not that there aren't legitimate cases where you want to
> indicate a class or interface as sealed, nor that developers should not be
> empowered to make this indication. It is that in PHP, as an interpreted
> language, there is little to no benefit in expressing this through a new
> language construct than through existing constructs and design patterns.

I'll just leave this as-is since Larry and Saif have already explained how 
there is in-fact benefit for `sealed` in PHP.

>> 
>>> In practice, the only thing I've ever seen this achieve is to create
>>> difficulties, while the claimed benefits can be adequately (and better)
>>> achieved through existing patterns like annotations, interfaces and DI.
>> 
>> I would argue that maybe the reason you have only seen it create
>> difficulties is because of your own perspective and experiences that are,
>> by definition, anecdotal and thus limited.
>> 
>> OTOH Fabien Potencier and/or Taylor Otwell might have a different
>> experiences and thus a different perspective on what those benefits are
>> (but I am admittedly just hypothesizing here.)
>> 
> 
> Allow me to re-phrase then, in a way which removes anecdotes from the
> equation; what is the problem in PHP which would be solved by adding the
> sealed keyword (or any equivalent) and can't be solved via attributes or
> other features already part of the language? There's no runtime benefit and
> an IDE can read attributes to tell you you're breaking someone else's
> intentions and prevent you making a mistake in respect of that.

As I said above, there is indeed a runtime benefit.  PHP can throw an error and 
disallow extending sealed classes that do not have stated permission.

> Part of the argument I see for these features in languages which have them
> is that inheritance is dangerous.

I do not see it as "dangerous" though you are certainly free to view it that 
way.

Having `sealed` would allow developer to significantly reduce the number of 
scenarios where they would need to bump major version numbers because of 
breaking changes since, in reality, any newly added method to an existing 
extensible class is potentially a breaking change.

Not having `sealed` is not so much "dangerous" as it increases the likelihood 
that a new release should be classified as a breaking change and thus requires 
everyone who uses the release to consider whether or not the new release will 
break their code. Even if a developer has never extended any of the 3rd party 
classes they will still need to spend time to understand what has changes and 
ponder whether if effects their code or not.

> And it certainly can be, but it can also
> be dangerous to put in new language features which can be misunderstood and
> used inappropriately. I just think we need to carefully weigh up the
> cost/benefit of new language features (particularly new syntax).

I think weighing the cost/benefit is exactly what this discussions are doing.

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

Reply via email to