I don't like "lexical" keyword, because it can be used anywhere in
function (e.q. inside "if" or loop statement), however lexical variables
must be the part of lambda function definition.
We can think about some better syntax, like
function ($x, $y) ($a, $b, $c) {};
function ($x, $y) [$a, $b, $c] {};
I like "|" separator more, but the syntax of definition is not so
important for me. It just must be clean, and the "lexical" keyword
doesn't provide clean definition.
I don't like the idea to add methods at runtime, as it can break shared
data structures in multi-threaded environment.
Thanks. Dmitry.
Federico Lebron wrote:
Hi Dmitry,
As a lowly userspace developer, the | syntax is a bit confusing. If I
see $x, $y | $a, $b, $c, my brain parses it as ($a, ($y | $a), $b, $c),
since , has lower precedence than |. I'd think "syntax error", then
"logical OR", but never "this refers to the variables I want imported to
inside the closures".
Also, I'd like "lexical" a bit more for the same reasons discussed in
the short array syntax ([1,2]) topic: a user faced with function($x, $y
| $a, $b, $c) has nowhere to search for what | means.
I do, however, see the benefit of not changing the scanner and not
breaking opcode caches. Would reusing "parent" be too much of a wtf?
Having little idea of how the internals work, would it be too
complicated to hook "->" so if you say $obj->var(), and var holds a
lambda function, for that function to be called instead of throwing a
syntax error?
I know it seems hackish to add methods at runtime, but this would be to
runkit's method addition what lambdas are to create_function.
IMO it would seem a bit more logical, if $obj->f = function(){echo
"foo";};, to be able to do $obj->f() instead of $f = $obj->f; $f();, and
knowing that $f() won't have access to $this (or at least, I wouldn't
suppose it would in the second case).
I also agree that shipping it with 5.3 would be a bit too rushed, since
this, like any other feature, needs to be debugged thoroughly if it's
going into production (and going to change the API). 5.4 and 6.0 don't
seem so bad, though.
- Federico Lebron
Dmitry Stogov wrote:
Hi Christian,
I took a look into your patch and found it too difficult.
So I implemented another patch (attached) which is based on your ideas.
From user's level of view it does exactly the same except for "lexical"
variables definition. I don't use any new reserver word because every
new reserved word is going to break some user code. I use the special
syntax for lambda function definition instead, which looks much clear
for me. The following code creates a lambda function with arguments $x,
$y and lexical variables $a, $b, $c.
$a = function($x, $y | $a, $b $c) {};
The patch shouldn't affect opcode caches and other extensions as it
doesn't change any structures. It uses the op_array->static_variables
for lexical variables.
The patch also fixes several small issues and adds some missing
functionality which didn't allow preg_replace_callback() (and may be
others) to work with lambda functions. Now the following example works
fine.
<?php
class X {
private function foo($x) {
echo $x;
}
function bar($s) {
return function ($x | $s) {
static $n = 0;
$n++;
$s = $n.':'.$s;
$this->foo($x[0].':'.$s);
};
}
}
$x = new X;
$x = $x->bar("bye\n");
$s = 'abc';
preg_replace_callback('/[abc]/', $x, $s);
?>
It prints:
a:1:bye
b:2:1:bye
c:3:2:1:bye
Of course the patch doesn't break any existent tests.
Please review.
Thanks. Dmitry.
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php