# Support negative indexes for arrays and strings

- Thread: https://externals.io/message/51268
- Original archive: https://news-web.php.net/php.internals/51268
- Started by Marc Easen on 2011-01-14T18:21:28+00:00
- Messages: 13
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #51268 — Marc Easen — 2011-01-14T18:21:28+00:00

URL: https://externals.io/message/51268#51268

Hello everyone,

I would like to open the discussion around the support of negative indexes, as I feel a lot of developers will benefit from this syntactical sugar.

Example:
$foo = array(1,2,3);
echo $foo[2]; // 3
echo $foo[-1]; // 3

$bar = 'baz';
echo $foo[2]; // 'z'
echo $foo[-1]; // 'z'

The change to PHP is quite trivial, but as it's a change to language it needs to be discussed. 

I'm happy to open a RFC, I have got a wiki account but I haven't got permission to add a wiki page. Whom do I need to contact regarding getting correct permissions to add/edit wiki pages?

Kind Regards
Marc

---

## #51269 — Matthew Fonda — 2011-01-14T18:32:54+00:00

URL: https://externals.io/message/51268#51269 · In reply to: #51268

> Hello everyone,
>
> I would like to open the discussion around the support of negative indexes, as I feel a lot of developers will benefit from this syntactical sugar.

It would be convenient, but PHP already allows arrays to have negative
indices. Changing their behavior would be a major BC break.

Best Regards,
--Matthew

---

## #51270 — Marcin Babij — 2011-01-14T18:34:43+00:00

URL: https://externals.io/message/51268#51270 · In reply to: #51268

> Hello everyone,
>
> I would like to open the discussion around the support of negative indexes, as I feel a lot of developers will benefit from this syntactical sugar.
>
> Example:
>
> echo $foo[2]; // 3
> echo $foo[-1]; // 3

Negative indexes are used already - for negative indexes.
What should:

$foo = array(1,2,3, -1 => 4, 5, 6);
echo $foo[-1];

return? Now it returns 4.

>
> $bar = 'baz';
> echo $foo[2]; // 'z'
> echo $foo[-1]; // 'z'
>
> The change to PHP is quite trivial, but as it's a change to language it needs to be discussed.
>
> I'm happy to open a RFC, I have got a wiki account but I haven't got permission to add a wiki page. Whom do I need to contact regarding getting correct permissions to add/edit wiki pages?

---

## #51271 — Stas Malyshev — 2011-01-14T18:47:41+00:00

URL: https://externals.io/message/51268#51271 · In reply to: #51268

Hi!

> I would like to open the discussion around the support of negative
> indexes, as I feel a lot of developers will benefit from this
> syntactical sugar.

What you are looking for is implemented in `array_slice()`. Python has
shortcuts for this thing, like a[1:-1], but PHP doesn't. If you wanted
to RFC something here, I think the idea of $a[X:Y] with array_slice 
semantics could be doable. $a[-1:1] would be your case then.
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #60736 — Marc Easen — 2012-06-04T19:08:58+00:00

URL: https://externals.io/message/51268#60736 · In reply to: #51271

I have submitted a patch to support negative indexs in strings, as per 
the conversation adding them to arrays could possibly detract from the 
syntactical sugar they are indented to be.

In summary:

An alternative to:
$var = 'abc';
echo $var[strlen($var) - 1];

Can be:
$var = 'abc';
echo $var[-1];

Commit:
https://github.com/Easen/php-src/commit/7016e52677f525139491467f3e76862b9a597b76

Pull request:
https://github.com/php/php-src/pull/100

Thanks,



> Hi!
>
> > […]
>
> What you are looking for is implemented in `array_slice()`. Python has
> shortcuts for this thing, like a[1:-1], but PHP doesn't. If you wanted
> to RFC something here, I think the idea of $a[X:Y] with array_slice 
> semantics could be doable. $a[-1:1] would be your case then.

---

## #60790 — Richard Lynch — 2012-06-11T18:34:21+00:00

URL: https://externals.io/message/51268#60790 · In reply to: #60736

> I have submitted a patch to support negative indexs in strings, as per
> the conversation adding them to arrays could possibly detract from the
> syntactical sugar they are indented to be.
>
> In summary:
>
> An alternative to:
> $var = 'abc';
> echo $var[strlen($var) - 1];
>
> Can be:
> $var = 'abc';
> echo $var[-1];

This seems simple enough for a hard-coded -1, but...

Would $var[-2] be strlen($var) - 2 and so on?

And then one would expect some rather complex logic to compute -N for
$var[-N]

At that point, this becomes a pretty big WTF, imho.

I've never honestly felt it to be a big burden to use strlen($var) -
1, so I don't really see the point, at least for me.

-- 
brain cancer update:
http://richardlynch.blogspot.com/search/label/brain%20tumor
Donate:
https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FS9NLTNEEKWBE

---

## #60791 — Stas Malyshev — 2012-06-11T19:13:47+00:00

URL: https://externals.io/message/51268#60791 · In reply to: #60790

Hi!

> > […]
> 
> This seems simple enough for a hard-coded -1, but...
> 
> Would $var[-2] be strlen($var) - 2 and so on?

The main question is what happens with "foo"[-4] or ['x'][-2].

> And then one would expect some rather complex logic to compute -N for
> $var[-N]

I don't see much of complex logic here, but $a[2] = 'a' would create a
new array element if it does not exist, while $a[-2] can't. Not a big
issue, but somewhat inconsistent I guess.

-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #60792 — Richard Lynch — 2012-06-11T19:28:21+00:00

URL: https://externals.io/message/51268#60792 · In reply to: #60791

> > […]
>
> I don't see much of complex logic here, but $a[2] = 'a' would create a
> new array element if it does not exist, while $a[-2] can't. Not a big
> issue, but somewhat inconsistent I guess.

$n = some_incredibly_long_and_complex_computation();
//and, for real fun, sometimes it returns positive, and sometimes
negative.

$s = $var[$n];

//a few hundred lines later, buried somewhere else

if ($n < 0){
//whatever
}
else{
//something entirely different
}

Sooner or later, somebody will do that, and I really don't want to
have to un-tangle all that mess to figure out if $n is positive or
negative for the sake of saving a few keystrokes...

-- 
brain cancer update:
http://richardlynch.blogspot.com/search/label/brain%20tumor
Donate:
https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FS9NLTNEEKWBE

---

## #60793 — Galen Wright-Watson — 2012-06-11T19:28:37+00:00

URL: https://externals.io/message/51268#60793 · In reply to: #60791

On Mon, Jun 11, 2012 at 12:13 PM, Stas Malyshev <smalyshev@sugarcrm.com>wrote:

> Hi!
>
> > […]
>
> The main question is what happens with "foo"[-4] or ['x'][-2].
>

The same thing that currently happens for:

    $f='foo'; echo $f[strlen($f)-4];
    $a=['x']; $a[count($a)-2];

which appears to be notices:

Notice: Uninitialized string offset: -1 in - on line 2
> Notice: Undefined offset: -1 in - on line 3


> And then one would expect some rather complex logic to compute -N for
> > […]
>
> I don't see much of complex logic here, but $a[2] = 'a' would create a
> new array element if it does not exist, while $a[-2] can't. Not a big
> issue, but somewhat inconsistent I guess.
>

Negative indices are currently valid for arrays. If anyone makes use of
negative indices, this could break their script. Personally, I'd rather
have Marc Easen's behavior.

---

## #60795 — Marc Easen — 2012-06-11T20:25:46+00:00

URL: https://externals.io/message/51268#60795 · In reply to: #60792

> 
> > […]
> $n = some_incredibly_long_and_complex_computation();
> //and, for real fun, sometimes it returns positive, and sometimes
> negative.
>
> $s = $var[$n];
If $n is a negative value, an `E_NOTICE` will be triggered. To not do
> if ($n<  0){
> //whatever
> }
> else{
> //something entirely different
> }
Prior to your string offset can be looked at being bad practice.

---

## #60796 — Marc Easen — 2012-06-11T21:01:25+00:00

URL: https://externals.io/message/51268#60796 · In reply to: #60791

> Hi!
>
> > […]
> The main question is what happens with "foo"[-4] or ['x'][-2].
>
> > […]
> I don't see much of complex logic here, but $a[2] = 'a' would create a
> new array element if it does not exist, while $a[-2] can't. Not a big
> issue, but somewhat inconsistent I guess.
>

Please note I'm not referring the negative indexes in arrays, just 
strings. As I see strings as being simpler to implement and produce a 
greater benefit compared to supporting negative indexes for arrays. As 
arrays are more complex structures and adding this behaviour would 
complicate things somewhat.

---

## #60871 — Marc Easen — 2012-06-17T19:53:38+00:00

URL: https://externals.io/message/51268#60871

Hi Lars,

I don't think there needs to be a new operator, as it is possible to 
achieve this behaviour without adding a new language construct. The odd 
thing with PHP as I'm sure you are aware of is that arrays can be either 
a lists or a dictionary. This is where this becomes quite difficult to 
implement:

Numerical keyed array:

     $a = array('foo', 'bar', 'baz');
     $a[0] === 'foo'

I would expect:

     $a[-1] === 'baz';

An string keyed array:

     $b = array('foo' => 1, 'bar' => 2, 'baz' => 3);
     $b[0] === 1;

Would generate an E_NOTICE:   PHP Notice:  Undefined offset: 0 in php 
shell code on line 1.
An negative offset would also generate the same E_NOTICE.

So going back to your point, the change would only be to numeric based 
arrays (list) and strings. It could be possible to string keyed arrays 
to be accessed by the numeric counter parts, but I'm not familiar to 
comment on if this is even possible.


It seems this topic has generated a lot of interest, I feel the best way 
to proceed would be to write a RFC. I've never written one before so 
could someone give me access to create a page on the RFC site or create 
a RFC for me and give me permission to update it, my username is 'easen'.

Thanks,
Marc



> Hi Marc,
>
> Am 11.06.2012 um 23:01 schrieb Marc Easen:
>
> [...]
> > […]
> I would propose not to try implementing a different behavior for strings than it is for arrays. I think we need a more convenient way to access parts of a string/parts of an array than `substr()` and `array_slice()` provide. But this will most likely be a new operator.
>
> cu,
> Lars

---

## #60874 — Lars Strojny — 2012-06-17T22:52:54+00:00

URL: https://externals.io/message/51268#60874 · In reply to: #60871

Hi Marc,


Am 17.06.2012 um 21:53 schrieb Marc Easen:
[...]
> Numerical keyed array:
> 
>    $a = array('foo', 'bar', 'baz');
>    $a[0] === 'foo'
> 
> I would expect:
> 
>    $a[-1] === 'baz';
> 
> An string keyed array:
> 
>    $b = array('foo' => 1, 'bar' => 2, 'baz' => 3);
>    $b[0] === 1;
> 
> Would generate an E_NOTICE:   PHP Notice:  Undefined offset: 0 in php shell code on line 1.
> An negative offset would also generate the same E_NOTICE.
> 
> So going back to your point, the change would only be to numeric based arrays (list) and strings. It could be possible to string keyed arrays to be accessed by the numeric counter parts, but I'm not familiar to comment on if this is even possible.

I see, must have overread that. This makes it slightly better but not optimal, as too varying behavior for hashes vs. lists will be harder to explain. We could go down that road and separate the both more and more but given the history (and the usage patterns) of arrays in PHP I'm not convinced this is a good idea.

I would prefer something like this (and no, I don't propose using ':' as an operator for real):

$string = "bar";
$string:-1                   // "b"
$string:-2                   // "r"
$string:-10                   // `NULL` 

$list = array("one", "two", "three");
$list:-1                     // "three"
$list:-2                     // "two"
$list:-10                    // `NULL` 

$hash = array("one" => 1, "two" => 2, "three" => 3)
$hash:-1                     // 3
$hash:-2                     // 2
$hash:-10                    // 10

As using arrays as hashes let’s them behave in a FIFO kind of way, we can do proper slicing.

> It seems this topic has generated a lot of interest, I feel the best way to proceed would be to write a RFC. I've never written one before so could someone give me access to create a page on the RFC site or create a RFC for me and give me permission to update it, my username is 'easen'.

For sure, RFC makes sense. I like the general idea, I’m just not sure about the syntax.

cu,
Lars
