Re: Inconsistent class behavior and undocumented(? ) BC change

From: Date: Mon, 06 Jan 2020 18:17:44 +0000
Subject: Re: Inconsistent class behavior and undocumented(? ) BC change
References: 1 2  Groups: php.internals 
Request: Send a blank email to internals+get-108009@lists.php.net to get a copy of this message
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

« previous php.internals (#108009) next »