> 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 <m...@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 <aidantwo...@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.brzuchal...@gmail.com> wrote:
>>
>>> 12.07.2017 15:35 "Mark Shust" <m...@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 <aidantwo...@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 <m...@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 <aidantwo...@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 <m...@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.coll...@gmail.com>
>>> > >>>> wrote:
>>> > >>>>
>>> > >>>> > On 11 July 2017 16:02:18 BST, Mark Shust <m...@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:
>>> > >>>> > >
>>> > >>>> > >
>>> > >>>> > ><?php
>>> > >>>> > >
>>> > >>>> > >$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]
>>> > >>>> >
>>> > >>>>
>>> > >>>
>>> > >>>
>>> > >
>>>
>>>
>>

Reply via email to