err, sorry, to correct my example:

function abc($a) {
 var_export(func_get_args());
}
abc(4, 'a' => 3);

would output array(0 => 4, 'a' => 3)

Greg

Gregory wrote:
Those are some good points. I would say with regard to 3, that we have the same problem (sic) with defining arrays in PHP, in terms of it not being clear what results from array(1, 2, 'a' => $b, 4). Although we could perfectly copy the array definition semantics, I think you're right, that abc(1, 2, 'a' => $b, 3) is not really useful in the first place. So with that in mind, we could stop perfectly duplicating "array definition semantics", and instead have the following:

a) Regular parameters cannot appear after named parameters, i.e. abc(1, 2, 'a' => $b) is fine but abc(1, 'a' => $b, 2) is not

b) Because of this, we can easily see where the named parameters start (and indeed if they are present in the call). Then, you can implicitly add a variable to the end of the stack which points to a hash, which contains the named parameters.

c) Then, func_get_args would be extended to check for the presence of this hash, and when it's there, simply merge it on top of the array it would have returned. Thus, if the function was abc($a) and I called it with abc(4, 'a' => 3) then func_get_args() inside abc would give array(0 => 3, 'a' => 3).

The question I have is if we are not copying the array semantics anymore, whether we should have abc('a' => 3) or abc(a => 3). I personally would prefer 'a' => 3 because that allows for variable parameter names.

Greg

Stanislav Malyshev wrote:
Hi!

The problem however is when an function accepts varargs (usually named
"...")..... if we however bring in strictct-ish naming convention I
don't see any immediate problems....

Varargs shouldn't be a problem and we don't even need ... there - we can just assume every function has implicit ... at the end (more or less what we are doing now). We have the following issues to overcome now:

1. We don't keep the name information on the receiving end. It should be pretty easy to fix - the parser knows the variable names. So instead of a number RECV opcode can just get a name, or maybe have separate name table that corresponds to numbers.

2. We don't have a way to pass the name information on the sending end - right now we use stack, which would not go well with named params. We'd probably have to switch to a hashtable - which would require substantial change to parameter change/receive code - but should be doable. Though introducing a hashtable may have performance impact there.

3. Combining named and un-named params can get weird - i.e. foo(1,2,3) is simple, foo(1, 2, bar => 3) is doable, but foo(1, 2, bar => 3, 4) would be trouble, since it is not clear at all where 4 should go to. Moreover, catching this situation can be non-trivial, as right now parsing nested function calls may not keep enough context for this.

4. varargs can be dealt with by either extending func_get_args() to provide name information or maybe by having some function that returns only those args that do not have matching names (that would make generic options easier to do).




--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to