Hey Rowan,

On Mon, Mar 2, 2020 at 3:39 PM Rowan Tommins <rowan.coll...@gmail.com>
wrote:

> Hi Marco,
>
> On Mon, 2 Mar 2020 at 14:00, Marco Pivetta <ocram...@gmail.com> wrote:
>
> >
> > Overall against the RFC: `++` and `--` (prefix and suffix) are supposed
> to
> > be used with numeric values, not with other types, as that makes
> everything
> > only more confusing.
> >
>
>
> While I'm generally sympathetic to that principle, it could also be said of
> the + and - operators, which currently silently handle both nulls and
> booleans. I would be open to changing *all* arithmetic behaviour,
> particularly on booleans, but don't think a vague ambition for that
> justifies inconsistent behaviour between different arithmetic operators.
>

Yes, I'm indeed not suggesting to change them: my comment is explicitly
about turning the BC break (in this RFC) into an useful and *loud* BC break.


> > Code written (intentionally) to use `++` and `--` against non-numeric
> > values should **NOT** pass a code review, and I am sorry for those that
> > have to maintain it if that happens.
> >
>
>
> I think you're taking simplified examples too literally here, and assuming
> that all affected code would be obvious at a glance.
>
> Take for instance this innocent-looking patch:
>
>   function foo($bar) {
> -     $bar -= 1;
> +    $bar--;
>       // more code here
>   }
>
> With the current behaviour, any inadvertent calls to the function passing
> null, true, false, or an array will change behaviour when this patch is
> merged. In particular, the variable $bar would previously have been
> guaranteed to be an integer, and will now retain the original type passed
> in.
>
> I completely agree that such code has a bug, but the difference in
> behaviour is still a massive WTF.
>

The code in the above example cannot be accepted without an `int` type
declaration, or an `(int)` cast (or similar number) applied before the
first arithmetic happens.

For older code that needs to respect BC due to LSP, a docblock type
declaration would suffice.

The code above is NOT going to pass a code review.

The asymmetry of ++ and -- is even more confusing. Consider this patch:
>
>   function repeatThing($extraTimes) {
> -      for ( $i = 0; $i <= $extraTimes ; $i ++ ) {
> +     for ( $i =  $extraTimes ; $i >= 0; $i -- ) {
>            doThing();
>        }
>   }
>
> Again, this looks like a safe change - but if passed a value of NULL, the
> old code will call doThing() once, and the new code will enter an infinite
> loop.
>

Same as above: types are not optional, and `$extraTimes` is not usable in
its form.

This code cannot pass a code review either.



>
>
> > Changing the current behavior, regardless in which way, is a BC break:
> > might as well make the BC break useful:
> >
> > RFC Proposal: `$a = null; $a--; $a === -1`. Let's make this an explicit
> > TypeError instead.
> > RFC Proposal: `$a = null; --$a; $a === -1`. Let's make this an explicit
> > TypeError instead.
> >
>
>
> And what about  `$a = null; $a++;` /  `$a = null; ++$a;`, which currently
> has behaviour consistent with other arithmetic operations (in particular,
> is identical to $a+=1) and this RFC does not propose to change?
>

Leave unchanged. If a BC break is to be introduced, make it go with a bang
(throw error)

If we change the ++ case to throw a TypeError, would we also change null+1
> to throw one? And would we then also examine all the other operators and
> utility functions which silently coerce null to zero or an empty string?
>

Can also not change it: I'd throw an error, if I were to propose it, but
the BC break must bring active value.

Right now, psalm & phpstan catch these, luckily.


Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

Reply via email to