Shorthand proposal for associative arrays

  101698
January 26, 2018 18:16 cschneid@cschneid.com (Christian Schneider)
Hi there,
I have a proposal for a shorthand notation of associative arrays borrowed from another language:
	:$foo
would be equivalent to
	'foo' => $foo
and would work with array, list or []

Motivation behind it, maybe someone else finds more good uses:

1) Emulating named parameters with associative arrays like
	html::img([ 'src' => $src, 'alt' => $alt ]);
   could be written as
	html::img([ :$src, :$alt ]);
   which encourages consistent naming of variables and parameters

2) Simplifying list destructuring with non-integer keys, example taking from http://php.net/manual/en/migration71.new-features.php#migration71.new-features.support-for-keys-in-list
	foreach ($data as ["id" => $id, "name" => $name]) {
   becomes
	foreach ($data as [ :$id, :$name ]) {
   which reduces redundancy.

I implemented a minimal patch (2 lines are added to the parser) to implement this which you can find at
	https://cschneid.com/php/php7_2/assoc_array_shorthand.patch

What do you think, is this worth an RFC? I hope I didn't miss an existing one :-)

Regards,
- Chris
  101701
January 26, 2018 20:00 david.proweb@gmail.com (David Rodrigues)
Maybe you should see the extract() method. It will receive strings as
varargs and will create an associative array with the string name and the
value, similar to your first example.

html::img(extract('src', 'alt'));


2018-01-26 16:16 GMT-02:00 Christian Schneider <cschneid@cschneid.com>:

> Hi there, > I have a proposal for a shorthand notation of associative arrays borrowed > from another language: > :$foo > would be equivalent to > 'foo' => $foo > and would work with array, list or [] > > Motivation behind it, maybe someone else finds more good uses: > > 1) Emulating named parameters with associative arrays like > html::img([ 'src' => $src, 'alt' => $alt ]); > could be written as > html::img([ :$src, :$alt ]); > which encourages consistent naming of variables and parameters > > 2) Simplifying list destructuring with non-integer keys, example taking > from http://php.net/manual/en/migration71.new-features.php# > migration71.new-features.support-for-keys-in-list > foreach ($data as ["id" => $id, "name" => $name]) { > becomes > foreach ($data as [ :$id, :$name ]) { > which reduces redundancy. > > I implemented a minimal patch (2 lines are added to the parser) to > implement this which you can find at > https://cschneid.com/php/php7_2/assoc_array_shorthand.patch > > What do you think, is this worth an RFC? I hope I didn't miss an existing > one :-) > > Regards, > - Chris > > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
-- David Rodrigues
  101702
January 26, 2018 20:01 david.proweb@gmail.com (David Rodrigues)
Sorry, the extract() function will receives an array as first argument.

html::img(extract(['src', 'alt']);

2018-01-26 18:00 GMT-02:00 David Rodrigues proweb@gmail.com>:

> Maybe you should see the extract() method. It will receive strings as > varargs and will create an associative array with the string name and the > value, similar to your first example. > > html::img(extract('src', 'alt')); > > > 2018-01-26 16:16 GMT-02:00 Christian Schneider <cschneid@cschneid.com>: > >> Hi there, >> I have a proposal for a shorthand notation of associative arrays borrowed >> from another language: >> :$foo >> would be equivalent to >> 'foo' => $foo >> and would work with array, list or [] >> >> Motivation behind it, maybe someone else finds more good uses: >> >> 1) Emulating named parameters with associative arrays like >> html::img([ 'src' => $src, 'alt' => $alt ]); >> could be written as >> html::img([ :$src, :$alt ]); >> which encourages consistent naming of variables and parameters >> >> 2) Simplifying list destructuring with non-integer keys, example taking >> from http://php.net/manual/en/migration71.new-features.php#migrat >> ion71.new-features.support-for-keys-in-list >> foreach ($data as ["id" => $id, "name" => $name]) { >> becomes >> foreach ($data as [ :$id, :$name ]) { >> which reduces redundancy. >> >> I implemented a minimal patch (2 lines are added to the parser) to >> implement this which you can find at >> https://cschneid.com/php/php7_2/assoc_array_shorthand.patch >> >> What do you think, is this worth an RFC? I hope I didn't miss an existing >> one :-) >> >> Regards, >> - Chris >> >> >> -- >> PHP Internals - PHP Runtime Development Mailing List >> To unsubscribe, visit: http://www.php.net/unsub.php >> >> > > > -- > David Rodrigues >
-- David Rodrigues
  101707
January 26, 2018 21:31 tendoaki@gmail.com (Michael Morris)
On Fri, Jan 26, 2018 at 2:00 PM, David Rodrigues proweb@gmail.com>
wrote:

> Maybe you should see the extract() method.
Uhm, what? You need to learn what extract does before you recommend it as an alternative to someone's proposal. Extract takes an array and moves their keys onto the local symbol table. So extract( ['src' => 'myimg.jpg', 'alt' => 'My alt']); echo $src; // myimg.jpg echo $alt; // My alt Using extract on an array with numeric keys gives you fun stuff like $0, $1 and so on. Extract sees most of its use in PHP based template management classes where an associative array is extracted than a template file is included, to allow the template file to use the key names as variables rather than the array syntax. As to the proposal itself.
> Motivation behind it, maybe someone else finds more good uses: > > 1) Emulating named parameters with associative arrays like > html::img([ 'src' => $src, 'alt' => $alt ]); > could be written as > html::img([ :$src, :$alt ]); > which encourages consistent naming of variables and parameters
I've been mulling this over since I saw it earlier today. It's kinda neat to be honest.
  101708
January 26, 2018 21:39 tendoaki@gmail.com (Michael Morris)
Forgot something in the previous post...

On Fri, Jan 26, 2018 at 12:16 PM, Christian Schneider <cschneid@cschneid.com
> wrote:
> Hi there, > I have a proposal for a shorthand notation of associative arrays borrowed > from another language: > :$foo > would be equivalent to > 'foo' => $foo > and would work with array, list or [] > > Motivation behind it, maybe someone else finds more good uses: > > 1) Emulating named parameters with associative arrays like > html::img([ 'src' => $src, 'alt' => $alt ]); > could be written as > html::img([ :$src, :$alt ]); > which encourages consistent naming of variables and parameters >
The most similar extant feature to this is compact, but it's not as compact as this syntax. $src = 'my.jpg'; $alt = 'My alt'; html::img(compact($src, $alt)); will accomplish the same thing since compact does the reverse of extract - it pulls the specified variables from the local scope and puts them into an associative array.
  101709
January 26, 2018 21:49 david.proweb@gmail.com (David Rodrigues)
Sorry. I mean "compact()" instead of extract() (it basically does the
oposite hehe), I confused everything in a hurry. Sorry.

So the real example is: html::img(compact('src', 'alt'));

2018-01-26 19:39 GMT-02:00 Michael Morris <tendoaki@gmail.com>:

> Forgot something in the previous post... > > On Fri, Jan 26, 2018 at 12:16 PM, Christian Schneider < > cschneid@cschneid.com > > wrote: > > > Hi there, > > I have a proposal for a shorthand notation of associative arrays borrowed > > from another language: > > :$foo > > would be equivalent to > > 'foo' => $foo > > and would work with array, list or [] > > > > Motivation behind it, maybe someone else finds more good uses: > > > > 1) Emulating named parameters with associative arrays like > > html::img([ 'src' => $src, 'alt' => $alt ]); > > could be written as > > html::img([ :$src, :$alt ]); > > which encourages consistent naming of variables and parameters > > > > The most similar extant feature to this is compact, but it's not as compact > as this syntax. > > $src = 'my.jpg'; > $alt = 'My alt'; > html::img(compact($src, $alt)); > > will accomplish the same thing since compact does the reverse of extract - > it pulls the specified variables from the local scope and puts them into an > associative array. >
-- David Rodrigues
  101714
January 27, 2018 23:29 pollita@php.net (Sara Golemon)
On Fri, Jan 26, 2018 at 4:49 PM, David Rodrigues proweb@gmail.com> wrote:
> Sorry. I mean "compact()" instead of extract() (it basically does the > oposite hehe), I confused everything in a hurry. Sorry. > > So the real example is: html::img(compact('src', 'alt')); > > 2018-01-26 19:39 GMT-02:00 Michael Morris <tendoaki@gmail.com>: > >> Forgot something in the previous post... >> >> On Fri, Jan 26, 2018 at 12:16 PM, Christian Schneider < >> cschneid@cschneid.com >> > wrote: >> >> > Hi there, >> > I have a proposal for a shorthand notation of associative arrays borrowed >> > from another language: >> > :$foo >> > would be equivalent to >> > 'foo' => $foo >> > and would work with array, list or [] >> > >> > Motivation behind it, maybe someone else finds more good uses: >> > >> > 1) Emulating named parameters with associative arrays like >> > html::img([ 'src' => $src, 'alt' => $alt ]); >> > could be written as >> > html::img([ :$src, :$alt ]); >> > which encourages consistent naming of variables and parameters >> > >> >> The most similar extant feature to this is compact, but it's not as compact >> as this syntax. >> >> $src = 'my.jpg'; >> $alt = 'My alt'; >> html::img(compact($src, $alt)); >> >> will accomplish the same thing since compact does the reverse of extract - >> it pulls the specified variables from the local scope and puts them into an >> associative array. >> > I see nothing in this proposal that compact doesn't already do quite well.
-1
  101715
January 28, 2018 02:51 cschneid@cschneid.com (Christian Schneider)
Am 28.01.2018 um 00:29 schrieb Sara Golemon <pollita@php.net>:
> On Fri, Jan 26, 2018 at 4:49 PM, David Rodrigues proweb@gmail.com <mailto:david.proweb@gmail.com>> wrote: >> Sorry. I mean "compact()" instead of extract() (it basically does the >> oposite hehe), I confused everything in a hurry. Sorry. >> >> So the real example is: html::img(compact('src', 'alt')); >> >>> On Fri, Jan 26, 2018 at 12:16 PM, Christian Schneider <cschneid@cschneid.com> wrote: >>>> 1) Emulating named parameters with associative arrays like >>>> html::img([ 'src' => $src, 'alt' => $alt ]); >>>> could be written as >>>> html::img([ :$src, :$alt ]); >>>> which encourages consistent naming of variables and parameters >> > I see nothing in this proposal that compact doesn't already do quite well.
Yes, it is syntactic sugar to remove verbosity. Using compact() has two problems for me: 1) It is verbose especially if the assoc-as-poor-man's-named-parameter approach is used frequently. A bit like array() vs. []. 2) More importantly: It hides the variable being used: 'src' instead of $src which makes it harder to search for the variable or statically analyse the code. - Chris
  101716
January 28, 2018 06:54 markus@fischer.name (Markus Fischer)
Hi,

On 28.01.18 03:51, Christian Schneider wrote:
> 2) More importantly: It hides the variable being used: 'src' instead of $src which makes it harder to search for the variable or statically analyse the code.
I'm not sure about that argument. compact() been around basically since forecer. Modern PHP IDEs do support this already and I'm pretty sure static analyzers do too (I now for a fact that both PhpStorm and phpstan support it). In contrast, I've this argument: With compact() you have a clear call acting as a boundary when such a behaviour is used. Use the direct-variable syntax doesn't give you that because you would at least know the name of a variable or apply regular expression for such but I bet you can't easily use any tool at hand like you could with compact. Is this _more_ relevant than your arguments? I'm not to judge :) But I too believe compact() serves well and covers everything and the proposal is one more thing to put alternative syntax for something already possible. I also weight that it's practical impact is much more less then compared to e.g. the coalesce operator. That ons is also just syntax sugar but it really made an impact to the language because that pattern is very very common. I don't think this applies to compact(); it only has very special use-cases (and it's not only templating…), I see it in almost every project I work and (and use it myself) and I never felt something "fix-worthy" with it. - Markus
  101717
January 28, 2018 07:47 narf@devilix.net (Andrey Andreev)
Hi,

I've got mixed feelings about this ...

On one hand, I've always avoided compact() because it is magic; a hack
that was very obviously made because there was no language construct
for it. This would've spared me lots of annoyance with code that was
already otherwise boring.
But on the other hand ...

> Yes, it is syntactic sugar to remove verbosity. Using compact() has two problems for me: > 1) It is verbose especially if the assoc-as-poor-man's-named-parameter approach is used frequently. A bit like array() vs. [].
array() vs [] is an entirely different level of frequency. If you're using compact() even remotely as much as arrays in general, it sounds more like you're abusing those poor-mans-named-params. The use cases for that should be limited to stuff like PDO's named parameter markers, not literally every function. And to speculate a bit, if your variable names always match the desired array key names, then you're probably (and paradoxically) already being verbose with stuff like $src = $url. For the few valid use cases where the names do 100% match, compact() (while I do hate it) already does the job and it isn't *that* verbose. Cheers, Andrey.
  101710
January 26, 2018 21:51 php@fleshgrinder.com (Fleshgrinder)
On 1/26/2018 7:16 PM, Christian Schneider wrote:
> Hi there, > I have a proposal for a shorthand notation of associative arrays borrowed from another language: > :$foo > would be equivalent to > 'foo' => $foo > and would work with array, list or [] > > Motivation behind it, maybe someone else finds more good uses: > > 1) Emulating named parameters with associative arrays like > html::img([ 'src' => $src, 'alt' => $alt ]); > could be written as > html::img([ :$src, :$alt ]); > which encourages consistent naming of variables and parameters > > 2) Simplifying list destructuring with non-integer keys, example taking from http://php.net/manual/en/migration71.new-features.php#migration71.new-features.support-for-keys-in-list > foreach ($data as ["id" => $id, "name" => $name]) { > becomes > foreach ($data as [ :$id, :$name ]) { > which reduces redundancy. > > I implemented a minimal patch (2 lines are added to the parser) to implement this which you can find at > https://cschneid.com/php/php7_2/assoc_array_shorthand.patch > > What do you think, is this worth an RFC? I hope I didn't miss an existing one :-) > > Regards, > - Chris > >
Hi Chris! I really like this proposal. `compact` is cumbersome to use, or lets say, almost impossible without an intelligent IDE. However, what is more important is the fact that is would allow for a very readable and usable approach for destructuring of associative arrays (as illustrated by your example) which is very, very neat. The change is also extremely minimal which speaks for it. I would support you in writing up an RFC for this (if desired). -- Richard "Fleshgrinder" Fussenegger
  101711
January 26, 2018 22:44 richard@jenningstechnology.com (Richard Jennings)
In my opinion this suggestion reduces readability and increases cognative
burden and as such I hope it is not included. Regards

On Fri, 26 Jan 2018 at 21:52, Fleshgrinder <php@fleshgrinder.com> wrote:

> On 1/26/2018 7:16 PM, Christian Schneider wrote: > > Hi there, > > I have a proposal for a shorthand notation of associative arrays > borrowed from another language: > > :$foo > > would be equivalent to > > 'foo' => $foo > > and would work with array, list or [] > > > > Motivation behind it, maybe someone else finds more good uses: > > > > 1) Emulating named parameters with associative arrays like > > html::img([ 'src' => $src, 'alt' => $alt ]); > > could be written as > > html::img([ :$src, :$alt ]); > > which encourages consistent naming of variables and parameters > > > > 2) Simplifying list destructuring with non-integer keys, example taking > from > http://php.net/manual/en/migration71.new-features.php#migration71.new-features.support-for-keys-in-list > > foreach ($data as ["id" => $id, "name" => $name]) { > > becomes > > foreach ($data as [ :$id, :$name ]) { > > which reduces redundancy. > > > > I implemented a minimal patch (2 lines are added to the parser) to > implement this which you can find at > > https://cschneid.com/php/php7_2/assoc_array_shorthand.patch > > > > What do you think, is this worth an RFC? I hope I didn't miss an > existing one :-) > > > > Regards, > > - Chris > > > > > > Hi Chris! > > I really like this proposal. `compact` is cumbersome to use, or lets > say, almost impossible without an intelligent IDE. However, what is more > important is the fact that is would allow for a very readable and usable > approach for destructuring of associative arrays (as illustrated by your > example) which is very, very neat. The change is also extremely minimal > which speaks for it. > > I would support you in writing up an RFC for this (if desired). > > -- > Richard "Fleshgrinder" Fussenegger > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > > -- Richard Jennings
Jennings Technology Limited Company Number: 09827512 VAT Number: 224 8864 84
  101713
January 27, 2018 14:14 rowan.collins@gmail.com (Rowan Collins)
Hi!

On 26/01/2018 18:16, Christian Schneider wrote:
> Hi there, > I have a proposal for a shorthand notation of associative arrays borrowed from another language: > :$foo > would be equivalent to > 'foo' => $foo > and would work with array, list or []
I'm always a little suspicious of features that give meaning to the name of a variable, because I consider variable names to be an important part of the readability of code, and the encapsulation of an implementation. As such, I want to be able to rename local variables as part of tweaking how a particular function is written. For instance, I'm not in favour of introducing named parameters based on existing function signatures, because it makes names which were previously local into part of the function's public signature. While this particular proposal doesn't prevent refactoring in the way named parameters would, it adds one more thing to trip up on: when renaming $foo to $bar, [:$foo] needs to be changed to ['foo' => $bar].
> 1) Emulating named parameters with associative arrays like > html::img([ 'src' => $src, 'alt' => $alt ]); > could be written as > html::img([ :$src, :$alt ]); > which encourages consistent naming of variables and parameters
This smells of bad code to me: it either means your functions are very closely coupled, and the variables have exactly the same meaning in both scopes; or that one or other name is poorly chosen, and doesn't reflect its meaning in the scope where it's used. In this example, $alt would probably have come from some other string, which could more appropriately be labelled $productName, or $bookTitle, or whatever the image is showing. If the values are constructed just for this function call, I would prefer to read:     html::img([          'src' => $imageDomain . $coverImagePath,          'alt' => "$bookTitle by $authorName"     ]); as opposed to:    $src = $coverImagePath . $coverImagePath;    $alt = "$bookTitle by $authorName";    html::img([ :$src, :$alt ]);
> 2) Simplifying list destructuring with non-integer keys, example taking from http://php.net/manual/en/migration71.new-features.php#migration71.new-features.support-for-keys-in-list > foreach ($data as ["id" => $id, "name" => $name]) { > becomes > foreach ($data as [ :$id, :$name ]) { > which reduces redundancy.
This example feels a bit more compelling, but again it assumes that you want the local name to match the array key, rather than having a name appropriate to the current task. For instance, you might well be dealing with other things which have IDs and names, and want to differentiate:    foreach( $bookList as ["id" => $bookId, "name" => $bookName ] ) { I'm not dead against this proposal, but it's not one I'd be using often myself, and personally I think it would lead to more bad code than good. Regards, -- Rowan Collins [IMSoP]