Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:47071 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 72166 invoked from network); 1 Mar 2010 13:30:07 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 1 Mar 2010 13:30:07 -0000 Authentication-Results: pb1.pair.com smtp.mail=ekneuss@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=ekneuss@gmail.com; sender-id=pass; domainkeys=bad 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: ekneuss@gmail.com X-Host-Fingerprint: 209.85.220.223 mail-fx0-f223.google.com Received: from [209.85.220.223] ([209.85.220.223:62030] helo=mail-fx0-f223.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 92/A8-16552-E51CB8B4 for ; Mon, 01 Mar 2010 08:30:06 -0500 Received: by fxm23 with SMTP id 23so98063fxm.23 for ; Mon, 01 Mar 2010 05:30:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:sender:received:in-reply-to :references:date:x-google-sender-auth:message-id:subject:from:to:cc :content-type:content-transfer-encoding; bh=wt3v0Ydcree3JWPOW74IFVUabvWxGfE+Ddv8hk5Y+kY=; b=Kn+v3JI29kbVQtAY0FaGeDcnh5p9zarTOdssf5HV7yMUHWpLm4I3muiKsHfYXDBzsn H18LGGFxmwLS8NSgfik+wVsHnzSJj3xAbmRHHA/R4WtC/R1YepBiAdjJS9l23jJU9f2N ThI5EKjUisR4vAB49zwB1pK8LSwPcP1DEcFeY= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type :content-transfer-encoding; b=U47T2jE7YPuF+ioCu1C0Uxs/i6+IGRtVpR/p/jh9tU/Yk+9ss3aJ6TE7ERtr8nERKH kx+7dnXRLPpCLIHNQY1mh67bpzldmA/FFqNSCtlVE1ChPfzm6ed2PDrLvtDkccQxaS06 h6prp2HeLEXUOB+FEC/GAVF3K/wqv9FNKYQ0E= MIME-Version: 1.0 Sender: ekneuss@gmail.com Received: by 10.87.40.2 with SMTP id s2mr576764fgj.72.1267450203032; Mon, 01 Mar 2010 05:30:03 -0800 (PST) In-Reply-To: <4B8BB419.8050402@easyflirt.com> References: <4B8BB419.8050402@easyflirt.com> Date: Mon, 1 Mar 2010 14:30:02 +0100 X-Google-Sender-Auth: dfe534203522f626 Message-ID: To: "mathieu.suen" Cc: internals@lists.php.net Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] Closure/lambda semantic comparaison From: colder@php.net (Etienne Kneuss) Hello, On Mon, Mar 1, 2010 at 1:33 PM, mathieu.suen w= rote: > 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) =3D> 7 > > > Now let reproduce that in php: > > $adder =3D function ($x) {return function ($y) use($x) =A0{return $y + $x= ;};}; > $add3 =3D $adder(3); > echo $add3(4); =3D> 7 > > Every thing is fine but let change the adder into a counter : > In lisp you could do: > > (let ((sum 0)) > =A0 =A0 (defun counter () (setf sum (1+ sum)))) > (counter) =3D> 1 > (counter) =3D> 2 > (counter) =3D> 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 =3D function ($sum) { return function () use ($sum) {retur= n > ++$sum;};}; > $counter =3D $createCounter(0); > $counter(); =3D> 1 > $counter(); =3D> 1 > $counter(); =3D> 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 =3D array(1, 2, 3); > foreach($array as $pos) > { > =A0 $adders[] =3D function ($x) use (&$pos) { return $pos+ $x;}; > } > > foreach($adders as $addIt) > { > =A0echo $addIt(5); > } > use($var) will import by copy, so you won't have the behavior you expect. If you want to keep a value in a function between calls, you can use "static $sum =3D 0;". > Thanks for your attention > > -- Mathieu Suen > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > > --=20 Etienne Kneuss http://www.colder.ch