> Am 04.06.2016 um 13:45 schrieb Niklas Keller <m...@kelunik.com>: > > Bob Weinand <bobw...@hotmail.com <mailto:bobw...@hotmail.com>> schrieb am > Fr., 3. Juni 2016 23:31: > > > Am 3.6.2016 um 18:49 schrieb Larry Garfield <la...@garfieldtech.com > > <mailto:la...@garfieldtech.com>>: > > > > On 06/03/2016 10:16 AM, Jordi Boggiano wrote: > >> On 03/06/2016 15:58, Thomas Bley wrote: > >>> To me type declarations help to make my code easier and more consistent. > >>> Having multiple scalar types for a single function parameter is against > >>> this goal since I need extra logic to handle this. > >>> > >>> e.g. function foo(string | int | bool $bar) {} makes no sense in weak > >>> mode since string can already handle int, bool, float, etc. > >>> > >>> having different behavior between > >>> foo("42"); function foo(string $b) {echo gettype($b);} // string > >>> and > >>> foo("42"); function foo(string | int $b) {echo gettype($b);} // integer > >>> also makes no sense to me. > >>> > >>> Things like string|array are useful (e.g. str_replace) since we can cast > >>> the string easily to array and calling a string parameter with an array > >>> would give a fatal error. > >> > >> That is a useful case, and don't forget also return values, e.g. all the > >> XX|false-kind of return types it's also nice to have. > >> > >> I don't think for function arguments it's massively useful and I doubt > >> it'll get put everywhere, but it's nice to be able to express this when > >> you have to. > >> > >> Cheers > > > > For parameters, I really don't think | is going to be the common use case. > > (It should still be rational, but I don't expect to see it day to day.) > > InterfaceA & InterfaceB Is the more useful use case for parameters. | is, > > as noted, likely more useful on returns. (even though I would discourage > > their use in most cases for reasons I won't go into here). > > > > --Larry Garfield > > > It won’t and it should not be *common*. But there are legit uses cases: > > https://github.com/amphp/aerys/blob/2a4d626fb1b8b8ac9d91711085c04eaabdec7768/lib/Host.php#L87 > > <https://github.com/amphp/aerys/blob/2a4d626fb1b8b8ac9d91711085c04eaabdec7768/lib/Host.php#L87> > > <https://github.com/amphp/aerys/blob/2a4d626fb1b8b8ac9d91711085c04eaabdec7768/lib/Host.php#L87 > > <https://github.com/amphp/aerys/blob/2a4d626fb1b8b8ac9d91711085c04eaabdec7768/lib/Host.php#L87>> > > This concrete example shows that a class may implement multiple concrete > interfaces which all get the same/similar behavior locally. [And somewhere > else the code checks for each element in the array what classes it implements > and marks them appropriately.] > Sure, you could have ->addMiddleware($foo)->addRequest($foo) … or just a > single ->add($foo). It’s maybe not the most pure API, but the most practical > one. > > But I agree, I myself would discourage usage of union types in most cases > too; but there *are* legitimate cases which shall be also properly typable. > Thus we need it. > > Bob > > I don't see where the massively added complexity justifies the very few edge > cases. That 1% can still be checked manually.
Massive is a nice hyperbole here... Sure, you can check it manually… but why not just always check it manually then? You then loose possibilities to reflect on it, have static analysis rely on code only [currently you always have to check docblocks when it's not declared; definitely not an option for e.g. Optimizer], and a single signature is generally easier to parse for a human. Also, I don't believe it's the languages task to put arbitrary limitations on this. If a library does this, that's the libraries problem. But a language should not do that and try to support full typing. We've decided to make PHP (opt-in) typed on function boundaries (and eventually soon on property storage boundaries), so we should also finish what we committed to instead of putting something half-arsed forward. > For Aerys\Host it could also be solved with an interface that just doesn't > have any methods. With the disadvantage of callable not being in the same > signature anymore. As you say, disadvantage of callable. Also, it requires you to inverse responsibilities. You'd have to specify a common super-interface on every single fundamentally unrelated interface (which are only indirectly related by the fact that they receive common handling in a single place). That's a clear anti-pattern. Additionally, this is only possible if you are actually in control on these classes and can change them. If you pull them from a library, no chance. Bob