Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:47075 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 76294 invoked from network); 1 Mar 2010 22:06:16 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 1 Mar 2010 22:06:16 -0000 Authentication-Results: pb1.pair.com header.from=ionut.g.stan@gmail.com; sender-id=pass; domainkeys=bad Authentication-Results: pb1.pair.com smtp.mail=ionut.g.stan@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.220.223 as permitted sender) DomainKey-Status: bad X-DomainKeys: Ecelerity dk_validate implementing draft-delany-domainkeys-base-01 X-PHP-List-Original-Sender: ionut.g.stan@gmail.com X-Host-Fingerprint: 209.85.220.223 mail-fx0-f223.google.com Received: from [209.85.220.223] ([209.85.220.223:61693] helo=mail-fx0-f223.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 9C/6B-16552-65A3C8B4 for ; Mon, 01 Mar 2010 17:06:14 -0500 Received: by fxm23 with SMTP id 23so652677fxm.23 for ; Mon, 01 Mar 2010 14:06:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from :user-agent:mime-version:to:subject:references:in-reply-to :content-type:content-transfer-encoding; bh=L/FgI+L0h8H/xYp9CC+LcUWr38SYN8KsCRWK4cAb5LE=; b=mYsyTFJN01ptdW4kC1g/AhsughjgHJyvrenWJkguSU4DIl/AxOsY6TT7ixilhf26qQ R3RA28kesijwCjRnUQeqIpQgtMI1Uo5qmG1zWyObe51Igb8Jao+NAKodkqL9bhq30usl sYSVEhfwTjce9C/nuG7b3tbrnlyoAO6tAC9z8= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:content-type:content-transfer-encoding; b=PHzcmTA6VWBn7wTRlghziMPIc32MKJw4wvcSVkARjyFbv9WV3GwHp+74+I/GaZ1aZ/ NqHvnDhsTL9UbsU0nxSuraPVHvPK/t7WOJ1v7lYHNOax6SQWpBc1OaSE/sRc3qUGSEZx /dr2lcSBS2HRdLs7MNiYoO/9mp/XQsvOgArIs= Received: by 10.87.69.26 with SMTP id w26mr8378268fgk.39.1267481171569; Mon, 01 Mar 2010 14:06:11 -0800 (PST) Received: from 89-36-11-205.stedu.ro ([89.36.11.205]) by mx.google.com with ESMTPS id l12sm4741502fgb.7.2010.03.01.14.06.10 (version=SSLv3 cipher=RC4-MD5); Mon, 01 Mar 2010 14:06:11 -0800 (PST) Message-ID: <4B8C3AD2.8050102@gmail.com> Date: Tue, 02 Mar 2010 00:08:18 +0200 User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.1.8) Gecko/20100216 Thunderbird/3.0.2 MIME-Version: 1.0 To: internals@lists.php.net References: <4B8BB419.8050402@easyflirt.com> In-Reply-To: <4B8BB419.8050402@easyflirt.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] Closure/lambda semantic comparaison From: ionut.g.stan@gmail.com ("Ionut G. Stan") In my opinion this is consistent with the fact that PHP has no block-scoped variables. The situation is similar with the one in JavaScript. In JavaScript the problem has been solved by Mozilla with so-called let definitions[1], which are block-scoped. 1: https://developer.mozilla.org/en/New_in_JavaScript_1.7#Block_scope_with_let On 3/1/10 2:33 PM, mathieu.suen wrote: > Hi, > > I am proposing a comparison between PHP closure with lisp one. > > First thing to compare is how scope are capture: > Suppose I want to create a function that add. > The common idiom to do it in lisp is: > > (defun adder (x) #'(lambda (y) (+ x y))) > > Then if I want the add3 method you can do: > > (setf (symbol-function 'add3) (adder 3)) > (add3 4) => 7 > > > Now let reproduce that in php: > > $adder = function ($x) {return function ($y) use($x) {return $y + $x;};}; > $add3 = $adder(3); > echo $add3(4); => 7 > > Every thing is fine but let change the adder into a counter : > In lisp you could do: > > (let ((sum 0)) > (defun counter () (setf sum (1+ sum)))) > (counter) => 1 > (counter) => 2 > (counter) => 3 ... > > In other to have the same behavior in PHP you first need to transform > the let into a lambda which make no difference in lisp: > > (funcall #'(lambda (sum) (defun counter () (setf sum (1+ sum)))) 0) > > Now we are ready to do it in PHP. > > $createCounter = function ($sum) { return function () use ($sum) {return > ++$sum;};}; > $counter = $createCounter(0); > $counter(); => 1 > $counter(); => 1 > $counter(); => 1 > ... > > So that's not the expected behavior. > In oder to have the expected behavior you need to add & in front of $sum. > But & is kind of evil since it mimics dynamic scoping: > > $array = array(1, 2, 3); > foreach($array as $pos) > { > $adders[] = function ($x) use (&$pos) { return $pos+ $x;}; > } > > foreach($adders as $addIt) > { > echo $addIt(5); > } > > Thanks for your attention > > -- Mathieu Suen > -- Ionut G. Stan I'm under construction | http://blog.igstan.ro/