Re: Re: Improving PHP's type system
| From: | Fleshgrinder | Date: | Tue, 19 Apr 2016 17:32:57 +0000 |
| Subject: | Re: Re: Improving PHP's type system | ||
| References: | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-92477@lists.php.net to get a copy of this message | ||
On 4/19/2016 11:41 AM, Zeev Suraski wrote:
> It could actually implement all of them - the two parents, and the child. That sounds like a
> pretty good, explicit way that requires no introduction of any new syntax, concepts or engine
> complexity in order to do what you're describing. This works fine:
>
> interface foo { function foo(); }
> interface bar { function bar(); }
> interface baz extends foo,bar {}
>
> class impl implements foo, bar, baz {
> function foo(){}
> function bar(){}
> }
>
> function sth(baz $b){}
>
Attachment: [application/pgp-signature] OpenPGP digital signature signature.asc
class impl implements baz {} is actually already enough here because
baz extends foo and bar. This is the only way to solve such
situations right now but it does not help with primitive types. :(
> One thing we could consider is adding some intelligence for these cases, and for interfaces
> that only extend other interfaces (without adding new signatures) - a class would be considered to
> implement that interface if it implements all of the 'parent' interfaces that the child
> interface extends:
>
> class impl implements foo, bar {
> function foo(){}
> function bar(){}
> }
>
> function sth(baz $b){} <-- would work, as impl implements both foo and bar, and baz does
> nothing but extending those.
>
> I'm not sure that's necessary, and believe the current mechanisms and syntax satisfy
> these use cases already, but it's probably a possibility.
>
That sounds like runtime checked duck typing. This actually makes the
type system less strict and might have horrific side effects and that is
exactly the opposite of what union/intersection types are meant for:
preventing this. Above code is the same as:
function sth($b) {
$b->foo();
$b->bar();
}
It will definitely fail if something else is passed in but if it is
foo, bar, or baz everything is fine. The problem is that any
object that satisfies the implementation of the methods foo and bar
would ultimately fulfill the contract here.
function sth(foo&bar $b) {}
This is a different situation because now we know that it is something
that actually implements exactly those two interfaces. Including
possible additional constraints like argument and return type hints.
There might even be a documentation shipped together with them that the
implementer should take care of honoring. The intersection type hint is
much stricter in such cases.
--
Richard "Fleshgrinder" Fussenegger
Attachment: [application/pgp-signature] OpenPGP digital signature signature.asc