Welcome! Log In Create A New Profile

Advanced

[PHP-DEV] On arrays starting with a negative index

Posted by Pedro Magalhães 
Pedro Magalhães
[PHP-DEV] On arrays starting with a negative index
February 15, 2017 07:30PM
Hi internals,

I've prepared a PR (https://github.com/php/php-src/pull/2383) that would
change the current behavior of arrays when the first index is a negative
integer.

The main goal is to make the result of array_fill more in line with what
you would expect if the start_index is a negative integer. However, the
current (and historical) result is properly documented on the array_fill
page.

I would like to hear your feedback about this change and if you feel this
warrants an RFC.

Best regards,
Pedro Magalhães
Pedro Magalhães
[PHP-DEV] Re: On arrays starting with a negative index
March 01, 2017 09:50PM
On Wed, Feb 15, 2017 at 7:28 PM, Pedro Magalhães <[email protected]> wrote:

> Hi internals,
>
> I've prepared a PR (https://github.com/php/php-src/pull/2383) that would
> change the current behavior of arrays when the first index is a negative
> integer.
>
> The main goal is to make the result of array_fill more in line with what
> you would expect if the start_index is a negative integer. However, the
> current (and historical) result is properly documented on the array_fill
> page.
>
> I would like to hear your feedback about this change and if you feel this
> warrants an RFC.
>
> Best regards,
> Pedro Magalhães
>

Bump on this topic as I would like to hear some feedback.

As a clarification, the current implementation of the PR affects arrays in
general, not only array_fill. Any array that starts with a negative index
would continue from that index instead of 0. Meaning that [-2 => true,
true, true] would now return [-2 => true, -1 => true, 0 => true] instead of
[-2 => true, 0 => true, 1 => true].

Regards,
Pedro
Rowan Collins
Re: [PHP-DEV] Re: On arrays starting with a negative index
March 02, 2017 11:50PM
On 01/03/2017 20:46, Pedro Magalhães wrote:
> As a clarification, the current implementation of the PR affects arrays in
> general, not only array_fill. Any array that starts with a negative index
> would continue from that index instead of 0. Meaning that [-2 => true,
> true, true] would now return [-2 => true, -1 => true, 0 => true] instead of
> [-2 => true, 0 => true, 1 => true].

Hi Pedro,

Would other behaviour also be affected?

For instance:

$foo = [ -2 => true ];
$foo[] = true;
$foo[] = true;
var_dump($foo);

If so, this is a much wider BC break; if not, why not?

Currently, this is completely consistent: https://3v4l.org/hXAsf Indeed,
I would say this is the missing explanation of why array_fill works the
way it does.


Presumably, this is why there is a note on the manual page:

> See also theArrays http://php.net/manual/en/language.types.array.php section of
manual for a detailed explanation of negative keys.

Although as pointed out by Andrew Nester, this "detailed explanation"
doesn't actually seem to exist. This seems to be the closest we get:

> As mentioned above, if no key is specified, the maximum of the existing integer indices is taken, and the new key will be that
maximum value plus 1 (but at least 0). If no integer indices exist yet,
the key will be 0 (zero).

Hidden in that first rambling sentence is the key phrase "but at least
0"; and the second should really say "If no positive integer indices..."
[It shouldn't say "exist", either, because as the next paragraph
explains, it can actually be affected by keys that no longer exist;
which I'd never actually realised before!]

This deserves to be a full section rather than a note, and much more
clearly articulated. It might even make sense to split that page into
sub-pages in some way, but I'm drifting into a different discussion, for
a different list.


The point right now is that array_fill's behaviour is actually
consistent with the rest of the language, and while the value of that
behaviour is questionable, changing it now would be a major decision.


Regards,

--
Rowan Collins
[IMSoP]


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Pedro Magalhães
Re: [PHP-DEV] Re: On arrays starting with a negative index
March 03, 2017 12:20AM
Hi Rowan,

On Thu, Mar 2, 2017 at 11:39 PM, Rowan Collins <[email protected]>
wrote:

>
> Would other behaviour also be affected?
>
> For instance:
>
> $foo = [ -2 => true ];
> $foo[] = true;
> $foo[] = true;
> var_dump($foo);
>
> If so, this is a much wider BC break; if not, why not?
>

It would indeed. Internally, nNextFreeElement is initialized with 0 and
updates on larger values. In the PR (
https://github.com/php/php-src/pull/2383/files#diff-fd78a0a3f78ea28c6907f907f25b908eR798
) I'm allowing it to be set to a negative value if it is the first element.


> Currently, this is completely consistent: https://3v4l.org/hXAsf Indeed,
> I would say this is the missing explanation of why array_fill works the way
> it does.


With this PR all of your examples would behave consistently but with the
negative indexes.


> As mentioned above, if no key is specified, the maximum of the existing
>> integer indices is taken, and the new key will be that
>>
> maximum value plus 1 (but at least 0). If no integer indices exist yet,
> the key will be 0 (zero).
>

The "but at least 0" is exactly what this PR would change.


> The point right now is that array_fill's behaviour is actually consistent
> with the rest of the language, and while the value of that behaviour is
> questionable, changing it now would be a major decision.


I completely agree on the impact of this change. But I also believe that
this behaviour would be preferable.

Thank you for the feedback.

Regards,
Pedro
Rowan Collins
Re: [PHP-DEV] Re: On arrays starting with a negative index
March 04, 2017 05:20PM
Hi Pedro,

On 02/03/2017 23:10, Pedro Magalhães wrote:
>
> Would other behaviour also be affected?
>
> For instance:
>
> $foo = [ -2 => true ];
> $foo[] = true;
> $foo[] = true;
> var_dump($foo);
>
> If so, this is a much wider BC break; if not, why not?
>
>
> It would indeed. Internally, nNextFreeElement is initialized with 0
> and updates on larger values. In the PR
> (https://github.com/php/php-src/pull/2383/files#diff-fd78a0a3f78ea28c6907f907f25b908eR798) I'm
> allowing it to be set to a negative value if it is the first element.

I haven't built with the patch to check, but have you checked it behaves
correctly with other combinations? For instance [-10 => true, -5 =>
true, true] or ['string_key' => true, -10 => true, true]


> I completely agree on the impact of this change. But I also believe
> that this behaviour would be preferable.

I broadly agree that the proposed behaviour would be preferable in
itself. Unfortunately, in a language with 20 years of history, and
millions of lines of deployed code, we don't have the luxury of looking
at behaviour in isolation, we have to think about the consequences of
change as well as the end result.

Would you be willing to draft an RFC for this change? If you're not
familiar with the process, have a look at this:
https://blogs.oracle.com/opal/entry/the_mysterious_php_rfc_process

You'll need to make the case for the change, and try to consider all the
angles. For instance:

- Exactly what behaviour will change, and how? We already have three
different things that are affected, and there may well be others.
- What code might rely on the current behaviour? What kind of bugs might
such code exhibit if it's not updated after the change? How can users
write code that will work the same before and after the change?
- On the other side, what are the benefits of the change? What is the
harm caused by the current behaviour, e.g. potential for bugs or mistakes?

This may seem like a lot of work for such a simple patch, but the more
we discuss it, the clearer it becomes that this would be a significant
language change, so we need to make sure it's considered properly.

Regards,

--
Rowan Collins
[IMSoP]
Pedro Magalhães
Re: [PHP-DEV] Re: On arrays starting with a negative index
March 07, 2017 11:20PM
Hi Rowan,

On Sat, Mar 4, 2017 at 5:09 PM, Rowan Collins <[email protected]>
wrote:
>
> I haven't built with the patch to check, but have you checked it behaves
> correctly with other combinations? For instance [-10 => true, -5 => true,
> true] or ['string_key' => true, -10 => true, true]


The first example behaves how you would expect with this patch (third
element gets -4).
In the second example however, it would act the "old" way. Thanks for the
hint! I'm working on making it consistent in that case as well.

Would you be willing to draft an RFC for this change? If you're not
> familiar with the process, have a look at this:
> https://blogs.oracle.com/opal/entry/the_mysterious_php_rfc_process


Yes, I'm already familiar with it. It clearly seems to be the way forward
so I'll create a draft once I'm done with the implementation fixes/further
discussion.


> - Exactly what behaviour will change, and how? We already have three
> different things that are affected, and there may well be others.
>

If the first numeric index - n - of an array is negative (however that
array is created), the next element (however it is inserted) will not
default to 0, but will have the index n + 1.


> - What code might rely on the current behaviour? What kind of bugs might
> such code exhibit if it's not updated after the change? How can users write
> code that will work the same before and after the change?
>

I have a hard time coming up with a use case for it but basically, any code
relying on the defaulting to 0. Basically, the only safe way I see is that
if you don't set explicit keys, you probably shouldn't try to access array
elements by an explicit key.


> - On the other side, what are the benefits of the change? What is the harm
> caused by the current behaviour, e.g. potential for bugs or mistakes?
>

IMHO, the benefit is that you naturally expect a subsequent element to get
the n+1 key regardless of n being positive or negative. The current
implementation gives you an effect that you only discover once you hit it
or read the manual page about array_fill or the note you mentioned before
on the page about arrays.

Regards,
Pedro
Sorry, only registered users may post in this forum.

Click here to login