Feature Proposal

php.internals

Andrew Brown

5 years ago
This is my first foray into PHP internals, so please let me know if I'm doing something wrong. Currently just following the instructions from https://wiki.php.net/rfc/howto. Currently this proposal is only a "concept". I propose we add a "default" keyword that can be passed as an argument into a function/method call. This would allow the calling code to defer to the function signature for the value of a parameter. Traditionally, all optional parameters are placed towards the end of the function parameter list, but as we all know, sometimes this order can be tricky. So if some calling code wants to override a later parameter, it currently needs to pass a value to the earlier optional parameters. A current solution around this is to define all defaults in the body of the function rather than in the signature. [image: Screen-Shot-2021-01-14-at-11.45.09-AM.jpg] However, this adds some extra boilerplate, and we can't use default parameters as they were really intended. My proposal is to add a new `default` keyword to be passed as an argument. [image: Screen-Shot-2021-01-14-at-11.44.57-AM.jpg] The first call of the function here is how we currently have to do things. We have to explicitly pass `true` in as the second parameter. However, in the second call, we now use the new `default` keyword, which will defer to the function signature for the default value of `$param2`. Thanks all, looking forward to some feedback!
-- Andrew M. Brown

Anna Filina

5 years ago
> So if some calling code wants to override a later parameter, it currently
needs to pass a value to the earlier optional parameters. I think that this is a code smell that should be addressed by a better design. Here's a detailed explanation of why one should use default parameters sparingly, along with alternatives: https://afilina.com/null-hell I feel like such a feature would enable developers to dig themselves a deeper hole towards unmaintainable code. That's just my 2 cents. Anna Filina On Thu, Jan 14, 2021 at 12:52 PM Andrew Brown <browner12@gmail.com> wrote:

Barel

5 years ago
This is handled in a more elegant way by the named arguments of PHP8 https://stitcher.io/blog/php-8-named-arguments With that feature you can just pass the parameters that you need and the others will get their default values Barel On Thu, 14 Jan 2021 at 18:12, Anna Filina <afilina@gmail.com> wrote:

AllenJB

5 years ago
Hi, It looks like your images have broken (Random guess: the list may remove attachments). As a general rule, I would suggest avoiding screenshots for code. Common mailing list etiquette for development lists is to avoid attachments or embedded remote images as these tend to get lost in history, and not all list members may be using graphical clients. Looking at what I can see of your proposal, PHP already supports default values for arguments: https://www.php.net/manual/en/functions.arguments.php#functions.arguments.default ...and as of PHP 8 this can be combined with named arguments to allow "skipping" when calling: https://www.php.net/manual/en/functions.arguments.php#functions.named-arguments https://3v4l.org/rUGuP     function test($foo, $bar = "bardefault", $qux = "quxdefault")     {         return [$foo, $bar, $qux];     }     var_dump(test(foo: "foovalue", qux: "quxvalue")); This doesn't allow for declaring required parameters after optional ones in the functional declaration, but does allow for flexibility when calling while making it explicit which parameters you actually want to pass. While some time ago, this feature suggestion has been discussed before: * https://externals.io/message/105123 * https://externals.io/message/80201 (There were additional older threads I found via externals.io searches for "default keyword" and "parameter skip" which I've not included here) You may also want to check threads / the RFC related to named parameters as there may be additional discussion there. AllenJB On 14/01/2021 17:52, Andrew Brown wrote:

Andrew Brown

5 years ago
Thanks for the feedback. Thanks for the tip on avoiding embedded images. *Anna*: Definitely agree that long signatures, along with lots of optional parameters can be signs of other issues. That's why I used a 3 parameter signature in my example, where it's "required", "optional", "optional", which I feel is pretty common. Here's an example from the Laravel codebase of that in action: public function ensureDirectoryExists($path, $mode = 0755, $recursive = true) { if (! $this->isDirectory($path)) { $this->makeDirectory($path, $mode, $recursive); } } In this scenario, I may not particularly care to explicitly define my mode, and instead defer to the package maintainer, but I may care to prevent a recursive directory from being made. *Allen*: Thanks for the links to the other discussions. I think this RFC ( https://wiki.php.net/rfc/skipparams) is basically exactly what I'm proposing. I know named arguments are a hotly contested feature right now, and honestly I'm not sure where I fall on them right now. But I would also see this as a complement to named parameters. I can see this feature has been debated heavily in the past, so I probably won't get anywhere further than they already have with it. Thanks for the help! On Thu, Jan 14, 2021 at 12:25 PM AllenJB <php.lists@allenjb.me.uk> wrote:
> Hi, > > It looks like your images have broken (Random guess: the list may remove > attachments). > > As a general rule, I would suggest avoiding screenshots for code. Common > mailing list etiquette for development lists is to avoid attachments or > embedded remote images as these tend to get lost in history, and not all > list members may be using graphical clients. > > Looking at what I can see of your proposal, PHP already supports default > values for arguments: > > https://www.php.net/manual/en/functions.arguments.php#functions.arguments.default > > ...and as of PHP 8 this can be combined with named arguments to allow > "skipping" when calling: > > https://www.php.net/manual/en/functions.arguments.php#functions.named-arguments > > https://3v4l.org/rUGuP > > function test($foo, $bar = "bardefault", $qux = "quxdefault") > { > return [$foo, $bar, $qux]; > } > > var_dump(test(foo: "foovalue", qux: "quxvalue")); > > This doesn't allow for declaring required parameters after optional ones > in the functional declaration, but does allow for flexibility when > calling while making it explicit which parameters you actually want to > pass. > > While some time ago, this feature suggestion has been discussed before: > * https://externals.io/message/105123 > * https://externals.io/message/80201 > > (There were additional older threads I found via externals.io searches > for "default keyword" and "parameter skip" which I've not included here) > > You may also want to check threads / the RFC related to named parameters > as there may be additional discussion there. > > > AllenJB > > > On 14/01/2021 17:52, Andrew Brown wrote: > > This is my first foray into PHP internals, so please let me know if > > I'm doing something wrong. Currently just following the instructions > > from https://wiki.php.net/rfc/howto <https://wiki.php.net/rfc/howto>. > > > > Currently this proposal is only a "concept". > > > > I propose we add a "default" keyword that can be passed as an argument > > into a function/method call. This would allow the calling code to > > defer to the function signature for the value of a parameter. > > > > Traditionally, all optional parameters are placed towards the end of > > the function parameter list, but as we all know, sometimes this order > > can be tricky. So if some calling code wants to override a later > > parameter, it currently needs to pass a value to the earlier optional > > parameters. > > > > A current solution around this is to define all defaults in the body > > of the function rather than in the signature. > > > > Screen-Shot-2021-01-14-at-11.45.09-AM.jpg > > > > However, this adds some extra boilerplate, and we can't use default > > parameters as they were really intended. > > > > My proposal is to add a new `default` keyword to be passed as an > argument. > > > > Screen-Shot-2021-01-14-at-11.44.57-AM.jpg > > > > The first call of the function here is how we currently have to do > > things. We have to explicitly pass `true` in as the second parameter. > > > > However, in the second call, we now use the new `default` keyword, > > which will defer to the function signature for the default value of > > `$param2`. > > > > Thanks all, looking forward to some feedback! > > > > -- > > Andrew M. Brown >
-- Andrew M. Brown

Ben Ramsey

5 years ago
> On Jan 14, 2021, at 12:56, Andrew Brown <browner12@gmail.com> wrote: > > I know named arguments are a hotly contested feature right now, and > honestly I'm not sure where I fall on them right now. But I would also see > this as a complement to named parameters. > > I can see this feature has been debated heavily in the past, so I probably > won't get anywhere further than they already have with it.
Named arguments are no longer hotly contested. They are in PHP 8. :-) See https://www.php.net/releases/8.0/en.php Cheers, Ben