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

Reply via email to