On Mon, Jan 6, 2020, at 5:16 AM, Nikita Popov wrote:
> Others have already explained why constructors are exempted from LSP
> checks, so let me reply to your other point...
>
> I believe that your example should indeed be legal in general and created a
> PR to fix this: https://github.com/php/php-src/pull/5059
>
> With this change, the variadic argument can replace any number of
> non-variadic arguments, as long as it is compatible with them, where
> compatibility is, as usual, determined based on type contravariance, as
> well as reference passing invariance. Effectively this means that
> function(...$args) is compatible with all signatures that do not involve
> reference passing.
>
> Does anyone see any soundness issues with this change?
>
> Nikita
Nifty! Since `func(...$args)` is already a universal caller, that gives us a
symmetrical way to defer calls, either to a parent or to a delegated method on
a wrapped object. So that means one can implement a pass-through class where
most of the methods are:
class Wrapper implements Thing {
public function thing(...$args) { $this->wrapped->thing(...$args); }
}
The symmetry appeals to me, even if it means types get caught only at the lower
level.
One possible question; would this mean bypassing type checks if not delegating?
Viz:
interface Foo {
public function bar(Foo, $f, Baz $b, Beep $e);
}
class Impl implements Foo {
public function bar(...$args) { ... }
}
$i = new Impl();
// Will this still report a type error, and if so, where/how?
// If not, does that become a back-door way to dodge an interface? Is that
good?
$i->bar('a', 'b', 'c');
--Larry Garfield
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php