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/