Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:34077 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 78585 invoked by uid 1010); 18 Dec 2007 05:40:15 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 78570 invoked from network); 18 Dec 2007 05:40:15 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 18 Dec 2007 05:40:15 -0000 Authentication-Results: pb1.pair.com smtp.mail=larry@garfieldtech.com; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=larry@garfieldtech.com; sender-id=unknown Received-SPF: error (pb1.pair.com: domain garfieldtech.com from 76.96.30.56 cause and error) X-PHP-List-Original-Sender: larry@garfieldtech.com X-Host-Fingerprint: 76.96.30.56 qmta06.emeryville.ca.mail.comcast.net Received: from [76.96.30.56] ([76.96.30.56:56568] helo=QMTA06.emeryville.ca.mail.comcast.net) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 6A/89-06889-E3D57674 for ; Tue, 18 Dec 2007 00:40:14 -0500 Received: from OMTA04.emeryville.ca.mail.comcast.net ([76.96.30.35]) by QMTA06.emeryville.ca.mail.comcast.net with comcast id S3Fp1Y0050lTkoC0A0BH00; Tue, 18 Dec 2007 05:40:17 +0000 Received: from earth.ufp ([71.228.13.89]) by OMTA04.emeryville.ca.mail.comcast.net with comcast id S5gG1Y0071vH2xB8Q00000; Tue, 18 Dec 2007 05:40:17 +0000 X-Authority-Analysis: v=1.0 c=1 a=ZN6zT4ptW18A:10 a=t_Kt16yKhuBpAhqbhVQA:9 a=6aW7alrTYjJjD-ZMkc4A:7 a=23VeQEHOU6LatL_HIuT5uXFACYIA:4 a=FHBbIDN7CdwA:10 a=LY0hPdMaydYA:10 Received: from localhost (localhost [127.0.0.1]) by earth.ufp (Postfix) with ESMTP id 1707CD834C for ; Mon, 17 Dec 2007 23:40:10 -0600 (CST) Received: from earth.ufp ([127.0.0.1]) by localhost (earth.ufp [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id lcQvoe9TpJBD for ; Mon, 17 Dec 2007 23:40:09 -0600 (CST) Received: from vulcan.ufp (vulcan.ufp [192.168.42.4]) by earth.ufp (Postfix) with ESMTP id 495A3D8338 for ; Mon, 17 Dec 2007 23:39:59 -0600 (CST) To: internals@lists.php.net Date: Mon, 17 Dec 2007 23:41:54 -0600 User-Agent: KMail/1.9.6 (enterprise 0.20070907.709405) References: <98b8086f0712150818n40056cedyf0aae7a5a08a27b7@mail.gmail.com> <200712172130.08216.larry@garfieldtech.com> <4FADC266-873E-4FD2-BEC8-28EA9D833297@procata.com> In-Reply-To: <4FADC266-873E-4FD2-BEC8-28EA9D833297@procata.com> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-ID: <200712172341.54372.larry@garfieldtech.com> Subject: Re: [PHP-DEV] Re: PATCH: anonymous functions in PHP From: larry@garfieldtech.com (Larry Garfield) On Monday 17 December 2007, Jeff Moore wrote: > On Dec 17, 2007, at 10:30 PM, Larry Garfield wrote: > > I'm assuming that making the function above GC-able would be a > > herculean task > > at this point, based on previous comments, but I do not actually > > know myself. > > Hi Larry, > > Let me use a different example than yours. > > function getAdder($x) { > return function ($y) { > lexical $x; > return $x + $y; > } > } > > $plusFive = getAdder(5); > $plusTen = getAdder(10); > > echo $plusFive(4); // 9 > echo $plusTen(7); // 17 > > If the closure definition (and thus getAddr) returns a string > representing an anonymous function name, then there is no where to > hold the enclosing variable $x and no way to know when to free it. > Notice that in this example, we have two different enclosing contexts, > one where $x is 5 and one where $x is 10. > > If we introduce a new variable type, a new kind of zval, then > internally, that variable can hold: > 1) A reference to the local variables of getAddr. (here $x) > 2) A reference to $this if the closure is declared in a method > 3) A reference to the opcodes of the compiled anonymous function. > > The opcodes for the closure would be compiled and squirreled away when > the script is compiled. > > When getAddr is executed, a zval would be created that holds the > reference to the enclosing locals and a reference to the proper > opcodes. Note that $plusFive and $plusTen would hold two different > zvals, one for each invocation of getAddr, but that both would refer > to the same opcodes structure. So the compiled code is then single-sourced, much the same way that a class is single sourced and objects simply contain references to it. The Objects can be GCed whenever, but the class opcodes remain for the life of the script. > When a codeblock zval is executed, such as at $plusFive(4), the > enclosing context can be passed to the anonymous function function to > make the lexical $x statement bind to the proper variable. > > When the zval in $plusFive reaches zero references, it can > subsequently free its references to the local variables of getAddr. > > As far as I can see, no herculean garbage collection or reference > counting is required. By separating the opcodes from the zval, you've side-stepped the need to do so. That means declaring a dynamic function (or lambda, or whatever we end up calling this thing) inside a loop is no more expensive than instantiating a class inside of a loop. I'm glad you know more about engine internals than I do. :-) > Adding a new kind of zval? Perhaps that's Herculean. I don't know. It sounds (to the layman) like it could/should be modeled on the way objects/classes are implemented in PHP 5, as "fancy references". (I believe Sara Golemon had an article a while back that explained them that way. Sara, my apologies if I am misquoting you.) Whether that's a "new type of zval" or not I do not know. > I hope I've gotten my zval terminology right. Better than mine would be. :-) And it seems to solve most of the implementation concerns that were raised earlier, at least at an abstract level. The catch would be that I don't know the performance impact of making the compiler find and define these sorts of functions. Can someone with more engine experience weigh in if the above is workable? -- Larry Garfield AIM: LOLG42 larry@garfieldtech.com ICQ: 6817012 "If nature has made any one thing less susceptible than all others of exclusive property, it is the action of the thinking power called an idea, which an individual may exclusively possess as long as he keeps it to himself; but the moment it is divulged, it forces itself into the possession of every one, and the receiver cannot dispossess himself of it." -- Thomas Jefferson