Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:99693 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 84253 invoked from network); 3 Jul 2017 01:45:04 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 3 Jul 2017 01:45:04 -0000 Received: from [127.0.0.1] ([127.0.0.1:15798]) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ECSTREAM id E9/D5-60825-0A1A9595 for ; Sun, 02 Jul 2017 21:45:04 -0400 Authentication-Results: pb1.pair.com smtp.mail=andreas@dqxtech.net; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=andreas@dqxtech.net; sender-id=unknown Received-SPF: error (pb1.pair.com: domain dqxtech.net from 209.85.223.170 cause and error) X-PHP-List-Original-Sender: andreas@dqxtech.net X-Host-Fingerprint: 209.85.223.170 mail-io0-f170.google.com Received: from [209.85.223.170] ([209.85.223.170:36332] helo=mail-io0-f170.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 6C/C1-60825-71ED7595 for ; Sat, 01 Jul 2017 13:38:32 -0400 Received: by mail-io0-f170.google.com with SMTP id z62so38061697ioi.3 for ; Sat, 01 Jul 2017 10:38:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dqxtech-net.20150623.gappssmtp.com; s=20150623; h=mime-version:from:date:message-id:subject:to; bh=4REOXuUlFrz6lWueQtcJDHl3P+62/cuUu0mYNqumTuo=; b=K4jZrI7afKvphZkcgSUuK920ck7c7aYaBRwYaY3Q9gHHJN0xmmkcakl8ekXT5jGsRv 6E5K+c3HrTUUPOVl1LHdHgtjii4S6wvP01vpfzjafq++QpWKLAetgfyOObUtoZwwKNSG BYACwym1kL71bsmR9kd3VRaPqubqudcoM02cr5sD8DYBIpFOkgvWxifvRXFZ4upDghqV MT4rB+Svsbc8jMSjj95N4Kc8Z6LheT3ysxbMwHs36ogu+EQSi7jAKGUm7C69FCMbx3Dp TVziiVdiKuG76iLZVGx/a3qg82FOG9KPx63o30J0z9Nge683+7TTPbuI0+0lyxfR8spu b/sg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=4REOXuUlFrz6lWueQtcJDHl3P+62/cuUu0mYNqumTuo=; b=Ipfhhttb0QBw1wCS7QOipqVhSPwKG5Am2ZlWjQt8YU+OqHHxyRwdi2c4rc7YCpevTp uHragswJPMaE+tj9WSCuehMwNr1kYjAuV/vsg9O40escCivJkKGwLj2WDUatI3Cxvwfn qyKYCvyPppt+7kbyIhGlsVzdvrYWj+FZ1F9MLlhPk/9gvJLX6BtMoDWUgKYT2anZsh3A RT+SvcrCQs6h3aR7rOOGT6FnVal/P6YbJCxBG8CSLwFSyqtkFYLbTmzadytoutBN/o4z adP9Wr00MX+f3UdDY/eJbuJ6+kTPAQ6xYDJ9P+p/ppaFKcUMpvsBwR5C8EiUPhw4ZekE hNrA== X-Gm-Message-State: AIVw113jOsxBJQpadJwxe6kvAeEm7PHgilWj2T+Adq/vWkYbzyeFBK9t xQq4qqzJu7EXUW3DtVg= X-Received: by 10.107.143.81 with SMTP id r78mr15009744iod.137.1498930709023; Sat, 01 Jul 2017 10:38:29 -0700 (PDT) Received: from mail-io0-f179.google.com (mail-io0-f179.google.com. [209.85.223.179]) by smtp.googlemail.com with ESMTPSA id w80sm231633ita.4.2017.07.01.10.38.28 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 01 Jul 2017 10:38:28 -0700 (PDT) Received: by mail-io0-f179.google.com with SMTP id z62so38061573ioi.3 for ; Sat, 01 Jul 2017 10:38:28 -0700 (PDT) X-Received: by 10.107.154.5 with SMTP id c5mr30543514ioe.109.1498930707739; Sat, 01 Jul 2017 10:38:27 -0700 (PDT) MIME-Version: 1.0 Received: by 10.36.246.71 with HTTP; Sat, 1 Jul 2017 10:38:07 -0700 (PDT) Date: Sat, 1 Jul 2017 19:38:07 +0200 X-Gmail-Original-Message-ID: Message-ID: To: internals@lists.php.net Content-Type: multipart/alternative; boundary="001a1140bc0a6128980553450067" Subject: "Reader" as alternative to Iterator From: andreas@dqxtech.net (Andreas Hennings) --001a1140bc0a6128980553450067 Content-Type: text/plain; charset="UTF-8" Hello internals, (this is my first email to this list, hopefully I'm doing ok.) -------------------------------------------------------------------------------- Background / motivation: Currently in PHP we have an interface "Iterator", and a final class "Generator" (and others) that implement it. Using an iterator in foreach () is straightforward: foreach ($iterator as $key => $value) {..} However, if we want to iterate only a portion and then continue elsewhere at the position where we stopped, we need to do something like this: for ($iterator->rewind(); $iterator->valid(); $iterator->next()) { $value = $iterator->current(); [..] } This is unpleasantly verbose, and also adds performance overhead due to additional function calls. Also, manually writing an iterator is quite painful. I sometimes implement "readers" that can be used like this (*): // Gets a reader at position zero. $reader = $readerProvider->getReader(); while (FALSE !== $value = $reader->read()) { [..] } (*) Note that I am using FALSE as an equivalent for "end of data". Of course it would be nice if we had a dedicated constant for this, that does not constrain the range of possible values of the iterator. Such readers are much easier to write than iterators. However, there is no native support for foreach(), and for generator syntax with yield. Adapters from Iterator to Reader and vice versa are possible to write. However, such userland adapters add additional performance overhead: One call to ->read() will trigger one call to ->valid(), one to ->current(), one to ->next(). -------------------------------------------------------------------------------- Proposal: Establish a new interface in core, "Reader" or "ReaderInterface" (*). This interface has only one method, "->read()". The existing interface Iterator will remain unchanged. (*) I am open to other naming suggestions. In fact in my own projects I called this thing "StreamInterface", and distinguish between "ObjectStreamInterface", "RowStreamInterface" etc. Currently I think "Reader" might be more suitable. Let the final class "Generator", and possibly other native iterators, implement Reader in addition to Iterator. Optionally, add an interface "ReaderAggregate", or "ReaderAggregateInterface", or "ReaderProvider". This interface has only one method, "getReader()". Let ReaderAggregate extend Traversable, and add foreach() support. The key will simply be a counter. Open questions: - The naming of "Reader", "ReaderAggregate", "->read()". - Which return value to use for "end of data", so that FALSE would become a valid value. I currently don't see a better option than FALSE. -------------------------------------------------------------------------------- - Andreas Hennings (https://github.com/donquixote) --001a1140bc0a6128980553450067--