Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:60780 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 16314 invoked from network); 8 Jun 2012 11:16:16 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 8 Jun 2012 11:16:16 -0000 Authentication-Results: pb1.pair.com smtp.mail=nikita.ppv@googlemail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=nikita.ppv@googlemail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain googlemail.com designates 209.85.215.42 as permitted sender) X-PHP-List-Original-Sender: nikita.ppv@googlemail.com X-Host-Fingerprint: 209.85.215.42 mail-lpp01m010-f42.google.com Received: from [209.85.215.42] ([209.85.215.42:63001] helo=mail-lpp01m010-f42.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id D7/84-19215-EFED1DF4 for ; Fri, 08 Jun 2012 07:16:15 -0400 Received: by lagy4 with SMTP id y4so1298452lag.29 for ; Fri, 08 Jun 2012 04:16:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; bh=TFOn357TLPm/PWhf8NHlylpqryq+1XTS7wHCt9B/OsU=; b=PsMnUgGd7Yu+OVC6gyGCQRe0lyqEkot0w8NLtashDNYf51UFnNn9p1EFmK+0C4sEqr ea4hYDhZdDMpA3Ut/AWn8njo1yvCOPZAvaUXnk2q1tKrbMNM3kSiICaTBktsirZ7IP0N j8V0EKCXZ318MOPMLXk/Ri5K60FX30brXIARwhzSC894ZGICBB1Yh3PvwKYddPTQL+jT zIe4BRnDLtOsyqc4CbA9k83MidP9aCKNQ2AvJHQhsUY9DQ6Cp/zthhR7xOzeIHI2UFBa tAQbyuRe8JtB/NpQ4WMDEBmQGWZgs28YIb8iuhoOr89dkiVGzBm4pE+CB5001Ol2KoqU vv6g== MIME-Version: 1.0 Received: by 10.152.124.141 with SMTP id mi13mr7584519lab.50.1339154172015; Fri, 08 Jun 2012 04:16:12 -0700 (PDT) Received: by 10.152.114.70 with HTTP; Fri, 8 Jun 2012 04:16:11 -0700 (PDT) In-Reply-To: <4FCF2F09.8050904@hoa-project.net> References: <4FCF2F09.8050904@hoa-project.net> Date: Fri, 8 Jun 2012 13:16:11 +0200 Message-ID: To: ivan.enderlin@hoa-project.net Cc: internals@lists.php.net Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] Generators in PHP From: nikita.ppv@googlemail.com (Nikita Popov) On Wed, Jun 6, 2012 at 12:20 PM, Ivan Enderlin @ Hoa wrote: > In addition to Gustavo's remarks, I wonder how the GC would collect a > Generator object that is not use anymore (especially with a referenced > yield). Does it fit to the current CG strategy or do we need an extra > strategy? I would notice that the =93Yield by reference=94 section does n= ot > exist but you have targeted it). I added a new section which answers the question at least partially: https://wiki.php.net/rfc/generators#closing_a_generator If you don't need the generator object anymore you can either explicitly ->close() it or wait until all references to it are removed (typically when leaving the scope of the calling function). When the generator is closed it releases all used resources, including the suspended execution context and the currently yielded value. Whether or not the value is yielded by reference shouldn't make a difference. So, yes, the current GC strategy works well for generators too :) > Moreover, I wonder how a =93recursive yield=94 would act (something like = =93public > function *f ( =85 ) { =85 yield $this->f(=85); =85 }=94). It is possible?= Is it > anticipated? Your particular code would simply yield a generator object (as that's what $this->f(=85) returns). If instead you wanted to yield all values from that object you could wrap it in a foreach loop: function *f() { // ... foreach ($this->f() as $value) { yield $value; } // ... } What this doesn't yet properly cover is the use of generators as cofunctions. In this case it is desirable that ->send() calls are also propagated (same applies to ->close() and the not yet implemented ->throw()). To cover all those use-cases you'd have to come up with a rather big and ugly block of code (you can find a Python same implementation in http://www.python.org/dev/peps/pep-0380/#formal-semantics). Thus it is clear that another expression is required which allows you to delegate execution to another generator/cofunction. In Python this is "yield from", in JavaScript "yield*". A tree implementation using it could look like this: class Tree implements IteratorAggregate { protected $value, $left, $right; public function __construct($value, Tree $left =3D null, Tree $right = =3D null) { $this->value =3D $value; $this->left =3D $left; $this->right =3D $right; } function *getIterator() { if ($this->left) yield* $this->left; yield $this->value; if ($this->right) yield* $this->right; } } As you can see the iterator implementation is dead simple. (Note though that the yield* expression described above isn't yet implemented, but I plan to implement it.) Nikita