Re: Allow dropping typehints during inheritance
| From: | Rowan Collins | Date: | Wed, 04 Feb 2015 22:02:30 +0000 |
| Subject: | Re: Allow dropping typehints during inheritance | ||
| References: | 1 2 3 4 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-81843@lists.php.net to get a copy of this message | ||
On 4 February 2015 21:25:49 GMT, Nikita Popov <nikita.ppv@gmail.com> wrote:
>On Wed, Feb 4, 2015 at 10:17 PM, Rowan Collins
><rowan.collins@gmail.com>
>wrote:
>
>> On 4 February 2015 21:02:30 GMT, Yasuo Ohgaki <yohgaki@ohgaki.net>
>wrote:
>> >Hi Nikita,
>> >
>> >On Thu, Feb 5, 2015 at 3:49 AM, Nikita Popov <nikita.ppv@gmail.com>
>> >wrote:
>> >
>> >> Currently we do not allow [1] removing a typehint during
>inheritance.
>> >For
>> >> example the following code is not valid:
>> >>
>> >> interface A {
>> >> public function method(Typehint $param);
>> >> }
>> >> class B implements A {
>> >> public function method($param);
>> >> }
>> >> // Fatal error: Declaration of B::method() must be compatible
>> >with
>> >> A::method(Typehint $param)
>> >>
>> >> The above code does *not* constitute an LSP violation, because
>> >B::method()
>> >> accepts more inputs than A::method(). However we still forbid it.
>> >>
>> >> This is an issue, because it makes it impossible to add typehints
>to
>> >> parameters at a later point in time. I've seen this issue come up
>> >both in
>> >> userland code, as well as in a recent DateTime change, see
>> >>
>> >>
>> >
>>
>https://github.com/php/php-src/commit/8e19705a93d785cd1ff8ba3a69699b00169fea47
>> >> .
>> >>
>> >> Instead of reverting the DateTime BC break, I'm wondering if it
>> >wouldn't be
>> >> better to fix the root cause by making the inheritance check less
>> >strict
>> >> and allow removing typehints?
>> >>
>> >
>> >I can understand your reason. It's reasonable perfectly.
>> >Template is better, but PHP is weakly typed language.
>> >I think it's acceptable.
>> >
>> >Since Dmitry agreed to introduce DbC, if he like the syntax, etc and
>> >proposal is passed.
>> >DbC may be used to check various types or user may simply write code
>> >that
>> >handles
>> >various types in function body.
>>
>> This is actually my fear: that people will misunderstand this as an
>excuse
>> to write invalid type checks, such as ones which are tighter rather
>than
>> looser than the parent class (it takes a bit of careful thought to
>> understand why this is wrong). Unfortunately, we don't have a keyword
>for
>> explicitly allowing any value, or even a base for all objects, so I
>guess
>> we have to take that risk, but at least if contravariance were fully
>> supported, we could have clear examples of correct usage.
>>
>> (Incidentally, I'm not sure how templates are relevant - this is
>purely
>> about inheritance and LSP of ordinary objects.)
>>
>>
>Maybe I wasn't clear here. I do not propose to allow any code that
>violates
>LSP. You will not be able to add a parameter typehint if the parent
>doesn't
>have one and you will not be able to change a typehint to a different
>class. I'm only proposing to support parameter contravariance to the
>limited degree we are capable of implementing currently.
I was replying to the idea that a "user may simply write code that handles various types in
function body". While a savvy user would only use that to implement contravariance, encouraging
it as a possibility risks people implementing covariance or other weirdness because they
haven't understood why it's a bad thing to do.
Full support for contravariance wouldn't stop that being possible, but it would give much
better examples for people to learn from.
Regards,
--
Rowan Collins
[IMSoP]