Hi internals!
This RFC proposes to add a syntax for argument unpacking:
https://wiki.php.net/rfc/argument_unpacking
Basically, this is the "complement" of the variadics RFC: It is not about
declaring variadic functions, but about calling them.
The syntax it introduces looks as follows:
$db->query($query, ...$params);
Thoughts?
Thanks,
Nikita
Hi internals!
This RFC proposes to add a syntax for argument unpacking:
https://wiki.php.net/rfc/argument_unpacking
Basically, this is the "complement" of the variadics RFC: It is not about
declaring variadic functions, but about calling them.The syntax it introduces looks as follows:
$db->query($query, ...$params);
seems so weird and ugly..
-1
thanks
Thoughts?
Thanks,
Nikita
--
Laruence Xinchen Hui
http://www.laruence.com/
On Fri, Aug 30, 2013 at 11:23 PM, Nikita Popov nikita.ppv@gmail.com
wrote:Hi internals!
This RFC proposes to add a syntax for argument unpacking:
https://wiki.php.net/rfc/argument_unpacking
Basically, this is the "complement" of the variadics RFC: It is not about
declaring variadic functions, but about calling them.The syntax it introduces looks as follows:
$db->query($query, ...$params);
seems so weird and ugly..
-1
thanks
Compared to the current alternatives it's definitely less ugly. I'm all for
this syntax addition.
Laruence <laruence <at> php.net> writes:
On Fri, Aug 30, 2013 at 11:23 PM, Nikita Popov <nikita.ppv <at> gmail.com>
wrote:Hi internals!
This RFC proposes to add a syntax for argument unpacking:
https://wiki.php.net/rfc/argument_unpacking
Basically, this is the "complement" of the variadics RFC: It is not about
declaring variadic functions, but about calling them.The syntax it introduces looks as follows:
$db->query($query, ...$params);
seems so weird and ugly..
-1
I totally agree.. the syntax design doesn't look quiet right. it isn't
readable and ugly.
Since it's unpacking the arguments from the caller, the "..." should be put
after the $params. e.g.
$db->query($query, $params...);
the above approach is also used in Go.
Cheers,
c9s
https://github.com/c9s
Yo-An Lin wrote on 05/06/2015 06:51:
Laruence <laruence <at> php.net> writes:
On Fri, Aug 30, 2013 at 11:23 PM, Nikita Popov <nikita.ppv <at> gmail.com>
wrote:Hi internals!
This RFC proposes to add a syntax for argument unpacking:
https://wiki.php.net/rfc/argument_unpacking
Basically, this is the "complement" of the variadics RFC: It is not about
declaring variadic functions, but about calling them.The syntax it introduces looks as follows:
$db->query($query, ...$params);
seems so weird and ugly..
-1
I totally agree.. the syntax design doesn't look quiet right. it isn't
readable and ugly.Since it's unpacking the arguments from the caller, the "..." should be put
after the $params. e.g.$db->query($query, $params...);
the above approach is also used in Go.
Not sure why you've picked this up now, but the mail you're replying to
is from nearly two years ago, and the syntax in question was accepted,
and released as part of PHP 5.6.0 in August 2014. The documentation can
be found here:
http://php.net/functions.arguments#functions.variable-arg-list
So it's far too late to change the syntax, even if we had a better
reason than "it looks nicer to me with the ... the other side of the name".
Regards,
Rowan Collins
[IMSoP]
Hi!
This RFC proposes to add a syntax for argument unpacking:
https://wiki.php.net/rfc/argument_unpacking
Basically, this is the "complement" of the variadics RFC: It is not about
declaring variadic functions, but about calling them.
This is just another way of doing call_user_func, I'm not sure we really
need it. And something like:
test(1, 2, ...[3, 4], 5, 6, ...[7, 8])
looks plain weird. What would be the use case for doing something like
that? I don't think we should add this.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
On Fri, Aug 30, 2013 at 6:57 PM, Stas Malyshev smalyshev@sugarcrm.comwrote:
And something like:
test(1, 2, ...[3, 4], 5, 6, ...[7, 8])looks plain weird. What would be the use case for doing something like
that?
No use case at all. This is a technical specification, so I write down what
is possible, not necessarily what you'd write in your code. Of course it
makes no sense to write something like ...[1, 2, 3], because you could just
as well write 1, 2, 3 directly. The point of that example is that it's
possible to mix it with normal arguments. The "practical" example for that
is the example in the introduction: $db->query($query, ...$params). Here a
"normal" argument is followed by an unpacked argument.
This is just another way of doing call_user_func, I'm not sure we really
need it.
Assuming you mean call_user_func_array, yes. This is just syntax sugar for
call_user_func_array. Advantages of this syntax over cufa are outlined
here:
https://wiki.php.net/rfc/argument_unpacking#advantages_over_call_user_func_array
Thanks,
Nikita
Hi!
Assuming you mean call_user_func_array, yes. This is just syntax sugar
for call_user_func_array. Advantages of this syntax over cufa are
outlined here:
https://wiki.php.net/rfc/argument_unpacking#advantages_over_call_user_func_array
The only case that I see that could make sense is $db->query($query,
...$params).
Multiple unpackings make no sense to me, as it is impossible to know
which argument ends up where and no corresponding syntax exists on
function side. Also, no other language as far as I can see allows it.
Also, I just noticed the RFC tries to sneak in the exception throwing
in the syntax construct, which we agreed not to do a long time ago and
which was never done in the engine. We shouldn't do this - if you want
to change PHP error handling, it should be in separate RFC for this
purpose.
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
On Fri, Aug 30, 2013 at 7:45 PM, Stas Malyshev smalyshev@sugarcrm.comwrote:
Hi!
Assuming you mean call_user_func_array, yes. This is just syntax sugar
for call_user_func_array. Advantages of this syntax over cufa are
outlined here:https://wiki.php.net/rfc/argument_unpacking#advantages_over_call_user_func_array
The only case that I see that could make sense is $db->query($query,
...$params).
Multiple unpackings make no sense to me, as it is impossible to know
which argument ends up where and no corresponding syntax exists on
function side. Also, no other language as far as I can see allows it.
Not sure I get what you mean. All languages with argument unpacking allow
this. It's not commonly needed, but there are uses for it and I don't see a
reason why one should explicitly disallow doing multiple unpacks.
If you want a practical example for this, consider partial application,
where you bind a number of arguments to a function.
An "old-style" definition for this (no variadics syntax, no argument
unpack) would look like this:
function bind(callable $function) {
$boundArgs = array_slice(func_get_args(), 1);
return function() use ($function, $boundArgs) {
return call_user_func_array(
$function, array_merge($boundArgs, func_get_args()
);
}
}
The equivalent new-style definition with variadics syntax and argument
unpacking:
function bind(callable $function, ...$boundArgs) {
return function(...$args) use($function, $boundArgs) {
return $function(...$boundArgs, ...$args);
}
}
As you can see, here two arguments are unpacked in one call.
Also, I just noticed the RFC tries to sneak in the exception throwing
in the syntax construct, which we agreed not to do a long time ago and
which was never done in the engine. We shouldn't do this - if you want
to change PHP error handling, it should be in separate RFC for this
purpose.
I tried to make sure that this does not "sneak in" but is mentioned
prominently (it's half of the by-ref section). Anyway, as already mentioned
in the RFC: Exceptions are how we deal with errors relating to Traversables
in general. Yes, also in the engine. E.g. in the foreach implementation, if
get_iterator fails an exception is thrown:
http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_vm_def.h#4191
If staying consistent with foreach is not wanted (or this is not considered
"consistent"), I'm also okay to turn that into a fatal error or into a
warning where the argument will simply be passed without the
reference-binding instead (like what we do when you pass a function call
that returns by-value to a by-reference parameter. Though there it's
actually just an E_STRICT.)
Nikita
Hi!
Not sure I get what you mean. All languages with argument unpacking
allow this. It's not commonly needed, but there are uses for it and I
I mean this:
a = [0,3]
range(*a)
[0, 1, 2]
a = [1]; b = [2]
range(*a, *b)
File "<stdin>", line 1
range(*a, *b)
^
SyntaxError: invalid syntax
a=[0]
range(*a, 3)
File "<stdin>", line 1
SyntaxError: only named arguments may follow *expression
don't see a reason why one should explicitly disallow doing multiple
unpacks.
Because it makes very hard to understand what's going on and makes no
sense semantically.
As you can see, here two arguments are unpacked in one call.
This is very special use case to be hidden in library functions, I don't
think we need to have language syntax specially directed at that, at the
cost of making it overall more complex and hard to understand. I can see
what "add all those params at the end" syntax mean. However having
something like ($a, ...$b, $c, ...$d, $e, $f, $g, ...$h) I have no idea
what's going on at all and what is sent where.
I tried to make sure that this does not "sneak in" but is mentioned
prominently (it's half of the by-ref section). Anyway, as already
mentioned in the RFC: Exceptions are how we deal with errors relating to
Traversables in general. Yes, also in the engine. E.g. in the foreach
implementation, if get_iterator fails an exception is thrown:
http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_vm_def.h#4191
This is the only instance of exception in the engine, and it is very
unfortunate. However what is proposed in this RFC is using exception for
one special case of factual argument not matching function definition,
while exceptions are never used in any other case of the same problem.
This is inconsistent and wrong.
If staying consistent with foreach is not wanted (or this is not
How calling a function can be consistent with foreach? Those are
different things. Calling a function should be consistent with all other
cases of calling a function.
considered "consistent"), I'm also okay to turn that into a fatal error
or into a warning where the argument will simply be passed without the
reference-binding instead (like what we do when you pass a function call
that returns by-value to a by-reference parameter. Though there it's
actually just an E_STRICT.)
it should work like other instances of non-ref parameter (i.e. not a
variable and not a function returning by ref) passed to by-ref function.
Namely producing E_STRICT.
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
2013/8/30 Stas Malyshev smalyshev@sugarcrm.com
don't see a reason why one should explicitly disallow doing multiple
unpacks.Because it makes very hard to understand what's going on and makes no
sense semantically.As you can see, here two arguments are unpacked in one call.
This is very special use case to be hidden in library functions, I don't
think we need to have language syntax specially directed at that, at the
cost of making it overall more complex and hard to understand. I can see
what "add all those params at the end" syntax mean. However having
something like ($a, ...$b, $c, ...$d, $e, $f, $g, ...$h) I have no idea
what's going on at all and what is sent where.
I agree with Stas here. If an argument comes after an unpacked array, its
position is not certain until runtime. This makes life difficult for static
analysis tools, which is one of the reasons for introducing the new syntax.
Even in the use case of Nikita, the two arguments to be unpacked come
without any standard arguments between or after them.
I suggest that argument unpacking should be limited to the last arguments
only.
Lazare Inepologlou
Ingénieur Logiciel
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Hi!
Am 31.8.2013 um 00:27 schrieb Lazare Inepologlou linepogl@gmail.com:
2013/8/30 Stas Malyshev smalyshev@sugarcrm.com
don't see a reason why one should explicitly disallow doing multiple
unpacks.Because it makes very hard to understand what's going on and makes no
sense semantically.As you can see, here two arguments are unpacked in one call.
This is very special use case to be hidden in library functions, I don't
think we need to have language syntax specially directed at that, at the
cost of making it overall more complex and hard to understand. I can see
what "add all those params at the end" syntax mean. However having
something like ($a, ...$b, $c, ...$d, $e, $f, $g, ...$h) I have no idea
what's going on at all and what is sent where.I agree with Stas here. If an argument comes after an unpacked array, its
position is not certain until runtime. This makes life difficult for static
analysis tools, which is one of the reasons for introducing the new syntax.
The alternative is for users to use what we have now: call_user_func_array
with some array_merge, which makes it as difficult for static analysis as the
new syntax does. This really is a non-argument.
And should we really restrict the user's code with some arbitrary limits?
It just makes the user use some really ugly hacks nobody wants to see.
Even in the use case of Nikita, the two arguments to be unpacked come
without any standard arguments between or after them.I suggest that argument unpacking should be limited to the last arguments
only.
An example where it really would make sense is:
function long ($arg, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7, $string) {
// do something with your arguments
}
// just instead of copying the seven parameters; increases readability
// and don't argue this would be badly statically analyzable - it is, but this isn't
// the point. I want to show that people may find here some use case.
function short (...$args) {
if (count($args))
return long(...$args, "some value");
}
Lazare Inepologlou
Ingénieur Logiciel--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
I finally am in favor of the proposal, because it allows removing a lot of ugly
call_user_func_array calls which aren't really well readable. (and naturally
because it allows passing the variadic parameters if that rfc will be accepted)
And I think you are really arguing about non-issues.
Example: Multiple uses of unpacking syntax makes sense when you call a
function with a variadic parameter:
function variadic (...$args) {
// do something
}
variadic(...$array1, ...$array2);
Bob Weinand
Hi!
function short (...$args) {
if (count($args))
return long(...$args, "some value");
}
This is exactly the problem. Since $args has undefined number of
arguments, there's no way to determine where "some value" ends up. Which
means it's impossible to understand what's going on here. Now, if we had
named arguments, like python had, then using "some value" as a named
argument might work (and we'd need to see what to do with named
arguments in this case), but as positional argument this just doesn't
make much sense beyond some very esoteric things that nobody uses
directly, without wrapping libraries (like partially applied functions)
- at least in PHP.
And I think you are really arguing about non-issues.
Example: Multiple uses of unpacking syntax makes sense when you call a
function with a variadic parameter:function variadic (...$args) {
// do something
}variadic(...$array1, ...$array2);
Again, since parameters in PHP are positional, they have meaning
depending on position. If you just wanted to pass an array, pass an
array, you don't need to use variadic syntax for that. Variadic syntax
makes sense only if positions there have meanings and you want to give
specific meanings to specific arguments in specific positions. In that
case, ...$array1, ...$array2 doesn't work since you can not have
meaningful positions. Only case where it works if you do functional
operations like partial application, where the meaning of the function
is not important but only the fact that it is a function is important.
But I don't think we need special syntax to do such things.
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Hi!
Am 31.8.2013 um 01:39 schrieb Stas Malyshev smalyshev@sugarcrm.com:
Hi!
function short (...$args) {
if (count($args))
return long(...$args, "some value");
}This is exactly the problem. Since $args has undefined number of
arguments, there's no way to determine where "some value" ends up. Which
means it's impossible to understand what's going on here. Now, if we had
named arguments, like python had, then using "some value" as a named
argument might work (and we'd need to see what to do with named
arguments in this case), but as positional argument this just doesn't
make much sense beyond some very esoteric things that nobody uses
directly, without wrapping libraries (like partially applied functions)
- at least in PHP.
That's why there is an if (count($args)) (I just forgot to add an == 7)
It should read:
function short (...$args) {
if (count($args) == 7)
return long(...$args, "some value");
}
And when you name the example with the "esoteric things", I'd like to have them
in the most readable format possible, which isn't achievable with func_get_args()
.
And I think you are really arguing about non-issues.
Example: Multiple uses of unpacking syntax makes sense when you call a
function with a variadic parameter:function variadic (...$args) {
// do something
}variadic(...$array1, ...$array2);
Again, since parameters in PHP are positional, they have meaning
depending on position. If you just wanted to pass an array, pass an
array, you don't need to use variadic syntax for that. Variadic syntax
makes sense only if positions there have meanings and you want to give
specific meanings to specific arguments in specific positions. In that
case, ...$array1, ...$array2 doesn't work since you can not have
meaningful positions. Only case where it works if you do functional
operations like partial application, where the meaning of the function
is not important but only the fact that it is a function is important.
But I don't think we need special syntax to do such things.
I mean, it looks way cleaner to use this instead of:
call_user_func_array("variadic", array_merge($array1, $array2));
And no, the order isn't always important. Example:
function variadic (...$args) {
return array_reduce($args, function ($a, $b) { return $a*$b; }, 1);
}
Yes, this is a very simple example, but just to show the idea of it.
And even when the order is important, it may be useful:
// according to implementation, arrays are expanded in insertion order here
// https://github.com/nikic/php-src/compare/variadics...splat#L11R3263
$short_default_options = [
"arg1" => 1,
"arg2" => 3,
"arg3" => 7,
];
function short (...$extra_options) {
global $short_default_options; // in classes, this would be a $this->short_options
if (count($args) <= 3)
return long(...$short_default_options, ...$extra_options);
}
function long ($arg1, $arg2, $arg3, $arg4 = 0, $arg5 = 0, $arg6 = 0) {
// do something
}
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Bob Weinand
2013/8/31 Bob Weinand bobwei9@hotmail.com
Hi!
Am 31.8.2013 um 00:27 schrieb Lazare Inepologlou linepogl@gmail.com:
2013/8/30 Stas Malyshev smalyshev@sugarcrm.com
don't see a reason why one should explicitly disallow doing multiple
unpacks.Because it makes very hard to understand what's going on and makes no
sense semantically.As you can see, here two arguments are unpacked in one call.
This is very special use case to be hidden in library functions, I don't
think we need to have language syntax specially directed at that, at the
cost of making it overall more complex and hard to understand. I can see
what "add all those params at the end" syntax mean. However having
something like ($a, ...$b, $c, ...$d, $e, $f, $g, ...$h) I have no idea
what's going on at all and what is sent where.I agree with Stas here. If an argument comes after an unpacked array, its
position is not certain until runtime. This makes life difficult for
static
analysis tools, which is one of the reasons for introducing the new
syntax.The alternative is for users to use what we have now: call_user_func_array
with some array_merge, which makes it as difficult for static analysis as
the
new syntax does. This really is a non-argument.
Please read carefully my argument. The alternative is to actually call the
function normally with the arguments expanded in the code.
In other words, the alternative to this:
strpos( ...$array , 3 ); // which cannot be verified statically
is this:
strpos( $array[0] , $array[1] , 3 ); // which is perfectly verifiable.
The power of this proposal is found when used with optional arguments (or
variadic arguments) which always come last anyway.
Lazare INEPOLOGLOU
Ingénieur Logiciel
And should we really restrict the user's code with some arbitrary limits?
It just makes the user use some really ugly hacks nobody wants to see.Even in the use case of Nikita, the two arguments to be unpacked come
without any standard arguments between or after them.I suggest that argument unpacking should be limited to the last arguments
only.An example where it really would make sense is:
function long ($arg, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7, $string) {
// do something with your arguments
}// just instead of copying the seven parameters; increases readability
// and don't argue this would be badly statically analyzable - it is, but
this isn't
// the point. I want to show that people may find here some use case.
function short (...$args) {
if (count($args))
return long(...$args, "some value");
}Lazare Inepologlou
Ingénieur Logiciel--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227I finally am in favor of the proposal, because it allows removing a lot of
ugly
call_user_func_array calls which aren't really well readable. (and
naturally
because it allows passing the variadic parameters if that rfc will be
accepted)And I think you are really arguing about non-issues.
Example: Multiple uses of unpacking syntax makes sense when you call a
function with a variadic parameter:function variadic (...$args) {
// do something
}variadic(...$array1, ...$array2);
Bob Weinand
Hi!
Am 31.8.2013 um 01:39 schrieb Lazare Inepologlou linepogl@gmail.com:
2013/8/31 Bob Weinand bobwei9@hotmail.com
Hi!Am 31.8.2013 um 00:27 schrieb Lazare Inepologlou linepogl@gmail.com:
2013/8/30 Stas Malyshev smalyshev@sugarcrm.com
don't see a reason why one should explicitly disallow doing multiple
unpacks.Because it makes very hard to understand what's going on and makes no
sense semantically.As you can see, here two arguments are unpacked in one call.
This is very special use case to be hidden in library functions, I don't
think we need to have language syntax specially directed at that, at the
cost of making it overall more complex and hard to understand. I can see
what "add all those params at the end" syntax mean. However having
something like ($a, ...$b, $c, ...$d, $e, $f, $g, ...$h) I have no idea
what's going on at all and what is sent where.I agree with Stas here. If an argument comes after an unpacked array, its
position is not certain until runtime. This makes life difficult for static
analysis tools, which is one of the reasons for introducing the new syntax.The alternative is for users to use what we have now: call_user_func_array
with some array_merge, which makes it as difficult for static analysis as the
new syntax does. This really is a non-argument.Please read carefully my argument. The alternative is to actually call the function normally with the arguments expanded in the code.
In other words, the alternative to this:
strpos( ...$array , 3 ); // which cannot be verified staticallyis this:
strpos( $array[0] , $array[1] , 3 ); // which is perfectly verifiable.The power of this proposal is found when used with optional arguments (or variadic arguments) which always come last anyway.
Lazare INEPOLOGLOU
Ingénieur Logiciel
This also isn't anything it ever would write, because it just doesn't make any sense for two or three arguments.
In my opinion you only should unpack arrays when it's at the end … AND when you can verify how many parameters will be inserted. Just shorter. Because writing:
func($array[0], $array[1], $array[2], $array[3], $array[4], $array[5], $array[6], "value");
is just ugly to write and to read.
if (count($array) == 7)
func(...$array, "value");
is much more readable, I think.
Bob Weinand
On Fri, Aug 30, 2013 at 11:50 PM, Stas Malyshev smalyshev@sugarcrm.comwrote:
If staying consistent with foreach is not wanted (or this is not
How calling a function can be consistent with foreach? Those are
different things. Calling a function should be consistent with all other
cases of calling a function.
Consistent with Traversable error handling. But don't want to argue that,
as I do agree with you that adding the exception there may not be a good
idea.
it should work like other instances of non-ref parameter (i.e. not a
variable and not a function returning by ref) passed to by-ref function.
Namely producing E_STRICT.
"Other instances" do everything ranging from fatal error (not a variable)
over warning (zend_call_function) to E_STRICT
(a function returning
by-value). I suggested a warning because I had the general impression that
we're trying to be more strict about by-reference passing. But if you're
saying that E_STRICT
is the right choice here, then lets go with that. I
adjusted the RFC/implementation to use E_STRICT
instead, see:
https://wiki.php.net/rfc/argument_unpacking#by-reference_passing
a = [1]; b = [2]
range(*a, *b)
File "<stdin>", line 1
range(*a, *b)
^
SyntaxError: invalid syntaxa=[0]
range(*a, 3)
File "<stdin>", line 1
SyntaxError: only named arguments may follow *expression
I wasn't aware that Python had such restrictions. I just checked and found
out that Ruby also had this restriction, but it was removed in version
1.9.1. I couldn't find anything more specific on why they did it though
(how Ruby does language development is a mystery to me. I can't even find
docs...) The ECMAScript Harmony proposal does not seem to have this
restriction. I also tried this in CoffeeScript, which also does not have
the restriction.
don't see a reason why one should explicitly disallow doing multiple
unpacks.Because it makes very hard to understand what's going on and makes no
sense semantically.As you can see, here two arguments are unpacked in one call.
This is very special use case to be hidden in library functions, I don't
think we need to have language syntax specially directed at that, at the
cost of making it overall more complex and hard to understand. I can see
what "add all those params at the end" syntax mean. However having
something like ($a, ...$b, $c, ...$d, $e, $f, $g, ...$h) I have no idea
what's going on at all and what is sent where.
It's possible to use nearly any feature in some totally convoluted way
that nobody can understand. The main usage of the proposed syntax will be
just fn(...$args) or fn($some, $fixed, $arguments, ...$args). In rare cases
it will be fn(...$args1, ...$args2) [the bind example]. That's what you'll
see in code. fn(...$args, $fixed) does not usually make sense, but if it
does for once, why do we need to forbid it? If it doesn't make sense,
people just won't use it, so you won't see it, so you won't have to figure
out what it means. If it does make sense, then understanding it should be
trivial.
Of course, maybe my logic is flawed because I give too much credit to
programmers and assume that they will employ features when reasonable and
not when "hey, why don't I go put a ... in here!"
Anyway, I don't think having a trailing fixed argument is that absurd. A
pretty pointless example off the top of my head would be
$this->query($query . ' LIMIT ?', ...$params, $limit), i.e. just adding
another bound param to a set of existing ones.
I don't really insist on allowing the trailing normal args, because I don't
think they would be useful particularly often, but I just fail to see what
we gain by forbidding them.
Thanks,
Nikita
This is very special use case to be hidden in library functions, I don't
think we need to have language syntax specially directed at that, at the
cost of making it overall more complex and hard to understand. I can see
what "add all those params at the end" syntax mean. However having
something like ($a, ...$b, $c, ...$d, $e, $f, $g, ...$h) I have no idea
what's going on at all and what is sent where.
I can grok this, but I'd rather not have to work through it when
reading someone else's code. The likely code in current versions of
PHP using call_user_func_array()
would almost certainly be clearer
here. So I think I'd prefer to disallow multiple splats in a function
invocation too.
At the risk of sounding even more bitter than normal, you need to
spend more time in ##php with that attitude. ;)
Anyway, I don't think having a trailing fixed argument is that absurd. A
pretty pointless example off the top of my head would be
$this->query($query . ' LIMIT ?', ...$params, $limit), i.e. just adding
another bound param to a set of existing ones.I don't really insist on allowing the trailing normal args, because I don't
think they would be useful particularly often, but I just fail to see what
we gain by forbidding them.
I have pretty much the same readability concern as with multiple
splats — this example is clear, but I'm not sure it's so clear with a
larger, more verbose set of arguments. This seems to require a
slightly sharper eye to me (OK, it'd be better in a fixed width
editor, admittedly):
do_something($a_long_variable, $another_long_variable,
...$hey_a_splat, $something_else, $foo, $bar)
I care less about this than multiple splats, but it's still a concern to me.
Adam, who will send another e-mail momentarily to paint some bikesheds.
2013/8/30 Stas Malyshev smalyshev@sugarcrm.com
Hi!
This RFC proposes to add a syntax for argument unpacking:
https://wiki.php.net/rfc/argument_unpacking
Basically, this is the "complement" of the variadics RFC: It is not about
declaring variadic functions, but about calling them.This is just another way of doing call_user_func, I'm not sure we really
need it. And something like:
test(1, 2, ...[3, 4], 5, 6, ...[7, 8])looks plain weird. What would be the use case for doing something like
that? I don't think we should add this.
Yes, this example is weird, because every argument is hardcoded anyway. I
guess it has been added just for completeness.
A good example would be function forwarding for variadic functions, without
resorting to call_user_func_array.
An even better example is that there would be no need to have both
call_user_func and call_user_func_array in the first place: The former
would be enough. The same applies to userland functions, and I have been
many times in a situation where I had to define two different functions to
cover both cases.
Lazare INEPOLOGLOU
Ingénieur Logiciel
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Hi!
A good example would be function forwarding for variadic functions,
without resorting to call_user_func_array.
What's wrong with "resorting to" call_user_func_array?
call_user_func_array is a PHP function and not some dark magic that one
should avoid using unless it is absolutely must.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
2013/8/30 Stas Malyshev smalyshev@sugarcrm.com
Hi!
A good example would be function forwarding for variadic functions,
without resorting to call_user_func_array.What's wrong with "resorting to" call_user_func_array?
call_user_func_array is a PHP function and not some dark magic that one
should avoid using unless it is absolutely must.
The disadvantages of call_user_func_array are very well described in the
RFC.
Lazare INEPOLOGLOU
Ingénieur Logiciel
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Hi internals!
This RFC proposes to add a syntax for argument unpacking:
https://wiki.php.net/rfc/argument_unpacking
Basically, this is the "complement" of the variadics RFC: It is not about
declaring variadic functions, but about calling them.The syntax it introduces looks as follows:
$db->query($query, ...$params);
Thoughts?
Thanks,
Nikita
can't we use a new cast operator like (unpack) for this instead of the
three dots?
$db->query($query, (unpack) $params); ?
Andrey
The syntax it introduces looks as follows:
$db->query($query, ...$params);
Somebody was going to do this, and it's going to be me. Sorry. We were
doing so well.
I don't like the ellipsis. I could just about deal with it for the
variadic RFC, since it's at least not worlds away from C++ (and there
are other precedents for it, as you noted), but it looks really weird
to me as the splat operator. It looks like you're hesitant to call the
function or ashamed of $params rather than unpacking something.
I know there's a symbol soup issue for by-ref variadic arguments, as
you mentioned in the RFC, but I think that's an unusual enough use
case that * is still the better option — it doesn't break the flow of
the code as much as a three character operator, and while it's no more
visually intuitive than ..., it does have the advantage of being what
Python and Ruby used.
I'm raising this in this thread because I'm more concerned about the
visual impact of it here, but obviously whatever we use as the
operator for one is what we should use for the other, assuming both
RFCs are accepted.
Adam, who is wincing as he sends this at the likely subthread that will ensue.
Big +1 from me, though as Stas pointed out, multiple unpacks in a single
call don't really work with PHP parameter typing, so I'd make that use an
error.
The syntax it introduces looks as follows:
$db->query($query, ...$params);
Somebody was going to do this, and it's going to be me. Sorry. We were
doing so well.I don't like the ellipsis. I could just about deal with it for the
variadic RFC, since it's at least not worlds away from C++ (and there
are other precedents for it, as you noted), but it looks really weird
to me as the splat operator. It looks like you're hesitant to call the
function or ashamed of $params rather than unpacking something.I know there's a symbol soup issue for by-ref variadic arguments, as
you mentioned in the RFC, but I think that's an unusual enough use
case that * is still the better option — it doesn't break the flow of
the code as much as a three character operator, and while it's no more
visually intuitive than ..., it does have the advantage of being what
Python and Ruby used.I'm raising this in this thread because I'm more concerned about the
visual impact of it here, but obviously whatever we use as the
operator for one is what we should use for the other, assuming both
RFCs are accepted.Adam, who is wincing as he sends this at the likely subthread that will
ensue.
hi Nikita!
Hi internals!
This RFC proposes to add a syntax for argument unpacking:
https://wiki.php.net/rfc/argument_unpacking
Basically, this is the "complement" of the variadics RFC: It is not about
declaring variadic functions, but about calling them.The syntax it introduces looks as follows:
$db->query($query, ...$params);
Thoughts?
The more I read these two RFCs (and the previous ones about similar
features), the more I think we really need to find a compromise about
named arguments. Many of the problems (remotely or closely related)
would be solved too.
About the syntax used in these RFCs, I really have to try out the
patch and see if it feels natural, but can't say it while reading the
RFCs... :)
Cheers,
Pierre
@pierrejoye | http://www.libgd.org