Hi again,

Andrea Faulds wrote:
How feasible would it be to add an exception to mixed keys? I'm thinking
list(7 => $a, $b, $c, $d) to specify an initial offset, similar to how
you
can define an array as [7 => 0, 1, 2, 3]. This obviously goes hand in
hand
with my desire for variable keys :)

Oh, yeah, it's unfortunate that what the RFC currently proposes makes
using initial offsets not possible. :/

The main reason I ended up disallowing mixed keys was because it
complicates implementation if you have a some value that must be
computed at runtime as a key (some constants, a variable, etc.), because
now we can't hard-code the indexes of the following values into the
opcodes. We don't know at compile-time that it'll be 5, 6, 7, we know
it'll be $x, *maybe* $x + 1 (if $x was an index, otherwise it'll be the
previous index), *maybe* $x + 2, etc.

The problem with disallowing mixed keys is it's inconsistent with the
array literal syntax, and as you've demonstrated, it also is
inconvenient for some use cases. As implemented, keyed list() is
actually an entirely different parser branch from unkeyed list(). It's
all a bit too arbitrary.

I may just have to allow mixed keys after all, even if it does make
implementation a pain. I could add an exception for a leading offset,
but that would have to have its own special rules. Better to just do
things properly.

After considering how to implement this at the opcode level, I've decided again that it's not worth it. Mixing keyed and unkeyed elements is not only an implementation nuisance (it's not necessarily hard, but it makes things more complicated), it's not something likely to be used in practice, and I think it's probably an indicator of bad code.

Now, I can understand your case, but I don't really want to add a special exception for it. If we're allowing keyed or unkeyed, not both, then we should stick to it.

Also, I realised that in your case (`list(7 => $a, $b, $c, $d)`), there are other, possibly cleaner ways to do it, such as:

    list($a, $b, $c, $d) = array_slice($array, 7);

This way is simple and clear. It's probably clearer than `list(7 => $a, $b, $c, $d)` in fact. There's also this:

    list(($i = 7) => $a, ++$i => $b, ++$i => $c, ++$i => $d) = $array;

This way is horrible, but at least demonstrates there are other ways to achieve what you want.

Thanks!
--
Andrea Faulds
https://ajf.me/

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to