# Feature Proposal

- Thread: https://externals.io/message/112881
- Original archive: https://news-web.php.net/php.internals/112881
- Started by Andrew Brown on 2021-01-14T17:52:24+00:00
- Messages: 6
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #112881 — Andrew Brown — 2021-01-14T17:52:24+00:00

URL: https://externals.io/message/112881#112881

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

---

## #112882 — Anna Filina — 2021-01-14T18:12:34+00:00

URL: https://externals.io/message/112881#112882 · In reply to: #112881

> 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



> 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

---

## #112883 — Barel — 2021-01-14T18:18:00+00:00

URL: https://externals.io/message/112881#112883 · In reply to: #112882

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



> > […]
> 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
>
> 
>
> > […]
> to
> > […]
> argument.
> > […]
> things.
> > […]

---

## #112884 — AllenJB — 2021-01-14T18:25:05+00:00

URL: https://externals.io/message/112881#112884 · In reply to: #112881

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



> 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

---

## #112886 — Andrew Brown — 2021-01-14T18:56:06+00:00

URL: https://externals.io/message/112881#112886 · In reply to: #112884

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!



> 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
>
>
> 
> > […]
> argument.
> > […]
>


-- 
Andrew M. Brown

---

## #112887 — Ben Ramsey — 2021-01-14T19:02:14+00:00

URL: https://externals.io/message/112881#112887 · In reply to: #112886

> 
> 
> 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
