Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:42601 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 90536 invoked from network); 13 Jan 2009 12:30:17 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 13 Jan 2009 12:30:17 -0000 Authentication-Results: pb1.pair.com header.from=xuefer@gmail.com; sender-id=pass; domainkeys=bad Authentication-Results: pb1.pair.com smtp.mail=xuefer@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.142.188 as permitted sender) DomainKey-Status: bad X-DomainKeys: Ecelerity dk_validate implementing draft-delany-domainkeys-base-01 X-PHP-List-Original-Sender: xuefer@gmail.com X-Host-Fingerprint: 209.85.142.188 ti-out-0910.google.com Received: from [209.85.142.188] ([209.85.142.188:7015] helo=ti-out-0910.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 6B/C6-42308-7598C694 for ; Tue, 13 Jan 2009 07:30:16 -0500 Received: by ti-out-0910.google.com with SMTP id u3so8299148tia.17 for ; Tue, 13 Jan 2009 04:30:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:sender:received:date :x-google-sender-auth:message-id:subject:from:to:content-type :content-transfer-encoding; bh=YAXvsAkq09C13ENJkaJvHwarfi+7uXemFNaQCWoADq0=; b=bQB3ojW2RVVkP9sHcKNw67zIVVlYveyd/w/yNTlG73QQ/epY+Mj5/RMlhwQ0bHs4Hv LmLQmmxh8dcAPCO/UnDOdEJIItCCvqD+DR97LVach+BU5yPN9ivXkVH6BRbLRiShj8Gl rVceAKuj7JYwkNp80F3MtbsnsKhzS8M0w94qs= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:sender:date:x-google-sender-auth:message-id:subject :from:to:content-type:content-transfer-encoding; b=FKHLJlBFnFmDp4GDLDS+8MTQNxQ39mnb4/BrnP7VnGzcZWqkFK1OL/bcqW/4Tp//Ip uwgzYy4r1iUk8NhHMijDa7/AdB86sADW4XticNGURLnbUL3q+m17hQvi3aYfeiFg6iAV lVw7cvtfYnF5TQW9zc0XjZYtJUyKSgTebkan4= MIME-Version: 1.0 Sender: xuefer@gmail.com Received: by 10.110.15.19 with SMTP id 19mr15219313tio.6.1231849811552; Tue, 13 Jan 2009 04:30:11 -0800 (PST) Date: Tue, 13 Jan 2009 20:30:11 +0800 X-Google-Sender-Auth: e4adf7954d1a0e58 Message-ID: <28139bc0901130430s32b0a156r792c39d2393e20c6@mail.gmail.com> To: PHP Developers Mailing List Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Subject: generator/yield operator feature request From: moo.tinys@gmail.com ("moo.tinys") this topic may be discussed before, but i'd bring it up again. closure was introduced in PHP 5.3, function with its context can now be stored in an callable object(or a handler in string type, whatever) i think it's easy and read to introduce generator and yield operator in php let's see what was in Iterator: 1. every class/interface can be prototyped in php userland, not internal, although many of the them was builtin written in c so make life easier pro: "simple" to implement in ZendEngine, see note 2 aboive con: really ugly to code Iterator/Filter in userland, hard to understand how they worked, code has to be split in rewind/next functions 2. no changes is required in ZendEngine, except powering up "foreach" to support iterator, so ppl can iterate over it much more easier. pro: "simple" to implement in ZendEngine, see note 2 aboive con: - let's see what will yeild/generator looks like: 1. require saving function calling context (not call stack) con(was): there was no way to save it, we had to implement it first con(now): no con, implemented already in 5.3 2. just 1 function, yield at any where in the body pro: much more readable than Iterator con: "yield" is now reserved keyword example: function foo($space_and_new_line = false) { yield "hello"; if ($space_and_new_line) { yield " "; } yield "world"; if ($space_and_new_line) { yield PHP_EOL; } } $g = foo(true); // function foo() is not called here foreach ($g as $i) { // function foo() IS called here echo $i; } function filter($g, $regex) { foreach ($g as $baa) { if (preg_match($regex, $i)) { return true; } // if } // foreach } $g = foo(true); foreach (filter($g, "^\\w+$") as $i) { echo $i; // now letters only } $g = foo(true); echo $g(); // same as: echo $g->value(); $g->next(); this is not in python, neither in php iterator echo $g(); echo $g(); (btw, i think iterator should be able to be used in this way) I don't think you can reimplement it into Iterator in any simpler form, except that you can reuse those classes already implemented. is it perl way? no. because yield/generator make code much more readable, easier to understood, not just "easier" to write, it's the php way ========== for those who don't know what yield/generator is, you can see python document or the following brief (correct me if i'm wrong) . functions (named or unamed/closure) with yield in its body, is a generator function that with context saved, not a normal. it's similar as closure context but with "yield point" saved . when you call a generator function, it returns an generator object . the interface to generator object is exactly like Iterator interface, that can be design to have rewind/next/valid methods, etc . generator is an OuterIterator . you can call $generator->next() (and other methods) explicitly, or call foreach which call iterator/generator methods implictly . the only difference between iterator and generator is how they implement it inside. when php execute "yield", the generator is execution is returned but its execution context is saved, next time the generator is iterated, php execute from the last yield point with all context restored.