Re: [PHP-DEV] array coalesce operator concept

  99857
July 12, 2017 15:26 michal.brzuchalski@gmail.com (=?UTF-8?Q?Micha=C5=82_Brzuchalski?=)
12.07.2017 15:35 "Mark Shust" <mark@shust.com> napisał(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 around 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 debuging very hard and leads to frustration.
> > Cheers, > Mark > > On Wed, Jul 12, 2017 at 4:22 AM Aidan Woods <aidantwoods@gmail.com> 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 remaining 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 would 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 errors > > generated in using a type not compatible with being iterated over in a > > `foreach` loop, and not just if the type is not array). > > > > Kind regards, > > Aidan > > > > On 12 July 2017 at 02:50, Mark Shust <mark@shust.com> wrote: > > > >> Aidan, > >> > >> Fantastic suggestion (@as) -- that is really the succinctness I was > >> 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 <aidantwoods@gmail.com> > >> 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 <mark@shust.com> 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 <mark@shust.com> wrote: > >>>> > >For a syntactic > >>>> > >sugar/improvement, this can be shorthand for executing the loop > >>>> instead > >>>> > >of > >>>> > >wrapping the block within an is_array check: > >>>> > > > >>>> > > > >>>> > > >>>> > > > >>>> > >$foo = "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 somehow > >>>> suggests > >>>> > these rules. The "??" is too much like the null coalesce, which 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] > >>>> > > >>>> > >>> > >>> > >
  99859
July 12, 2017 16:18 aidantwoods@gmail.com (Aidan Woods)
> 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 to 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 behaviour (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 too: 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ł Brzuchalski brzuchalski@gmail..com> wrote:
> 12.07.2017 15:35 "Mark Shust" <mark@shust.com> napisał(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 around 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 debuging very hard > and leads to frustration. > > > > > Cheers, > > Mark > > > > On Wed, Jul 12, 2017 at 4:22 AM Aidan Woods <aidantwoods@gmail.com> > 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 remaining > 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 would > 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 errors > > > generated in using a type not compatible with being iterated over in a > > > `foreach` loop, and not just if the type is not array). > > > > > > Kind regards, > > > Aidan > > > > > > On 12 July 2017 at 02:50, Mark Shust <mark@shust.com> wrote: > > > > > >> Aidan, > > >> > > >> Fantastic suggestion (@as) -- that is really the succinctness I was > > >> 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 <aidantwoods@gmail.com> > > >> 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 <mark@shust.com> 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 <mark@shust.com> wrote: > > >>>> > >For a syntactic > > >>>> > >sugar/improvement, this can be shorthand for executing the loop > > >>>> instead > > >>>> > >of > > >>>> > >wrapping the block within an is_array check: > > >>>> > > > > >>>> > > > > >>>> > > > >>>> > > > > >>>> > >$foo = "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 somehow > > >>>> suggests > > >>>> > these rules. The "??" is too much like the null coalesce, which > 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] > > >>>> > > > >>>> > > >>> > > >>> > > > > >
  99860
July 12, 2017 17:25 mark@shust.com (Mark Shust)
I agree, error suppression is generally ugly/nasty behavior that is a hack
to the language. I also agree that if it's there now, @as is a pretty good
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 <aidantwoods@gmail.com> 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 to > 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 behaviour > (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 too: > 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ł Brzuchalski brzuchalski@gmail.com > > wrote: > >> 12.07.2017 15:35 "Mark Shust" <mark@shust.com> napisał(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 around 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 debuging very hard >> and leads to frustration. >> >> > >> > Cheers, >> > Mark >> > >> > On Wed, Jul 12, 2017 at 4:22 AM Aidan Woods <aidantwoods@gmail.com> >> 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 remaining >> 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 would >> 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 errors >> > > generated in using a type not compatible with being iterated over in a >> > > `foreach` loop, and not just if the type is not array). >> > > >> > > Kind regards, >> > > Aidan >> > > >> > > On 12 July 2017 at 02:50, Mark Shust <mark@shust.com> wrote: >> > > >> > >> Aidan, >> > >> >> > >> Fantastic suggestion (@as) -- that is really the succinctness I was >> > >> 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 <aidantwoods@gmail.com> >> > >> 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 <mark@shust.com> 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 <mark@shust.com> wrote: >> > >>>> > >For a syntactic >> > >>>> > >sugar/improvement, this can be shorthand for executing the loop >> > >>>> instead >> > >>>> > >of >> > >>>> > >wrapping the block within an is_array check: >> > >>>> > > >> > >>>> > > >> > >>>> > >> > >>>> > > >> > >>>> > >$foo = "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 somehow >> > >>>> suggests >> > >>>> > these rules. The "??" is too much like the null coalesce, which >> 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] >> > >>>> > >> > >>>> >> > >>> >> > >>> >> > > >> >> >
  99861
July 12, 2017 17:43 aidantwoods@gmail.com (Aidan Woods)
> 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 => value pairs for all publically accessible properties if the object hasn't defined its own way of being traversable. e.g. ``` $O = new class() { private $a = '1'; protected $b = '2'; public $c = '3'; }; foreach ($O as $k => $v) { echo "$k: $v"; } ``` Will output: ``` c: 3 ``` Kind regards, Aidan On 12 July 2017 at 18:25, Mark Shust <mark@shust.com> wrote:
> I agree, error suppression is generally ugly/nasty behavior that is a hack > to the language. I also agree that if it's there now, @as is a pretty good > 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 <aidantwoods@gmail.com> > 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 to >> 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 behaviour >> (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 too: >> 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ł Brzuchalski < >> michal.brzuchalski@gmail.com> wrote: >> >>> 12.07.2017 15:35 "Mark Shust" <mark@shust.com> napisał(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 around >>> 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 debuging >>> very hard and leads to frustration. >>> >>> > >>> > Cheers, >>> > Mark >>> > >>> > On Wed, Jul 12, 2017 at 4:22 AM Aidan Woods <aidantwoods@gmail.com> >>> 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 remaining >>> 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 would >>> 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 errors >>> > > generated in using a type not compatible with being iterated over in >>> a >>> > > `foreach` loop, and not just if the type is not array). >>> > > >>> > > Kind regards, >>> > > Aidan >>> > > >>> > > On 12 July 2017 at 02:50, Mark Shust <mark@shust.com> wrote: >>> > > >>> > >> Aidan, >>> > >> >>> > >> Fantastic suggestion (@as) -- that is really the succinctness I was >>> > >> 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 <aidantwoods@gmail.com> >>> > >> 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 <mark@shust.com> 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 <mark@shust.com> >>> wrote: >>> > >>>> > >For a syntactic >>> > >>>> > >sugar/improvement, this can be shorthand for executing the loop >>> > >>>> instead >>> > >>>> > >of >>> > >>>> > >wrapping the block within an is_array check: >>> > >>>> > > >>> > >>>> > > >>> > >>>> > >>> > >>>> > > >>> > >>>> > >$foo = "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 somehow >>> > >>>> suggests >>> > >>>> > these rules. The "??" is too much like the null coalesce, which >>> 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] >>> > >>>> > >>> > >>>> >>> > >>> >>> > >>> >>> > > >>> >>> >>
  99865
July 12, 2017 20:14 me@kelunik.com (Niklas Keller)
2017-07-12 17:26 GMT+02:00 Michał Brzuchalski brzuchalski@gmail.com>
:

> 12.07.2017 15:35 "Mark Shust" <mark@shust.com> napisał(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 around 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 debuging very hard > and leads to frustration.
You have to update a whole lot of APIs before you can do that. There are many things where it's better to ignore the warning and check the return value and throw an exception if something is wrong. Regards, Niklas
  99867
July 13, 2017 07:01 michal.brzuchalski@gmail.com (=?UTF-8?Q?Micha=C5=82_Brzuchalski?=)
2017-07-12 22:14 GMT+02:00 Niklas Keller <me@kelunik.com>:

> 2017-07-12 17:26 GMT+02:00 Michał Brzuchalski < > michal.brzuchalski@gmail.com>: > >> 12.07.2017 15:35 "Mark Shust" <mark@shust.com> napisał(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 around 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 debuging very >> hard >> and leads to frustration. > > > You have to update a whole lot of APIs before you can do that. There are > many things where it's better to ignore the warning and check the return > value and throw an exception if something is wrong. > > Regards, Niklas > > Hi Niklas,
could you name few of them? My ideal vision is catching thrown exceptions instead of suppressing errors.. BTW it would unlock '@' for future features like use for annotations/attributes. Regards, -- Michał Brzuchalski
  99868
July 13, 2017 07:35 me@kelunik.com (Niklas Keller)
> > 2017-07-12 22:14 GMT+02:00 Niklas Keller <me@kelunik.com>: > > > 2017-07-12 17:26 GMT+02:00 Michał Brzuchalski < > > michal.brzuchalski@gmail.com>: > > > >> 12.07.2017 15:35 "Mark Shust" <mark@shust.com> napisał(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 > around 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 debuging very > >> hard > >> and leads to frustration. > > > > > > You have to update a whole lot of APIs before you can do that. There are > > many things where it's better to ignore the warning and check the return > > value and throw an exception if something is wrong. > > > > Regards, Niklas > > > > > Hi Niklas, > > could you name few of them? >
Sure. fwrite and many other stream functions - https://github.com/amphp/byte-stream/blob/47775086376fd2f82fc70b3862aa82e64a5ea667/lib/ResourceOutputStream.php#L67 openssl_x509_read - https://github.com/kelunik/certificate/blob/524fa432ed1b5f50efbe7749f3c19e28a9866bc7/lib/Certificate.php#L13
> My ideal vision is catching thrown exceptions instead of suppressing > errors. > BTW it would unlock '@' for future features like use for > annotations/attributes. >
We would have to make it a compile time error for quite a long time before we could reuse any operators. Regards, Niklas