Re: [PATCH] [RFC] Closures and lambda functions in PHP

From: Date: Thu, 19 Jun 2008 13:48:55 +0000
Subject: Re: [PATCH] [RFC] Closures and lambda functions in PHP
References: 1 2  Groups: php.internals 
Request: Send a blank email to internals+get-38397@lists.php.net to get a copy of this message
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.


« previous php.internals (#38397) next »