Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:38403 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 6901 invoked from network); 19 Jun 2008 14:37:05 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 19 Jun 2008 14:37:05 -0000 Authentication-Results: pb1.pair.com header.from=dmitry@zend.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=dmitry@zend.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain zend.com designates 212.25.124.162 as permitted sender) X-PHP-List-Original-Sender: dmitry@zend.com X-Host-Fingerprint: 212.25.124.162 mail.zend.com Windows 2000 SP4, XP SP1 Received: from [212.25.124.162] ([212.25.124.162:33665] helo=mx1.zend.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 8D/43-10717-01F6A584 for ; Thu, 19 Jun 2008 10:37:05 -0400 Received: from [10.1.10.8] ([10.1.10.8]) by mx1.zend.com with Microsoft SMTPSVC(6.0.3790.3959); Thu, 19 Jun 2008 17:37:12 +0300 Message-ID: <485A6F0C.4090809@zend.com> Date: Thu, 19 Jun 2008 18:37:00 +0400 User-Agent: Thunderbird 2.0.0.14 (Windows/20080421) MIME-Version: 1.0 To: Federico Lebron CC: Christian Seiler , php-dev List References: <4856A547.3080801@gmx.net> <485A35A0.9050602@zend.com> <485A63C7.5020600@gmail.com> In-Reply-To: <485A63C7.5020600@gmail.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-OriginalArrivalTime: 19 Jun 2008 14:37:12.0508 (UTC) FILETIME=[F61B9FC0:01C8D219] Subject: Re: [PHP-DEV] [PATCH] [RFC] Closures and lambda functions in PHP From: dmitry@zend.com (Dmitry Stogov) 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. >> >> > 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.