Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:99861 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 82978 invoked from network); 12 Jul 2017 17:43:40 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 12 Jul 2017 17:43:40 -0000 Authentication-Results: pb1.pair.com smtp.mail=aidantwoods@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=aidantwoods@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 74.125.82.42 as permitted sender) X-PHP-List-Original-Sender: aidantwoods@gmail.com X-Host-Fingerprint: 74.125.82.42 mail-wm0-f42.google.com Received: from [74.125.82.42] ([74.125.82.42:36331] helo=mail-wm0-f42.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 1C/D8-01782-BCF56695 for ; Wed, 12 Jul 2017 13:43:40 -0400 Received: by mail-wm0-f42.google.com with SMTP id 62so1376773wmw.1 for ; Wed, 12 Jul 2017 10:43:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=9dtwjpb/BSBF1s/nYoEbXT1hr37svN/0DKsOEgObNhg=; b=n5Wovsjhnhl419Ik1DK3KRFZW5RIqmFqvGfx1vr00GXxVtL2HvxqUcqSvhVvIKamXm EJdW8I1EIRaX97vDKED1i4+/vrEXMYb00H+CZagu7hydeNtTjR4YDg1VDkBR/vUhd17k jDTwKghRVGx/bJlWjBnPrvDRm5QwWVU8XH22hsJdatFIPn+3rx9jk29VMTncUZU5tFHC D2+ipoWr6gDE824vf650sal4BB2jPeYLsqgoFVN3yUg0afj31L8tUTkoEuv5qMzeEihA eYY5QK/hQ3G2CwnoCfxZVd+ibib1svK+aW8MLDtwCylY2lKj1yVNTqKTCt8MKhP1iSxm dZPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=9dtwjpb/BSBF1s/nYoEbXT1hr37svN/0DKsOEgObNhg=; b=VJUt2uvfribI1R7yzZpgtYWkwJEHrA1aaIK8H39q0czER3vv8J1gn+OL6jlvKV6Img Yn9+0oNDgD6Q3vbgLZCEWFGiInhoY8IxrBQta6WCcYUSlZtmTdmRmWIQaMPn86RvZ/m9 sySJQDPcLmq8FPuXUBZi/XjrXmZZ7LWFuxK4q1K2694pfKRnzc/mJsY+LpaiPnQNRzm/ 2hIBFvVZaK8PV7cjjR8VlzCe47jRarFVA7sSKL7AW5/NnbQDEsliUdhX7ZbQWzfsE//I Eqouu3VkzPde+kOZHQjxIo/go/O/qNrqU7T93A8GgVvlCyO0eGSmaW/VNTWfWG3zLdnU 7WKg== X-Gm-Message-State: AIVw111acEGnSdF8IFBxdS00CPNfAwEiFPvT/sN5E/MRiA5/G6BrRW++ +S2vTvAde/nptHUEb/mu4hhxmJpQrZ5mXmPPiw== X-Received: by 10.28.51.212 with SMTP id z203mr3586182wmz.103.1499881416682; Wed, 12 Jul 2017 10:43:36 -0700 (PDT) MIME-Version: 1.0 Received: by 10.223.161.26 with HTTP; Wed, 12 Jul 2017 10:43:35 -0700 (PDT) In-Reply-To: References: Date: Wed, 12 Jul 2017 18:43:35 +0100 Message-ID: To: Mark Shust Cc: =?UTF-8?Q?Micha=C5=82_Brzuchalski?= , Rowan Collins , PHP Internals List Content-Type: multipart/alternative; boundary="001a114421d60bf5fb0554225b4e" Subject: Re: [PHP-DEV] array coalesce operator concept From: aidantwoods@gmail.com (Aidan Woods) --001a114421d60bf5fb0554225b4e Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable > That said, another possibility I thought of is automatically converting whatever is passed into a foreach loop to > be cast into an iterable/array for the duration of the loop. I'm wondering what opinions would be on the cons of > going this route. Given php's weak typing and someone's desire to execute a foreach on _something_, I think > this alternate method might be a good option. PHP kinda already does this. It won't do it for all types (e.g. each string of a letter), but it'll implicitly cast any object to property =3D> value pairs for all publically accessible propertie= s if the object hasn't defined its own way of being traversable. e.g. ``` $O =3D new class() { private $a =3D '1'; protected $b =3D '2'; public $c =3D '3'; }; foreach ($O as $k =3D> $v) { echo "$k: $v"; } ``` Will output: ``` c: 3 ``` Kind regards, Aidan On 12 July 2017 at 18:25, Mark Shust wrote: > I agree, error suppression is generally ugly/nasty behavior that is a hac= k > to the language. I also agree that if it's there now, @as is a pretty goo= d > use for it. > > That said, another possibility I thought of is automatically converting > whatever is passed into a foreach loop to be cast into an iterable/array > for the duration of the loop. I'm wondering what opinions would be on the > cons of going this route. Given php's weak typing and someone's desire to > execute a foreach on _something_, I think this alternate method might be = a > good option. > > Mark > > > On Wed, Jul 12, 2017 at 12:18 PM Aidan Woods > wrote: > >> > IMHO the whole error supression and its operator should be deprecated >> and removed from language. >> > Supressing errors is just hiding problems because someone didn't want >> to solve it. Supressing errors >> > makes debuging very hard and leads to frustration. >> >> I can concur with disliking the error suppression operator, and in >> general silent failures. This is why we >> have linting CI checkers though ;-) Tbh, I also dislike silent type >> "juggling" for the same reason. But >> those are my opinions, and they don't get on with everyone. >> >> Deprecation of the operator is probably a different discussion. Though t= o >> say a few words on it: if >> presented with no other option, I'd rather someone suppress an error in = a >> controlled single-use >> manner, than changing the global error reporting setting somewhere in >> their code to do the same >> thing. >> Notwithstanding my preference on error suppression method, I'd >> still prefer it avoided if at all possible, >> though again, very much IMO. >> >> Regardless of personal opinion on actually using the operator, would you >> not rather it were used in all >> cases of error suppression? >> 'tis to say, if we are going to introduce new error suppression behaviou= r >> (which is what the proposal >> here does), should it not be consistent with existing language features? >> >> Given that the error suppression operator is a feature already in the >> language, I think that it makes >> sense to use it to facilitate this use case of "silently skip the loop >> if it errors", as opposed to introducing >> a new operator to do it. >> >> I think it makes sense to force its use to be as targeted as possible to= o: >> Placing the `@` on `as` is the most targeted placement for catching the >> failure we're talking about (failing to >> be able to iterate over something), as opposed to something like >> `@foreach` which could feasibly mean >> anything failing in the entire loop block. >> >> If we're going to introduce this behaviour, let's get it right ;-) (even >> if we don't like it ourselves) >> >> Kind regards, >> Aidan >> >> On 12 July 2017 at 16:26, Micha=C5=82 Brzuchalski < >> michal.brzuchalski@gmail.com> wrote: >> >>> 12.07.2017 15:35 "Mark Shust" napisa=C5=82(a): >>> > >>> > Hi Aidan, >>> > >>> > I think you are correct on all points. The initial emit is just a >>> warning, >>> > so I think a suppressor will work just fine, since it does just pass >>> over >>> > the foreach if a traversable isn't passed in. >>> > >>> > I could see this being helpful as it makes wrapping an if block aroun= d >>> a >>> > foreach not needed anymore (and in turn indenting the foreach another >>> > level), replacing it with just a single character. I also think for >>> those >>> > that use linting tools and flag error suppressions, that an @as >>> definition >>> > could be easily ignored from such a linter. I develop with warnings >>> on, and >>> > see error suppressions as a sort of code smell, however I think the @= as >>> > definition could be really useful. >>> >>> IMHO the whole error supression and its operator should be deprecated >>> and removed from language. Supressing errors is just hiding problems >>> because someone didn't want to solve it. Supressing errors makes debugi= ng >>> very hard and leads to frustration. >>> >>> > >>> > Cheers, >>> > Mark >>> > >>> > On Wed, Jul 12, 2017 at 4:22 AM Aidan Woods >>> wrote: >>> > >>> > > In theory you'd only *need* it be considered a suppressor? PHP >>> already >>> >>> > > exhibits the skipping behaviour (it only emits a warning for the >>> wrong type >>> > > used in `foreach`, skips the loop, and then continues with remainin= g >>> code). >>> > > >>> > > No harm in/there is probably value in, making that skipping intent >>> > > explicit in a RFC though, but in terms of a patch, the warning woul= d >>> only >>> > > need be suppressed as far as I can tell? >>> > > >>> > > Another thing I meant to mention -- this should not only be useful >>> for >>> > > arrays, but for any `Traversable` too (i.e. it should suppress erro= rs >>> > > generated in using a type not compatible with being iterated over i= n >>> a >>> > > `foreach` loop, and not just if the type is not array). >>> > > >>> > > Kind regards, >>> > > Aidan >>> > > >>> > > On 12 July 2017 at 02:50, Mark Shust wrote: >>> > > >>> > >> Aidan, >>> > >> >>> > >> Fantastic suggestion (@as) -- that is really the succinctness I wa= s >>> > >> initially looking for, and I think the intention makes a lot of >>> sense. My >>> > >> only concern/issue would be to make sure that isn't considered a >>> > >> 'suppressor' -- but it's actual intent is to skip the execution of >>> the >>> > >> foreach to prevent the error/loop from occurring (rather than just >>> > >> suppressing an error). >>> > >> >>> > >> Cheers, >>> > >> Mark >>> > >> >>> > >> >>> > >> On Tue, Jul 11, 2017 at 4:05 PM Aidan Woods >>> > >> wrote: >>> > >> >>> > >>> If you were willing to accept >>> > >>> >>> > >>> ``` >>> > >>> foreach ($foo as $bar) if (is_array) { >>> > >>> ... >>> > >>> } >>> > >>> ``` >>> > >>> >>> > >>> as a solution, then you might as well use >>> > >>> >>> > >>> ``` >>> > >>> if (is_array($foo)) foreach ($foo as $bar) { >>> > >>> ... >>> > >>> } >>> > >>> ``` >>> > >>> >>> > >>> I wonder if this could be better achieved by expanding what the >>> error >>> > >>> suppression operator `@` can do? This entire behaviour seems more >>> like an >>> > >>> error suppression action on `foreach` to me, otherwise should we >>> consider >>> > >>> coalescing operators for other types/creating a more generic one? >>> > >>> >>> > >>> Going back to the error suppression operator: >>> > >>> >>> > >>> e.g. perhaps >>> > >>> >>> > >>> ``` >>> > >>> foreach ($foo @as $bar) { >>> > >>> ... >>> > >>> } >>> > >>> ``` >>> > >>> >>> > >>> could prevent skip past execution of the entire foreach block if >>> there >>> > >>> is an error using $foo as an array. So might make most sense to >>> place the >>> > >>> `@` on `as`, IMO, but I guess arguments could be made to place it >>> like >>> > >>> `@foreach ($foo as $bar)` or `foreach @($foo as $bar)`. >>> > >>> >>> > >>> >>> > >>> Regards, >>> > >>> Aidan >>> > >>> >>> > >>> On 11 July 2017 at 20:06, Mark Shust wrote: >>> > >>> >>> > >>>> Thanks for the great feedback. >>> > >>>> >>> > >>>> Based on the last mindset on keyword syntax, this comes to mind, >>> > >>>> intended >>> > >>>> to be used similarly to the 'use' keyword when used within the >>> context >>> > >>>> of a >>> > >>>> closure: >>> > >>>> >>> > >>>> foreach ($foo as $bar) if (is_array) { >>> > >>>> ... >>> > >>>> } >>> > >>>> >>> > >>>> >>> > >>>> I don't think this is a vast improvement over wrapping this >>> within an >>> > >>>> is_array check, however it does avoid the additional >>> nest/wrapping. I >>> > >>>> was >>> > >>>> hoping for something that reads a bit more concisely or with a >>> bit more >>> > >>>> syntactical sugar than the above. I think this does read nicely >>> though. >>> > >>>> >>> > >>>> Cheers, >>> > >>>> Mark >>> > >>>> >>> > >>>> On Tue, Jul 11, 2017 at 1:50 PM Rowan Collins < >>> rowan.collins@gmail.com> >>> > >>>> wrote: >>> > >>>> >>> > >>>> > On 11 July 2017 16:02:18 BST, Mark Shust >>> wrote: >>> > >>>> > >For a syntactic >>> > >>>> > >sugar/improvement, this can be shorthand for executing the lo= op >>> > >>>> instead >>> > >>>> > >of >>> > >>>> > >wrapping the block within an is_array check: >>> > >>>> > > >>> > >>>> > > >>> > >>>> > >>> > >>>> > > >>> > >>>> > >$foo =3D "abc"; >>> > >>>> > > >>> > >>>> > >foreach (??$foo as $bar) { >>> > >>>> > > >>> > >>>> > > echo $bar; >>> > >>>> > > >>> > >>>> > >} >>> > >>>> > >>> > >>>> > Hi! >>> > >>>> > >>> > >>>> > I think there's definitely the start of a good idea here, but >>> the >>> > >>>> syntax >>> > >>>> > you suggest doesn't read quite right. As has been pointed out, >>> this >>> > >>>> differs >>> > >>>> > from existing features in two ways: >>> > >>>> > >>> > >>>> > - the special handling is for any non-iterable value, not just >>> null or >>> > >>>> > empty/falsey values, for which you could use $foo??[] and >>> $foo?:[] >>> > >>>> > respectively >>> > >>>> > - the handling is to skip the loop, not loop once assigning >>> $bar to >>> > >>>> the >>> > >>>> > scalar value, as would happen with (array)$foo >>> > >>>> > >>> > >>>> > The challenge, then, is to come up with some syntax that someh= ow >>> > >>>> suggests >>> > >>>> > these rules. The "??" is too much like the null coalesce, whic= h >>> would >>> > >>>> be >>> > >>>> > misleading. >>> > >>>> > >>> > >>>> > The only idea that immediately comes to mind is a keyword: >>> > >>>> > >>> > >>>> > foreach ifarray ($foo as $bar) { >>> > >>>> > >>> > >>>> > I can't say I'm that keen on that syntax, but maybe it will >>> inspire >>> > >>>> > someone else. >>> > >>>> > >>> > >>>> > Regards, >>> > >>>> > >>> > >>>> > -- >>> > >>>> > Rowan Collins >>> > >>>> > [IMSoP] >>> > >>>> > >>> > >>>> >>> > >>> >>> > >>> >>> > > >>> >>> >> --001a114421d60bf5fb0554225b4e--