Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:101036 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 41473 invoked from network); 3 Nov 2017 02:27:09 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 3 Nov 2017 02:27:09 -0000 X-Host-Fingerprint: 95.148.70.12 unknown Received: from [95.148.70.12] ([95.148.70.12:8641] helo=localhost.localdomain) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id DE/77-09857-AF3DBF95 for ; Thu, 02 Nov 2017 21:27:08 -0500 Message-ID: To: internals@lists.php.net References: <14.52.09857.F0B0BF95@pb1.pair.com> Date: Fri, 3 Nov 2017 02:27:02 +0000 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:49.0) Gecko/20100101 Firefox/49.0 SeaMonkey/2.46 MIME-Version: 1.0 In-Reply-To: <14.52.09857.F0B0BF95@pb1.pair.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Posted-By: 95.148.70.12 Subject: Re: [PHP-DEV] RFC - Array Of for PHP 7 From: ajf@ajf.me (Andrea Faulds) Hi, Mark Randall wrote: > On 01/11/2017 01:36, Andrea Faulds wrote: >> Thank you for bringing this up. The introduction of nullables means >> that the type[] syntax is problematic and should probably be avoided >> now. As you say, there is an issue of ambiguity as to whether it would >> be interpreted as (?int)[] or ?(int[]). > > That would be a shame, TypeName[] is a defacto standard already for PHP > docs (not to mention a absolute standard for many programming languages) > and if it can be made to work it would be one less piece of syntax. > > IMHO ?(int[]) would be the way to go staying with the current trend, Yes, it is a bit unfortunate to deviate from the docs. But array<> is also a familiar syntax, yet it's unambiguous and wouldn't require the new complication of parentheses. For that reason I don't find [] a compelling option. Syntax æsthetics are nice but in the end it's readability that matters. or > alternatively bite the bullet and specific both like we do in docblocs: > > function fn(null | int[] $x) { ... } > > Generics gives the less ambiguous option: > > function fn(?array $x) { ... } This makes things even more complicated. > > This would become a lot less of an issue if we had function overloading > in future *crosses fingers*. > >>> Our current infrastructure requires us to check every element of >>> the array for conformance. While undesirable I believe this can be >>> optimized away in the future if we care enough, and therefore not a >>> show-stopper. > > Which brings up perhaps a longer term point, does the language need an > inbuilt alternative to "array" that implements ArrayAccess and provides > for an "Operator array" that will allow it to be cast to an native array > just as __tostring does for objects that implement it. > > The benefit would be that type checking could be performed on > initialization and assignment, and with "operator array" it would be > transparent. > > The downside I see? Well, being a generic object it would not exhibit > traditional PHP copy-on-write behaviour, unless that was somehow baked > into the language as part of the class definition (in a similar manner > to "abstract" or "implements CopyOnWrite"). Why create an almost-array that works almost-everywhere when you can improve the actual array that works actually everywhere? > >> Something I've thought about but not gotten round to implementing is a >> typed array value. That is, you could write `$x = array(1, 2, >> 3);` and `$x` would contain a typed array that would enforce the types >> of values added to it. This feels like a cleaner solution, but it >> introduces a new issue: does an array type declaration require an >> array value, or will it implicitly cast from vanilla array? > > Would an "operator array" not solve this in the same manner that > __tostring does? Your proposed objects would not be usable everywhere an array is, because they're not arrays, and by converting to an array you lose the type info, so we still have to iterate over the whole thing to type check. This would be significantly less useful than an actually typed array. I can see some benefit to it, but I'm not sure it's worth the effort. > > I think once we have operator overloading (and supported by native > types) then we should be able to do the following: > > function fn(MyCollection $y) { ... } > > generic class MyCollection { > public function __construct(array $in) { > foreach ($in as $x) { > if (!($x typeof T1)) { > throw new InvalidArgumentException('...'); > } > } > } > } > > fn(['hello', 'world']); > > And the engine should be smart enough to create a new instance of > MyCollection with the defined constructor. I say overloading would > be necessary as several different constructors may be required. > > Equally: > > generic class SomeArray { > ... > public function __operator_array(): array { > return $this->privateInternalArray; > } > ... > } > > function fn(array $x) { ... } > fn(new SomeArray(1, 2, 3)); A problem here is that we'd need to implement generics! That's quite the complex task. I do like the idea of generics, but I don't really expect them to get implemented (let alone accepted) any time soon. Maybe if I suddenly decide to take all my yearly paid holiday at once and am unusually determined. But there are much nicer things to go on holiday for… > > Admittedly I do not know the PHP core with any degre of intimacy, but > from a language perspective I can't think of a better way than generics, > casting operators, and overloaded function constructors... > > ... and yes, that did include almost every major language wishlist item > in a single go. Chalk it up to me romancing my long lost love of C++. We all have our wishlist features. :) I think I share some of yours. Thanks for your reply. > >> Thanks. > > -- > Mark Randall -- Andrea Faulds https://ajf.me/