Hi internals!
I'd like to propose an RFC, which adds dedicated syntax for variadic
functions:
https://wiki.php.net/rfc/variadics
Basically this allows declaring variadics directly in the function
signature, rather than fetching the arguments using func_get_args()
.
Example:
public function query($query, ...$params) { /* ... */ }
What are your thoughts on this?
Thanks,
Nikita
2013/8/28 Nikita Popov nikita.ppv@gmail.com
Hi internals!
I'd like to propose an RFC, which adds dedicated syntax for variadic
functions:https://wiki.php.net/rfc/variadics
Basically this allows declaring variadics directly in the function
signature, rather than fetching the arguments usingfunc_get_args()
.
Example:public function query($query, ...$params) { /* ... */ }
What are your thoughts on this?
+1, primarily because it makes the code self-documented.
However, I would like to hilight one shortcoming of variadic functions
(both with the old and with the proposed syntax): There is no way to call a
variadic function unless all the arguments are hard-coded.
I am extenting the example of the RFC:
class MySQL implements DB {
public function query($query, ...$params) {
// ...
}
public function query_and_log($query, ...$params) {
// this will not work:
$result = $this->query( $query, $params );
log( $query );
return $result;
}
}
Not only this does not work, but there is no way to make it work without
modifying the original function. Would it be possible to extend the RFC
with new syntax that could cover cases like that as well? Maybe something
like that:
$result = $this->query( $query, ...$params );
Other than that, the RFC is very welcome.
Lazare INEPOLOGLOU
Ingénieur Logiciel
Thanks,
Nikita
On Wed, Aug 28, 2013 at 6:18 PM, Lazare Inepologlou linepogl@gmail.comwrote:
Not only this does not work, but there is no way to make it work without
modifying the original function. Would it be possible to extend the RFC
with new syntax that could cover cases like that as well? Maybe something
like that:$result = $this->query( $query, ...$params );
I will implement this, but in a separate RFC :) [Later today or tomorrow]
Nikita
Hi internals!
Hi Nikita :-),
I'd like to propose an RFC, which adds dedicated syntax for variadic
functions:https://wiki.php.net/rfc/variadics
Basically this allows declaring variadics directly in the function
signature, rather than fetching the arguments usingfunc_get_args()
.
Example:public function query($query, ...$params) { /* ... */ }
What are your thoughts on this?
Huge +1!
So if we call query('foo'), $params is set to an empty array, right?
Could it be possible to change this behavior? Would it be interesting?
For example: public function query($query, ...$params = null).
Cheers.
--
Ivan Enderlin
Developer of Hoa
http://hoa-project.net/
PhD. student at DISC/Femto-ST (Vesontio) and INRIA (Cassis)
http://disc.univ-fcomte.fr/ and http://www.inria.fr/
Member of HTML and WebApps Working Group of W3C
http://w3.org/
Hi internals!
I'd like to propose an RFC, which adds dedicated syntax for variadic
functions:
...What are your thoughts on this?
I think it's great way to clean things up and add some subtle new
functionality, particularly with Lazare's follow-up proposal about
expanding an indexed array into arguments.
Would any functions get deprecated as a result of this? e.g., func_get_args()
I assume it's a syntax error to do function fn(...$foo, $bar) or
function fn(...$foo, ...$bar)
I assume that function fn($a, $b = null, ...$c) is possible, and the
only way to populate $c is to call fn with three or more parameters.
--
Matthew Leverton
Am 28.08.2013 21:27, schrieb Matthew Leverton:
<snip>Would any functions get deprecated as a result of this? e.g.,
<snip>func_get_args()
It's not a good idea to deprecate the function
func_get_args/func_num_args() because it is used in user land code to
detect if a function was called with a specific argument like the following:
function (&$argByRef = null) {
if (func_num_args() > 1) {
// do expensive stuff to set $argByRef
$argByRef = true;
}
return false;
}
On Wed, Aug 28, 2013 at 9:27 PM, Matthew Leverton leverton@gmail.comwrote:
Would any functions get deprecated as a result of this? e.g.,
func_get_args()
Nope, func_get_args()
etc stay. This is now mentioned in
https://wiki.php.net/rfc/variadics#userland.
I assume it's a syntax error to do function fn(...$foo, $bar) or
function fn(...$foo, ...$bar)
Correct. This is now mentioned in
https://wiki.php.net/rfc/variadics#syntactic_restrictions.
I assume that function fn($a, $b = null, ...$c) is possible, and the
only way to populate $c is to call fn with three or more parameters.
That's also correct :)
Nikita
How about having the ellipsis after the variable? That then coincides
with phpDocumentor's recommended syntax of "$c,..." and it keeps any
typehint or & with the variable name ("array &$arr..." versus "array
&...$arr") and, honestly, I think that reads more easily.
On Wed, Aug 28, 2013 at 9:27 PM, Matthew Leverton <leverton@gmail.com
wrote:
Would any functions get deprecated as a result of this? e.g.,
func_get_args()
Nope,
func_get_args()
etc stay. This is now mentioned in
https://wiki.php.net/rfc/variadics#userland.I assume it's a syntax error to do function fn(...$foo, $bar) or
function fn(...$foo, ...$bar)Correct. This is now mentioned in
https://wiki.php.net/rfc/variadics#syntactic_restrictions.I assume that function fn($a, $b = null, ...$c) is possible, and the
only way to populate $c is to call fn with three or more parameters.That's also correct :)
Nikita
How about having the ellipsis after the variable? That then coincides
with phpDocumentor's recommended syntax of "$c,..."
That syntax has it neither before nor after, because there is no parameter
name.
and it keeps any typehint or & with the variable name ("array &$arr..."
versus "array &...$arr") and, honestly, I think that reads more easily.
Please see the https://wiki.php.net/rfc/variadics#choice_of_syntax section
of the RFC. Quoting: "With ref-modifier (&$args...) this does not show well
that the individual arguments are references, rather than $args itself.
With typehint (array $args...) it also looks like the typehint applies to
$args itself rather than all variadic arguments."
Thanks,
Nikita
Hi!
I like the idea, the concept of capturing "rest of args" is pretty
common. But couldn't we in addition have func_get_args()
be able to
receive an int argument that would produce "the rest" in an easier way
for those that prefer func_ger_args()?
I wonder if this makes harder to implement named argument in the future
- which I think we still need to be looking at - but so far doesn't look
like it presents any additional problem compared tofunc_get_args()
.
For prototype checks, this:
public function query($query, ...$params);
public function query($query, $param = null, ...$params);
Should be compatible. Same with:
public function query($query, ...$params);
public function query($query);
functions should be able to ignore some arguments, especially ones that
are optional anyway. I also think this:
public function query($query, ...$params)
public function query(...$params)
should be legal too.
I think it should also be explicitly specified what $params is if there
is no arguments - null? false? array()? I'd probably prefer array as it
makes it easy to do something like:
public __construct(...$params) {
foreach($params as $k => $v) { $this->$k = $v; }
}
but in any way it should be specified.
I didn't look at the implementation yet, so I'll add comments on that
later.
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
functions should be able to ignore some arguments, especially ones that
are optional anyway.
This is not the current behavior, so why should we change it? See:
1 <?php
2
3 interface TestInterface {
4 function query($params = null);
5 }
6
7 class TestImplementation implements TestInterface {
8 function query() {
9
10 }
11 }
Fatal error: Declaration of TestImplementation::query() must be compatible
with that of TestInterface::query() in
/Users/levijm/Projects/HighlightPHP/tmp.php on line 7
Hi!
functions should be able to ignore some arguments, especially ones that are optional anyway.
This is not the current behavior, so why should we change it? See:
Because it makes no sense?
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
On Thu, Aug 29, 2013 at 12:09 AM, Stas Malyshev smalyshev@sugarcrm.comwrote:
Hi!
I like the idea, the concept of capturing "rest of args" is pretty
common. But couldn't we in addition havefunc_get_args()
be able to
receive an int argument that would produce "the rest" in an easier way
for those that prefer func_ger_args()?
I would do that if this RFC doesn't pass, but I don't see much point doing
both things (syntax + extra arg). Are there any particular scenarios where
using func_get_args()
would be preferable?
For prototype checks, this:
public function query($query, ...$params); public function query($query, $param = null, ...$params);
Should be compatible.
It already is. Only requirement is that the typehint/by-ref-mode of
$param=null is compatible with the typehint/by-ref-mode of ...$params :)
Same with:
public function query($query, ...$params); public function query($query);
functions should be able to ignore some arguments, especially ones that
are optional anyway. I also think this:public function query($query, ...$params)
public function query(...$params)should be legal too.
I would like to stay consistent with the normal PHP behavior here. PHP
currently doesn't allow leaving off (required or optional) parameters. I
created a separate thread regarding that issue:
http://markmail.org/message/ejgmqjnjnbmfnuzv If we decide to allow having
less parameters there, then I'll follow suit here as well.
I think it should also be explicitly specified what $params is if there
is no arguments - null? false? array()? I'd probably prefer array as it
makes it easy to do something like:public __construct(...$params) {
foreach($params as $k => $v) { $this->$k = $v; }
}but in any way it should be specified.
Now specified in
https://wiki.php.net/rfc/variadics#population_of_variadic_parameter: The
default is an empty array.
Thanks for the comments,
Nikita
-----Original Message-----
From: Nikita Popov [mailto:nikita.ppv@gmail.com]
Sent: Thursday, August 29, 2013 3:03 PM
To: Stas Malyshev
Cc: PHP internals
Subject: Re: [PHP-DEV] [RFC] Syntax for variadic functionsOn Thu, Aug 29, 2013 at 12:09 AM, Stas Malyshev
smalyshev@sugarcrm.comwrote:Hi!
I like the idea, the concept of capturing "rest of args" is pretty
common. But couldn't we in addition havefunc_get_args()
be able to
receive an int argument that would produce "the rest" in an easier way
for those that prefer func_ger_args()?I would do that if this RFC doesn't pass, but I don't see much point
doing
both things (syntax + extra arg). Are there any particular scenarios
where
usingfunc_get_args()
would be preferable?
Admittedly I'm (very) late to the game, but admittedly #2 - I actually
just noticed this thread as it went up for a vote.
Personally I find Stas's direction preferable to introducing new semantics
- mainly because I think that with every new piece of syntax we make the
language a tad bit more complex no matter what.
Conversely, adding an optional argument tofunc_get_args()
sticks with the
same spirit we've had for years regarding variadic functions, and arguably
is more versatile. Assuming we implement a [, start[, end]] syntax
support, then you can more granularly split exactly the offsets you want -
in case you don't want all of them in one array (which would require a
call toarray_slice()
using the new syntax). Before you jump and say it's
not such a common case - I agree - I said arguably :)
Zeev
2013/8/28 Nikita Popov nikita.ppv@gmail.com:
Hi internals!
I'd like to propose an RFC, which adds dedicated syntax for variadic
functions:https://wiki.php.net/rfc/variadics
Basically this allows declaring variadics directly in the function
signature, rather than fetching the arguments usingfunc_get_args()
.
Example:public function query($query, ...$params) { /* ... */ }
What are your thoughts on this?
Thanks,
Nikita
Using the current variadic functions makes it possible to use 0 or N
arguments, e.g.:
function sum() {
return array_sum(func_get_args());
}
echo sum(10, 5); // echoes 15
echo sum(); // echoes 0
I see nowhere in the RFC whether:
function sum(...$params) { /* */ }
Requires at minimum one argument or none.
I have the feeling that you imply it's minimum one which I would
consider a bit inconsistent with the current "implementation".
Can you please clarify this Nikita?
Thanks
Nikita Popov wrote:
I'd like to propose an RFC, which adds dedicated syntax for variadic
functions:https://wiki.php.net/rfc/variadics
I can remember in PHP4 days, passing parameters to the database as a string of
variables was the norm. Then arrays came along and it was preferable to pass the
query followed by an array of values. We could take the array and validate the
data in a function, adding any missing values needed before processing the SQL.
Going back to the cumbersum method of working just seems wrong? Surely we should
be promoting a tidier method of working?
--
Lester Caine - G8HFL
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk
Lester's position seems unclear but I'll weigh-in. Having strict interfaces
and arguments means that the developer does not have to parse and validate
each parameter that is arbitrarily passed in. If anything, I would prefer to
see func_get_args()
removed entirely. Now, I know that won't happen but I
don't think extending the associated functionality to be more vague is a
good choice.
-----Original Message-----
From: Lester Caine [mailto:lester@lsces.co.uk]
Sent: Thursday, August 29, 2013 7:52 AM
To: PHP internals
Subject: Re: [PHP-DEV] [RFC] Syntax for variadic functions
Nikita Popov wrote:
I'd like to propose an RFC, which adds dedicated syntax for variadic
functions:https://wiki.php.net/rfc/variadics
I can remember in PHP4 days, passing parameters to the database as a string
of variables was the norm. Then arrays came along and it was preferable to
pass the query followed by an array of values. We could take the array and
validate the data in a function, adding any missing values needed before
processing the SQL.
Going back to the cumbersum method of working just seems wrong? Surely we
should be promoting a tidier method of working?
--
Lester Caine - G8HFL
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk
https://wiki.php.net/rfc/variadics
Interesting idea, expanding on:
function log($message, ...$options) {}
It would seem convenient to allow ...$options to be passed as a key-value array of arguments as well:
function logA($message, ...$options[]) { echo count($options); }
logA("foo"); // 0
logA("foo", 1, 2); // 2
logA("foo", array(1,2,3)); // 3
The difference here is that variadic options is declared as an optional array, it would not support a 'typehint' forcing all arguments to be of the same type.
It could be a way to support ~ named parameters
// requires at least 1 argument named as 'level'
function logB($message, ...$options['level']) {
echo $options['level'] .' '. count($options);
}
logB("foo"); // fails: 'level' argument missing
logB("foo", 'notice'); //notice 1
logB("foo", ['level' => 'notice']); // notice 1
logB("foo", 'notice', 'extra'); // notice 2
logB("foo", ['level' => 'notice'], 'extra'); // notice 2
// requires min 2 arguments
function logC($message, ...$options['level','priority']) {
echo 'level:'. $options['level'];
echo 'priority:'. $options['priority'];
}
logC("foo", "notice", 4);
logC("foo", ['level' => 'notice', 'priority' => 4]);
That would remove the need for a "splat" or "scatter" operator. The declaration "...$options[]" would mean, I accept an array of arguments followed by extra arguments
2013/8/30 jbondc@openmv.com jbondc@openmv.com
https://wiki.php.net/rfc/variadics
Interesting idea, expanding on:
function log($message, ...$options) {}
It would seem convenient to allow ...$options to be passed as a key-value
array of arguments as well:
function logA($message, ...$options[]) { echo count($options); }logA("foo"); // 0
logA("foo", 1, 2); // 2
logA("foo", array(1,2,3)); // 3The difference here is that variadic options is declared as an optional
array, it would not support a 'typehint' forcing all arguments to be of the
same type.
It could be a way to support ~ named parameters// requires at least 1 argument named as 'level'
function logB($message, ...$options['level']) {
echo $options['level'] .' '. count($options);
}logB("foo"); // fails: 'level' argument
missing
logB("foo", 'notice'); //notice 1
logB("foo", ['level' => 'notice']); // notice 1
logB("foo", 'notice', 'extra'); // notice 2
logB("foo", ['level' => 'notice'], 'extra'); // notice 2// requires min 2 arguments
function logC($message, ...$options['level','priority']) {
echo 'level:'. $options['level'];
echo 'priority:'. $options['priority'];
}
logC("foo", "notice", 4);
logC("foo", ['level' => 'notice', 'priority' => 4]);That would remove the need for a "splat" or "scatter" operator. The
declaration "...$options[]" would mean, I accept an array of arguments
followed by extra arguments
I'd recommend to use an object, or separate parameters instead. Thats not a
use-case for argument-lists.
Regards
Sebastian
--
Hi internals!
I'd like to propose an RFC, which adds dedicated syntax for variadic
functions:https://wiki.php.net/rfc/variadics
Basically this allows declaring variadics directly in the function
signature, rather than fetching the arguments usingfunc_get_args()
.
Example:public function query($query, ...$params) { /* ... */ }
What are your thoughts on this?
I'd like to go forward with voting on this. Are there any issues that still
need to be resolved?
Nikita
I'd like to go forward with voting on this. Are there any issues that still
need to be resolved?Assuming the RFC as-is represents the current state, I'm +1 on all of it.
I'm not a fan of some of the proposed alterations which would translate
arrays (a la call_user_func_array()
). To clarify, the following output is
what I'd expect:
function f(...$args) {
echo count($args);
}
f(1,2,3); // 3
f([1,2,3]); // 1
Not "3" in both cases.
-Sara
I'd like to go forward with voting on this. Are there any issues that
still
need to be resolved?Assuming the RFC as-is represents the current state, I'm +1 on all of it.
I'm not a fan of some of the proposed alterations which would translate
arrays (a lacall_user_func_array()
). To clarify, the following output is
what I'd expect:
function f(...$args) {
echo count($args);
}
f(1,2,3); // 3
f([1,2,3]); // 1Not "3" in both cases.
Yes, that's the output you'll get. If it weren't the case it would be
impossible to define a function accepting multiple array arguments like
f([1, 2, 3], [4, 5, 6], [7, 8, 9]).
Nikita
Assuming the RFC as-is represents the current state, I'm +1 on all of it.
I'm not a fan of some of the proposed alterations which would translate
arrays (a lacall_user_func_array()
). To clarify, the following output is
what I'd expect:
function f(...$args) {
echo count($args);
}
f(1,2,3); // 3
f([1,2,3]); // 1Not "3" in both cases.
Yes, that's the output you'll get. If it weren't the case it would be
impossible to define a function accepting multiple array arguments like
f([1, 2, 3], [4, 5, 6], [7, 8, 9]).Right, that was exactly the ambiguity I was unfond of. Glad that was as I
hoped. Voted +1.