PHP's notion of "implements" is identical to that of Java and C#. This is
not by accident, many programmers have to work in multiple programming
languages. The less a language does things "differently" the better.

And honestly, the upsides of this proposal are not worth the BC breaks
created with the new keywords.

On Wed, Jun 10, 2020 at 11:16 AM Doug Wilbourne <dougwilbou...@gmail.com>
wrote:

> I propose the following language additions:
>
>
>
> 1) add three new keywords to the available syntax for class declarations:
> 'inherits' and 'subtypes' and 'patterns'.
>
>
>
> Currently the 'extends' keyword means both inherits and subtypes,
> which leads to unnecessarily restrictive typing problems in order to
> satisfy the Liskov substitution principle.  'Inherits' would mean that
> class A inherits B's properties and methods but is not a subtype of B and
> cannot be substituted for B.  And just as A can override/overload B's
> methods, the method signatures would not be subject to the parameter
> widening / return-type restricting principle necessary for substitution.
> Conversely, the 'subtypes' keyword indicates that if A subtypes B then A
> can be substituted anywhere B can be used but 'subtypes' does not imply
> that A inherits any of B's methods and properties - simply that it has
> signatures that conform to the parameter widening and return-type
> restricting principles of substitution.  Lastly 'patterns' complements the
> 'implements' keyword.  A class 'patterns' an interface if it conforms to
> the declared signature of the interface but it does not imply that the
> concrete class can be substituted for any other object which either
> implements or patterns the interface.
>
>
>
> It should be possible to write 'A inherits, subtypes B' and this should
> have the same effect as 'A extends B'.
>
>
>
> 2) Add two new operators: 'descendentof' and 'subtypeof' that would augment
> 'instanceof'.  Semantics parallel the class declaration keywords described
> above.
>
>
>
>
>
> Benefits:
>
>
>
> It would then be possible to write something like the following:
>
>
>
> interface ValidatorInterface
>
> {
>
>     public function validate($x) : bool;
>
>     public function getErrmsg() : string;
>
> }
>
>
>
> abstract class Validator patterns ValidatorInterface
>
> {
>
>     abstract public function validate($x) : bool;
>
>
>
>     public function getErrmsg() : string
>
>     {
>
>         return $this->errmsg;
>
>     }
>
> }
>
>
>
> class ValidatorNonNegativeInteger inherits Validator patterns
> ValidatorInterface
>
> {
>
>     public function validate(int $x) : bool { return 0 <= $x; }
>
> }
>
>
>
> class ValidatorAlphaText(string $x) inherits Validator patterns
> ValidatorInterface : bool
>
> {
>
>     return 1 == preg_match('/^[a-zA-Z]+$/', $x);
>
> }
>
>
>
> ValidatorNonNegativeInteger and ValidatorAlphaText cannot be substituted
> for each other or Validator or ValidatorInterface.  Explicitly trying to
> upcast ValidatorNonNegativeInteger should produce a compiler error (e.g.
> (Validator) new ValidatorNonNegativeInteger() is not legal).
>
>
>
> If you adopt the data type 'mixed' and use it as in "public function
> validate(mixed $x)", it makes it even clearer that the syntax permits
> covariant parameters.
>
>
>
> Currently the compiler allows contradictory parameter declaration between
> parent and descendant (using 'extends') but produces a runtime error
> indicating that the child method's parameter must conform to that of the
> parent.  Because substitution is not an issue when A inherits B (using
> ‘inherits’ as above, not ‘extends’), a parent declaring "function foo(int
> $bar)" and a descendant declaring "function foo(string $bar)" has no
> theoretical problem as far as I can tell and should not produce an error.
>
>
>
> Along with generics (already being suggested / discussed I think - and
> thank you for unions), this approach should lead to DRYer code and cleaner
> abstractions.  In the example above, ValidatorNonNegativeInteger and
> ValidatorAlphaText can leverage common code in the parent class.  And it is
> not necessary to write two separate interfaces in order to handle the two
> different data types.  Essentially, it creates a bridge between the old
> 'untyped' Zvals and the tightly typed C derivatives.
>
>
>
>
>
> Who Is Going To Write This?
>
>
>
> I am relatively new to the PHP community and have never once glanced at the
> internals of PHP.  As much as I would love to do it, my learning curve will
> be quite some time before I would be ready to tackle something like this.
> And I think the time for this idea is now while there is so much momentum
> in the community on type-safety.  I am considering getting involved in the
> community per the guidance (test writing, documentation, etc) but have not
> plucked up the courage to make the commitment yet.  And my C is super
> rusty.  If this falls on deaf ears, I am afraid the idea will never bear
> fruit. If everyone thinks it is a good idea, then I am particularly sorry I
> cannot do it myself since it is wrong to make my problem someone else’s
> problem.  I would consider writing something in PHP to implement the idea,
> but cannot really see how it could be accomplished.
>
>
>
> Thank you for your time and consideration.  And thank you so much for all
> the work you do to make PHP the product that it is.
>
>
>
> Kind regards,
>
>
> Doug Wilbourne
>

Reply via email to