Hi everyone,
Here's an RFC that would extend the syntax of list() to be more useful
with associative arrays:
https://wiki.php.net/rfc/list_keys
Please read it and tell me your thoughts.
Thanks!
Andrea Faulds
https://ajf.me/
Hi everyone,
Here's an RFC that would extend the syntax of list() to be more useful
with associative arrays:https://wiki.php.net/rfc/list_keys
Please read it and tell me your thoughts.
Nice, Andrea, thanks! Destructuring is quite handy.
I wonder if there is opportunity to include array gathering. Something
along the lines of:
list ('foo' => $foo, ...$rest) = [ 'foo' => 1, 'bar' => 2, 'baz' => 3];
assert $foo === 1;
assert $rest === [ 'bar' => 2, 'baz' => 3];
What do you think?
Hi Bishop,
Bishop Bettini wrote:
Hi everyone,
Here's an RFC that would extend the syntax of list() to be more useful
with associative arrays:https://wiki.php.net/rfc/list_keys
Please read it and tell me your thoughts.
Nice, Andrea, thanks! Destructuring is quite handy.
I wonder if there is opportunity to include array gathering. Something
along the lines of:list ('foo' => $foo, ...$rest) = [ 'foo' => 1, 'bar' => 2, 'baz' => 3];
assert $foo === 1;
assert $rest === [ 'bar' => 2, 'baz' => 3];What do you think?
That might be useful, and it's certainly intuitive. In languages with
linked lists like Haskell, you can pattern-match the rest of a list, so
there's a precedent. Though with linked lists it's an O(1) operation,
while this is O(n).
I don't think that should go into this RFC specifically, though, but it
could be a future enhancement.
Thanks!
Andrea Faulds
https://ajf.me/
hi Andrea,
I very much like this proposal. Good work as usual!
The only part where I think we should not rely on list is the future
scope. I can see the logic that leads to use list for named arguments.
However I really think it is a very different topic and having to use
list to define arguments, it sounds like a hack to solve another long
due feature. Anyway, as it is not part of this RFC, I will ignore it
for now :)
Keep the good work,
Cheers,
Pierre
Hi Bishop,
Bishop Bettini wrote:
Hi everyone,
Here's an RFC that would extend the syntax of list() to be more useful
with associative arrays:https://wiki.php.net/rfc/list_keys
Please read it and tell me your thoughts.
Nice, Andrea, thanks! Destructuring is quite handy.
I wonder if there is opportunity to include array gathering. Something
along the lines of:list ('foo' => $foo, ...$rest) = [ 'foo' => 1, 'bar' => 2, 'baz' => 3];
assert $foo === 1;
assert $rest === [ 'bar' => 2, 'baz' => 3];What do you think?
That might be useful, and it's certainly intuitive. In languages with linked
lists like Haskell, you can pattern-match the rest of a list, so there's a
precedent. Though with linked lists it's an O(1) operation, while this is
O(n).I don't think that should go into this RFC specifically, though, but it
could be a future enhancement.Thanks!
Andrea Faulds
https://ajf.me/--
--
Pierre
@pierrejoye | http://www.libgd.org
Hi Andrea
I am writing you in private since I think this is rather out of scope.
-----Ursprüngliche Nachricht-----
Von: Pierre Joye [mailto:pierre.php@gmail.com]
Gesendet: Montag, 18. Januar 2016 05:54
An: Andrea Faulds
Cc: PHP internals
Betreff: Re: [PHP-DEV] [RFC] Allow specifying keys in list()hi Andrea,
I very much like this proposal. Good work as usual!
The only part where I think we should not rely on list is the future scope. I can see the logic that leads to use list for named
arguments.
However I really think it is a very different topic and having to use list to define arguments, it sounds like a hack to solve
another long due feature.
I agree with Pierre on this one. Using list for named parameters seems like a lot of overhead on the declaration side to me (writing the name of a parameter twice). IMO it should not require additional effort than writing a function/method today and it should be available for all functions/methods and not only for ones with special named-paramater-syntax. I think you should consider further (when thinking about using the new feature for named parameters)
- how can you specify optional parameters?
- how can you specify byRef parameters?
- what happens if one does not provide all keys? Currently this: list($a, $b) = [1]; //only produces a Warning
- are there differences between strict mode and none strict mode? e.g., what if the type of the key is different?
- would it be possible to use a type for the key as well (as for the value indicated in your RFC)?
- would you allow nested destructuring for parameters?
- how would you reduce the overhead of creating an array which is then copied and passed to the function?
IMO destructuring parameters and named parameters are two different things which could be combined. Something like this:
function foo(SomeClass $class, list("x" => $x, "y" => $y) $point = ["x"=>0, "y"=>0], $flagA = true, $flagB = 1) {
}
foo($myClass, point: [1,2], flagB: 0);
foo($myClass, flagB: 2);
yet, IMO it would hamper readability (probably in many cases) and it would be better to do it inside the function.
I understand destructuring parameters just as syntactic sugar and I would still expect that PhpDocumenter would indicate that my function requires an array. Otherwise the same feature would suddenly also be used to declare deep structured data structures and at this point I am not so sure whether auto conversion of keys play well together with strict mode. It would certainly be interesting from a type safety point of view that one can define very complex data structures and let PHP do the work for verification. Yet, it also opens a door to very ugly code (well... which also exists without the feature) -- sorry, drifting away from the topic.
Some other points crossing my mind
- how well does the feature interact with typed arrays (if they should be introduced at some point)?
- how well does it interact with structural types (if they should be introduced at some point)?
And now some points to the RFC:
- I like the RFC in general
- I am not really a fan of the naming "list" in general but I think it is appropriate to reuse the same syntax for this task.
- one thing I am missing in the RFC is error handling. What happens if a key is not found? And there are surely other questions. I think you should include a section about error handling in the RFC.
- I guess mixing number keys with string keys is possible, right?
- are placeholders (something like list(_ , $a, _) = [1,2,3]) in your pipeline or do you think they make no sense in PHP?
- already an idea how it would interact with pattern matching?
Cheers,
Robert
Hi everyone,
Here's an RFC that would extend the syntax of list() to be more useful
with associative arrays:https://wiki.php.net/rfc/list_keys
Please read it and tell me your thoughts.
Hi!
I found the idea convincing from the first read, but maybe it's just my
mind's assumptions about list() that I dislike the resulting syntax,
yet, it seems to be the logical choice.
So, maybe I'm just trying to say, that I don't like list() to be reused
for that, but I don't have any better idea otherwise.
--
Regards,
Mike
Here's an RFC that would extend the syntax of list() to be more useful
with associative arrays:
https://wiki.php.net/rfc/list_keys
Please read it and tell me your thoughts.
Hi!I found the idea convincing from the first read, but maybe it's just my
mind's assumptions about list() that I dislike the resulting syntax,
yet, it seems to be the logical choice.So, maybe I'm just trying to say, that I don't like list() to be reused
for that, but I don't have any better idea otherwise.
As someone still using 'extract' in legacy code, I can sort of see the
logistics of this, but why not just extend 'extract' to use the current
object rather than the symbol table. It already has handling for
duplicate keys and to prefix the 'array' name to the resulting variables.
--
Lester Caine - G8HFL
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk
Lester Caine wrote on 18/01/2016 12:35:
As someone still using 'extract' in legacy code, I can sort of see the
logistics of this, but why not just extend 'extract' to use the current
object rather than the symbol table. It already has handling for
duplicate keys and to prefix the 'array' name to the resulting variables.
The main advantage I can see is that this is a whitelist-based approach
- you state explicitly in your code what you expect the array to look
like, and what variables you are assigning based on it. This is very
different from "whatever's in this array, turn it into a variable".
The "current object" was just one possible use case, have a look at some
of the other examples in the RFC, such as:
list(
CURLOPT_GET => $isGet,
CURLOPT_POST
=> $isPost,
CURLOPT_URL
=> $url
) = $curlOptions;
Note that $curlOptions probably had other things in it, $url may be an
existing variable getting a new value. The best extract would give you
is $curloption_10002, which isn't all that useful.
Regards,
Rowan Collins
[IMSoP]
Hi!
I found the idea convincing from the first read, but maybe it's just my
mind's assumptions about list() that I dislike the resulting syntax,
yet, it seems to be the logical choice.So, maybe I'm just trying to say, that I don't like list() to be reused
for that, but I don't have any better idea otherwise.As someone still using 'extract' in legacy code, I can sort of see the
logistics of this, but why not just extend 'extract' to use the current
object rather than the symbol table. It already has handling for
duplicate keys and to prefix the 'array' name to the resulting variables.
The uses for this extended syntax go beyond simply populating object
properties, and shoehorning it into extract would pretty much limit it to
this use-case.
In favour of this improvement, although I would very much like to see
variable keys too (second option makes the most sense to me, as it's in
line with the syntax).
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 :)
Thanks Andrea, looking forward to this.
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 :)
I would like it to be like, destructuring assignment, in ES6
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
Hi Leigh,
Leigh wrote:
The uses for this extended syntax go beyond simply populating object
properties, and shoehorning it into extract would pretty much limit it to
this use-case.
In fact I don't think extract()
even works on object properties. list()
works with any "variable" (in the isset() sense).
I should really add some more examples to the RFC, so that it's more
obvious that $this-> assignment is not the only thing this can or will
be used for.
In favour of this improvement, although I would very much like to see
variable keys too (second option makes the most sense to me, as it's in
line with the syntax).
So far I haven't actually heard anyone say they thought it would behave
like (1), which is making me think that allowing arbitrary expressions
would be fine. It'd be unfortunate to lock them out, because constants
can't contain objects, so now you wouldn't be able to use list() with
SplObjectStorage and such, and that would be a shame.
(2) is the only thing I was going to make it do anyway, (1) would mean
list() functioning differently than it does at present.
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.
Thanks Andrea, looking forward to this.
I'm glad you like it!
--
Andrea Faulds
https://ajf.me/
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/
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, I wouldn't worry about it. The use-case was hypothetical
anyway. I could see how I might use it, but I have nowhere at present
I'd actually use it.
list($offset => $a, $b, $b, $c) = $array;
$offset += 4;
vs.
list($a, $b, $c, $d) = array_slice($array, $offset);
$offset += 4;
Probably not worth the complexity overhead as you suggest, for what
amounts to (arguably) syntactic sugar. I also doubt it would see
enough usage to warrant the small gain of avoiding the fcall there.
Hi again,
I've updated the RFC to v1.1, because I've resolved the open issue of
whether to allow arbitrary expressions for keys. It seems that the risk
of confusion was less than I thought it was, and allowing anything not
only simplifies implementation, but means you can do things like have
object keys (when working with SplObjectStorage, for example).
You may wish to look over the RFC again: https://wiki.php.net/rfc/list_keys
Thanks.
--
Andrea Faulds
https://ajf.me/
Hi!
Here's an RFC that would extend the syntax of list() to be more useful
with associative arrays:https://wiki.php.net/rfc/list_keys
Please read it and tell me your thoughts.
After reading the RFC, it looks like a great idea. I wouldn't exactly
encourage this for replacement of named parameters (for one, I
understand it would produce some complaints - like notice? - if the key
does not exist) but there are cases when it's useful and I don't see any
harm in it.
--
Stas Malyshev
smalyshev@gmail.com