Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:92349 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 84756 invoked from network); 15 Apr 2016 18:13:09 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 15 Apr 2016 18:13:09 -0000 Authentication-Results: pb1.pair.com smtp.mail=larry@garfieldtech.com; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=larry@garfieldtech.com; sender-id=unknown Received-SPF: error (pb1.pair.com: domain garfieldtech.com from 66.111.4.26 cause and error) X-PHP-List-Original-Sender: larry@garfieldtech.com X-Host-Fingerprint: 66.111.4.26 out2-smtp.messagingengine.com Received: from [66.111.4.26] ([66.111.4.26:59574] helo=out2-smtp.messagingengine.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 21/99-29891-43F21175 for ; Fri, 15 Apr 2016 14:13:09 -0400 Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.nyi.internal (Postfix) with ESMTP id 53D63201F9 for ; Fri, 15 Apr 2016 14:13:06 -0400 (EDT) Received: from frontend1 ([10.202.2.160]) by compute1.internal (MEProxy); Fri, 15 Apr 2016 14:13:06 -0400 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= messagingengine.com; h=content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-sasl-enc:x-sasl-enc; s=smtpout; bh=JPtKioWQSX+kaQ6 apU75oCdmUy8=; b=R4/OAdJwmswivJEuYaYQHlVVyYD8lrvvfcTp8GrNUw6XALi 68xzLVVs6V7ezfILWywKq9xBXUtzccU/VOwYeta6BqF2GuvQ9dExglUNa5SbQJ4h IRavk7saUZm6vLFDvlr5y3r54O23qEdGDffFXwjFGaqD8IvixX/xyziVrfyQ= X-Sasl-enc: JN7HTiL73FH/DAUlOSOGz595z8Tir9vHXOew5XBmx/4g 1460743986 Received: from Crells-MacBook-Pro.local (unknown [63.250.249.138]) by mail.messagingengine.com (Postfix) with ESMTPA id 17EABC00012 for ; Fri, 15 Apr 2016 14:13:06 -0400 (EDT) To: internals@lists.php.net References: <570E99AC.3090804@fleshgrinder.com> <570EA5EB.8090501@fleshgrinder.com> <570EAB0D.6080706@gmail.com> <570EB67E.8010908@garfieldtech.com> <5B147E88-CC0A-4CBC-A49D-C7FE3BF557C0@zend.com> <6F.C3.12455.94C5F075@pb1.pair.com> <20160414094440.GF19347@phcomp.co.uk> <570FD94F.90703@fleshgrinder.com> <570FE8A9.4020809@gmail.com> <20.53.29891.17401175@pb1.pair.com> <57110BCD.5030009@garfieldtech.com> <571124C2.9040606@gmx.de> Message-ID: <57112F31.8070209@garfieldtech.com> Date: Fri, 15 Apr 2016 13:13:05 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:38.0) Gecko/20100101 Thunderbird/38.0.1 MIME-Version: 1.0 In-Reply-To: <571124C2.9040606@gmx.de> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] Re: Improving PHP's type system From: larry@garfieldtech.com (Larry Garfield) On 4/15/16 12:28 PM, Christoph Becker wrote: > On 15.04.2016 at 17:42, Larry Garfield wrote: > >> I think there's 2 general use cases for union types that would be "good >> things", which are different for & and |, and have very little... >> intersection. (*yaaaaaaa!*) >> >> The OR case is for cases where the language doesn't support a unified >> case at all. The most obvious example here is array|Traversable. If I >> want "a thing I can foreach()", then PHP right now has no way of saying >> that syntactically. You have to type on array, or Traversable, or not >> type at all. array|Traversable is what you really want, > It is not what I would want, though. > >> because those >> DO have an overlap (foreach-ablility), PHP is just incapable of >> representing that otherwise. > Maybe we should consider to accept an array as Traversable? Actually, I > wonder why that's not already the case. It's been asked a few dozen times, but never went anywhere. Mainly, I think, Traversable implies object, which implies certain passing semantics. Array is a primitive, so has different passing semantics. There's probably other subtle issues like that which have kept the engine-gurus from trying to make it work. My assumption here is "if it were that easy someone would have done it already". (Which may not be an entirely accurate assumption, but seems logical given how often it's been asked for.) >> A similar example would be callable|SomeInterface. An interface can >> specify a signature for __invoke(), which gives you documentation on the >> format that is expected for a callable. However, you can't strictly >> enforce that because then you don't allow for a function or closure that >> fits the same method signature. That means you have to leave it >> untyped. This, I argue, would be better *and* reasonably type safe: >> >> interface MiddlewareInterface { >> function __invoke(RequestInterface $req, ResponseInterface $res); >> } >> >> function middleware_builder(callable|MiddlewareInterface $m) { >> // ... >> } >> >> As that self-documents that MiddlewareInterface is the callable >> signature we need, but still allows an arbitrary callable to be passed. >> It's not perfect (I could pass a string of a function name that doesn't >> have that interface and it would still explode), but it is an >> improvement over middleware_builder() having no type specification at >> all, as is the case today. > In my opinion, `callable' is to weak a type hint to be really useful, > and it would be better if we would improve that (generics come to mind). > Then you wouldn't need MiddlewareInterface at all and be not afraid > that somebody passes in an incompatible function. One of the key language design points I think we should be keeping in mind is that, on the whole, single-purpose features are inferior to more general capabilities that implicitly grant the same capability. Thus, I'd argue that the Property Accessor RFC is superior to adding a half dozen keywords to object properties (because they implicitly grant all of those same capabilities with less mental overhead and fewer keywords) and Union Types are superior to special casing array|Traversable or array|ArrayAccess, etc. (Making array a for-reals honest to goodness object would be good too, but that's a considerably larger issue.) Union Types side-step the need for more special cases, as they can be handled in user-space code. It's not a perfect fix, but the perfect fix involves very BC-unfriendly changes to PHP (making everything an object, Go-style type aliases, etc.) that are not likely to happen any time soon. Related: What would union types mean for the typed property RFC? Would this be a good solution or an evil solution: class Foo { public array|Traversable $arr; public Foo&Bar $c; } -- --Larry Garfield