Skip to content

Proposal: Support [key: expr] alias for ['key' => expr] #6635

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from

Conversation

TysonAndre
Copy link
Contributor

@TysonAndre TysonAndre commented Jan 24, 2021

In every place where key is a valid php identifier
(e.g. can be used in PHP 8.0's named parameters),
allow [key: expr] to be used instead of ['key' => expr].

This is useful for shortening long arrays where the keys are known literals,
e.g.

return [success: true, data: $data, cursor: $cursor];
// is equivalent to the following, but shorter:
return ['success' => true, 'data' => $data, 'cursor' => $cursor];

This uses a similar syntax to named parameter invocations,
making it unlikely to cause future parser conflicts.

// Invoking a function with PHP 8.0 named parameters.
process_api_result(success: true, data: $data);

This can also be used in the older array() value and list() destructuring
syntaxes. Forbidding key: value there seemed like
an unnecessary restriction that would make
the language harder to remember and a language specification a bit longer.
It is already possible to configure a linter to suggest that a project
consistently use [] vs array() or list() according to coding standards,
and automatically apply fixes.

It is possible to mix syntaxes, e.g. this works:

return [
    config: [
        user: [id: get_user_id(), name: $name],
    ],
    myReference: &$this->property,
    $extraFieldName => $extra,
    ...$overrides,
];

This was part of the potential future scope mentioned in
https://wiki.php.net/rfc/named_params#shorthand_syntax_for_matching_parameter_and_variable_name

After a quick check of mailing lists, this is about the same as the https://wiki.php.net/rfc/bare_name_array_literal which was proposed 6 years ago for php 5.x.
Because the named parameters RFC had passed and php has added many new syntaxes since then, and there are much better open source static analyzers available for php nowadays to catch potential issues, there may be more interest in adding this.
(Possibly in combination with allowing [: $success, : $data] as a shorthand for ['success' => $success, 'data' => $data] for array values and/or destructuring where variables have string names)


The second commit also adds support for
[: $key] = $collection; as an alias for ['key' => $key] = $collection
and return [: $key] as an alias for return ['key' => $key]. (plus reference syntax)

That syntax is more readable and more efficient than extract/compact and saves a lot more typing
(https://wiki.php.net/rfc/named_params#shorthand_syntax_for_matching_parameter_and_variable_name)

EDIT: apparently, https://externals.io/message/101698 proposed that earlier with mixed, mostly negative responses

all three of the following would behave identically:

$point = ['x' => $x, 'y' => $y, 'z' => $z];
$point = [x: $x, y: $y, z: $z];
$point = [:$x, :$y, :$z];

Many programming languages support the ability to use unquoted literals
to concisely represent field names of data. Some examples are listed below:

Javascript: literal keys are allowed. {key: "value"} is shorthand for
{"key": "value"} and the former is frequently preferred.

Python: dict(key='value') is equivalent to {'key': 'value'} and can be
shorter for long lists of literal keys.
(https://docs.python.org/3/tutorial/datastructures.html#dictionaries)
(Note that {key: value} would be referring to the variable key, not a string
literal, and key=value is the named parameter syntax)

Ruby: {key: 'value'} is equivalent to {:key => 'value'} for Symbol keys
https://docs.ruby-lang.org/en/2.0.0/Hash.html

Lua: {key="value"} is equivalent to {["key"]="value"}
https://www.lua.org/pil/3.6.html

In compiled languages such as C++, Golang, and Rust,
struct/classes are used more often than associative arrays for type safety,
and identifiers are used unquoted in structs,
and maps can use more types than just strings/ints so there generally isn't a
dedicated shorthand.
https://en.cppreference.com/w/c/language/struct_initialization
https://doc.rust-lang.org/book/ch05-01-defining-structs.html
https://tour.golang.org/moretypes/5

@mvorisek
Copy link
Contributor

Do you allow syntax mixing within one array declaration?

@TysonAndre
Copy link
Contributor Author

Do you allow syntax mixing within one array declaration?

Yes. This is mentioned in the description

It is possible to mix syntaxes, e.g. this works:

return [
    config: [
        user: [id: get_user_id(), name: $name],
    ],
    myReference: &$this->property,
    $extraFieldName => $extra,
    ...$overrides,
];

In every place where `key` is a valid php identifier
(e.g. can be used in PHP 8.0's named parameters),
allow `[key: expr]` to be used instead of `['key' => expr]`.

This is useful for shortening long arrays where the keys are known literals,
e.g.

```
return [success: true, data: $data, cursor: $cursor];
// is equivalent to the following, but shorter:
return ['success' => true, 'data' => $data, 'cursor' => $cursor];
```

This uses a similar syntax to named parameter invocations,
making it unlikely to cause future parser conflicts.

```
// Invoking a function with PHP 8.0 named parameters.
process_api_result(success: true, data: $data);
```

This can also be used in the older `array()` value and `list()` destructuring
syntaxes. Forbidding `key: value` there seemed like
an unnecessary restriction that would make
the language harder to remember and a language specification a bit longer.
It is already possible to configure a linter to suggest that a project
consistently use `[]` vs `array()` or `list()` according to coding standards,
and automatically apply fixes.

It is possible to mix syntaxes, e.g. this works:

```php
return [
    config: [
        user: [id: get_user_id(), name: $name],
    ],
    myReference: &$this->property,
    $extraFieldName => $extra,
    ...$overrides,
];
```

This was part of the potential future scope mentioned in
https://wiki.php.net/rfc/named_params#shorthand_syntax_for_matching_parameter_and_variable_name

-------

Many programming languages support the ability to use unquoted literals
to concisely represent field names of data. Some examples are listed below:

Javascript: literal keys are allowed. `{key: "value"}` is shorthand for
`{"key": "value"}` and the former is frequently preferred.

Python: `dict(key='value')` is equivalent to `{'key': 'value'}` and can be
shorter for **long lists** of literal keys.
(https://docs.python.org/3/tutorial/datastructures.html#dictionaries)
(Note that {key: value} would be referring to the variable `key`, not a string
literal, and key=value is the named parameter syntax)

Ruby: `{key: 'value'}` is equivalent to `{:key => 'value'}` for Symbol keys
https://docs.ruby-lang.org/en/2.0.0/Hash.html

Lua: {key="value"} is equivalent to `{["key"]="value"}`
https://www.lua.org/pil/3.6.html

In compiled languages such as C++, Golang, and Rust,
struct/classes are used more often than associative arrays for type safety,
and identifiers are used unquoted in structs,
and maps can use more types than just strings/ints so there generally isn't a
dedicated shorthand.
https://en.cppreference.com/w/c/language/struct_initialization
https://doc.rust-lang.org/book/ch05-01-defining-structs.html
https://tour.golang.org/moretypes/5
@iluuu1994
Copy link
Member

@TysonAndre Are you planning on pursuing this RFC?

@iluuu1994
Copy link
Member

Closing since there was no response. Feel free to reopen whenever work continues.

@iluuu1994 iluuu1994 closed this Jun 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants