Hi!
As I've got some questions on the topic, I'd like to revive and soon put
to vote the parameter skipping RFC: https://wiki.php.net/rfc/skipparams
For those who doesn't remember, quick reminder - it is about an ability
to skip parameters in function calls so they'd take default value, like
this:
function foo($a, $b = true, $c = "abc") { ... }
foo($x, default, $y); // $b gets to be true here
In the last discussion I had a lot of "objections" to the tune of "we'd
rather have named parameters". I like the idea of named parameters too,
but this one does not contradict it - rather, it compliments it, and a
lot of the extensions cleanup done in this patch also serves as a base
for possible implementation of named params, if it happens (more on that
in the RFC itself).
The pull is at: https://github.com/php/php-src/pull/981
The patch has been reworked to work with PHP 7 engine changes, it is not
perfect yet but in workable condition, and at this point I'd like to
have a decision if we want to continue with it before I invest more time
into covering the remaining corners.
Note that the RFC has been changed in some details (e.g. variadics
handling, but there's more) since the last time it was discussed, due to
the changes in phpng, so I recommend re-reading the RFC even if you were
familiar with it before.
Stas Malyshev
smalyshev@gmail.com
Hi Stas,
For those who doesn't remember, quick reminder - it is about an ability
to skip parameters in function calls so they'd take default value, like
this:
function foo($a, $b = true, $c = "abc") { ... }
foo($x, default, $y); // $b gets to be true hereIn the last discussion I had a lot of "objections" to the tune of "we'd
rather have named parameters". I like the idea of named parameters too,
but this one does not contradict it - rather, it compliments it, and a
lot of the extensions cleanup done in this patch also serves as a base
for possible implementation of named params, if it happens (more on that
in the RFC itself).
Yes, they complement one another. Both exist because of horrible APIs. But I don’t think we should encourage horrible APIs.
I don’t want to end up with the Windows API, except in PHP style:
CreateWindowEx($foo, default, default, $bar, 0, 0, 100, 100, default, default, default, default);
For well-designed functions, there is no need to skip parameters, either with a default keyword or with named parameters.
So it’s a firm -1 from me. The solution to horrid APIs isn’t to add kludges to the language that make them slightly less painful. The solution is to fix them, or add new APIs, that are well designed.
Thanks!
--
Andrea Faulds
http://ajf.me/
Hi!
Yes, they complement one another. Both exist because of horrible
APIs. But I don’t think we should encourage horrible APIs.
You can create horrible APIs with this, but you can also create them
without this. This doesn't make it any more likely, it just makes
working with optional parameters easier.
For well-designed functions, there is no need to skip parameters,
either with a default keyword or with named parameters.
I disagree with that and in general I disagree with the stance "I don't
need this so the language does not need that". We can and should have a
wider look than personal needs and preferences. There are many cases
where optional parameters have their place, and making them more
convenient is a good thing. As a witness to that, most of the languages
with this syntax model (I'm not talking about the likes of Lisp of
course) do allow optional parameters, and making it easy to work with
them is a very frequently requested (and implemented) feature. You can,
of course, say these all people are wrong and their code is horrible,
but this is the reality of what people want and what they use. They'll
do it whether you like it or not, but with this RFC it would be less
painful. For me, it is a clear win.
--
Stas Malyshev
smalyshev@gmail.com
Hi Stas,
Hi!
Yes, they complement one another. Both exist because of horrible
APIs. But I don’t think we should encourage horrible APIs.You can create horrible APIs with this, but you can also create them
without this. This doesn't make it any more likely, it just makes
working with optional parameters easier.
Sure, but things like this make such APIs easier to work with. That’s not a good thing.
For well-designed functions, there is no need to skip parameters,
either with a default keyword or with named parameters.I disagree with that and in general I disagree with the stance "I don't
need this so the language does not need that”.
It’s not that I don’t need this… there are some horrible APIs I’ve used which would be slightly (but only slightly) more pleasant to use with this feature. But I don’t think we should add features to the language to work around poor API design. We should get better APIs instead.
We can and should have a
wider look than personal needs and preferences. There are many cases
where optional parameters have their place, and making them more
convenient is a good thing.
There are places where optional parameters are good. I never said they were bad. This RFC doesn’t help with optional parameters, it helps with excessive numbers of them, or optional parameters with weird default values. I don’t think that it is necessary to have parameter skipping for a well-designed API. If the default values are obvious and intuitive, as they should be, you don’t need “default”. If there is not an excessive number of parameters, you don’t need “default”.
If your function takes so many arguments that you need “default”, you should probably reconsider your function’s signature. If someone else’s function does so, you should probably either fix it for them or write a wrapper function, so people trying to read and maintain your code don’t gradually go insane.
As a witness to that, most of the languages
with this syntax model (I'm not talking about the likes of Lisp of
course) do allow optional parameters, and making it easy to work with
them is a very frequently requested (and implemented) feature.
Well, some of the languages. Others have decided that named parameters aren’t a good idea.
You can,
of course, say these all people are wrong and their code is horrible,
but this is the reality of what people want and what they use. They'll
do it whether you like it or not, but with this RFC it would be less
painful. For me, it is a clear win.
I’m not sure if this RFC actually would make such functions that much less painful. For functions with a lot of default parameters, telling them apart is key. Seeing “NULL, FALSE, FALSE, 0, NULL” may orient the user better when scanning a parameter list than “default, default, default, default, default” would.
Thanks!
Andrea Faulds
http://ajf.me/
Hi!
Sure, but things like this make such APIs easier to work with. That’s
not a good thing.
For me, it is. Your stance is "if it's not ideal (in my opinion) design,
we should not do anything to make it better". I think it's wrong - there
are many opinions about what ideal design is, and yours has no inherent
advantage over others. Removing the existing pain is always good for me,
and telling people "rewrite all your code or live with the pain forever"
is not a good practical stance. It may feel very purist and satisfying -
"here we showed these horrible people how to do things right!" - but
practically it is next to useless. PHP has always been a practical and
not theory-purist language, and this IMO falls directly in this category.
There are places where optional parameters are good. I never said
they were bad. This RFC doesn’t help with optional parameters, it
helps with excessive numbers of them, or optional parameters with
"Excessive" is a matter of opinion. If you have more than one of them,
this RFC is helpful.
Well, some of the languages. Others have decided that named
parameters aren’t a good idea.
I don't think the majority of PHP users here on your side:
http://programmers.stackexchange.com/questions/27564/what-features-would-you-like-to-have-in-php
Neither probably would be a majority of Python users. Or Ruby users. Of
course, you can say all these people are horrible programmers who know
nothing about designing APIs, but I'm afraid if you exclude all these
from consideration when you design language features I'll get pretty
lonely.
them apart is key. Seeing “NULL, FALSE, FALSE, 0, NULL” may orient
the user better when scanning a parameter list than “default,
default, default, default, default” would.
Nobody would use "default, default, default, default" because that's
meaningless, you could just not put them in. $foo, default, $bar would
be much more frequent case, and that's what it is for. You can, of
course, get it to absurd lengths, but so can be done to any feature.
--
Stas Malyshev
smalyshev@gmail.com
Hi,
Stanislav, great RFC. A huge part of core PHP API would benefit of
parameter skipping.
Andrea Faulds,
It’s not that I don’t need this… there are some horrible APIs I’ve used
which would be slightly (but only slightly) more pleasant to use with this
feature. But I don’t think we should add features to the language to work
around poor API design. We should get better APIs instead.
Not sure how this RFC rant is helpful since it's based on completely unreal
alternatives. This "We should get better APIs instead" suggestion, in
practice, means a ton of BC breaks that will never happen on PHP global
functions for obvious reasons.
2015-01-05 19:51 GMT-03:00 Stanislav Malyshev smalyshev@gmail.com:
Hi!
Sure, but things like this make such APIs easier to work with. That’s
not a good thing.For me, it is. Your stance is "if it's not ideal (in my opinion) design,
we should not do anything to make it better". I think it's wrong - there
are many opinions about what ideal design is, and yours has no inherent
advantage over others. Removing the existing pain is always good for me,
and telling people "rewrite all your code or live with the pain forever"
is not a good practical stance. It may feel very purist and satisfying -
"here we showed these horrible people how to do things right!" - but
practically it is next to useless. PHP has always been a practical and
not theory-purist language, and this IMO falls directly in this category.There are places where optional parameters are good. I never said
they were bad. This RFC doesn’t help with optional parameters, it
helps with excessive numbers of them, or optional parameters with"Excessive" is a matter of opinion. If you have more than one of them,
this RFC is helpful.Well, some of the languages. Others have decided that named
parameters aren’t a good idea.I don't think the majority of PHP users here on your side:
http://programmers.stackexchange.com/questions/27564/what-features-would-you-like-to-have-in-php
Neither probably would be a majority of Python users. Or Ruby users. Of
course, you can say all these people are horrible programmers who know
nothing about designing APIs, but I'm afraid if you exclude all these
from consideration when you design language features I'll get pretty
lonely.them apart is key. Seeing “NULL, FALSE, FALSE, 0, NULL” may orient
the user better when scanning a parameter list than “default,
default, default, default, default” would.Nobody would use "default, default, default, default" because that's
meaningless, you could just not put them in. $foo, default, $bar would
be much more frequent case, and that's what it is for. You can, of
course, get it to absurd lengths, but so can be done to any feature.--
Stas Malyshev
smalyshev@gmail.com
Hi Marcio,
Not sure how this RFC rant is helpful since it's based on completely unreal
alternatives. This "We should get better APIs instead" suggestion, in
practice, means a ton of BC breaks that will never happen on PHP global
functions for obvious reasons.
I’m not saying change existing APIs. I’m saying add new, parallel ones. We’ve done this before, we can do it again. It doesn’t break BC.
Andrea Faulds
http://ajf.me/
I’m not saying change existing APIs. I’m saying add new, parallel ones.
We’ve done this before, we can do it again. It doesn’t break BC.
Makes sense to have new better overlapping APIs while old ones are slowly
deprecated (which is still a (delayed) BC break). Thanks for clarifying
this, anyway.
But I still disagree when you say that parameter skipping would
instantly "encourage
horrible APIs". That's a huge stretch, IMMO, unless you have any real case
to support such statement.
2015-01-05 20:17 GMT-03:00 Andrea Faulds ajf@ajf.me:
Hi Marcio,
Not sure how this RFC rant is helpful since it's based on completely
unreal
alternatives. This "We should get better APIs instead" suggestion, in
practice, means a ton of BC breaks that will never happen on PHP global
functions for obvious reasons.I’m not saying change existing APIs. I’m saying add new, parallel ones.
We’ve done this before, we can do it again. It doesn’t break BC.Andrea Faulds
http://ajf.me/
If the default values are obvious and intuitive, as they should be, you don’t need “default”.
It's not always a case of not knowing what the default values are;
sometimes it's a case of not knowing - and not wanting to worry about -
what they might be in the future.
For instance, you might have an integer parameter representing some kind
of cost-benefit tradeoff, with a "best practice" value as default, which
happened to be the second of 3 well-defined parameters. To specify the
third parameter, you need some way of saying "I'll accept the best
practice for the second parameter, thanks".
There are a few options we can consider:
- You just hard-code the current documented value, leaving a comment
that you have no idea what it means, or whether it might change. Clearly
not optimal. - The library allows some special-case value, such as NULL, to be
passed. Not particularly readable, because it's not clear whatNULL
means in this context, or whether you've just messed up and it will be
coerced to int(0). On the other hand, allows calling with a variable set
toNULL
(or other magic value) to select the default behaviour at run-time. - The library defines a constant containing the default value, such as
DEFAULT_FOO_COST. More readable, but relies on the library author having
a good naming convention so that you don't have to keep going to the
manual to find it. - The proposed "default" keyword. More explicit than NULL, supported
out-the-box without any effort on the part of the library author, lets
you get on with your job. On the other hand, doesn't address the case
where you want to select the default at run-time, e.g. foo('bar',
$_GET['cost'] ?? default, 'baz') doesn't work; this is however true of
existing optional parameters, it's just that they can only come at the
end of the list.
I’m not sure if this RFC actually would make such functions that much less painful. For functions with a lot of default parameters, telling them apart is key. Seeing “NULL, FALSE, FALSE, 0, NULL” may orient the user better when scanning a parameter list than “default, default, default, default, default” would.
A list of all defaults is clearly a straw man, since it would be a daft
use of this feature. However, "10, null, default, 0" is clearer in its
intent than "10, null, false, 0" - the 1st, 2nd and 4th parameters have
been specifically chosen by the programmer, while the 3rd is left to the
implementation to choose.
Named parameters do seem to offer a solution to a lot of the same use
cases, but they have their drawbacks too - for instance, currently,
parameter names are implementation details private to the function, and
a straight implementation of named parameters would make them public
overnight. However, as Stas says, the two mechanisms can coexist and
complement each other, and if we get both it can be left to a matter of
personal taste or style guides.
--
Rowan Collins
[IMSoP]