Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:80741 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 95991 invoked from network); 18 Jan 2015 15:05:45 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 18 Jan 2015 15:05:45 -0000 Authentication-Results: pb1.pair.com header.from=rowan.collins@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=rowan.collins@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.217.178 as permitted sender) X-PHP-List-Original-Sender: rowan.collins@gmail.com X-Host-Fingerprint: 209.85.217.178 mail-lb0-f178.google.com Received: from [209.85.217.178] ([209.85.217.178:56927] helo=mail-lb0-f178.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 11/AC-18613-8CBCBB45 for ; Sun, 18 Jan 2015 10:05:45 -0500 Received: by mail-lb0-f178.google.com with SMTP id u14so24574893lbd.9 for ; Sun, 18 Jan 2015 07:05:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=E5jm2lZHzWoXqIq5kY3aiNLW7R7Kpz1lW3udn9+l9t4=; b=wxOP/Ga9bG3BCG/2oeRyUcPTWlC6fPdhvNfC1NA8iA7QL6Vb4F/1bjUefA38+7tqg8 G03ihiATjOHoTSxKgKyImJyMzogL0BwdwRNGpsfk2xjtHPwFwXg/I21a4qRkgWf5bdRy m3r3QMK1F1KYHNsIffhHAQLpyfzMdmIHMLUgY8yNYhAetAzHFh8wD6pE6pVWEZk3EIJo 4Q4IqrAo2MJTivcYOQrPjLE6iUiocGEADVNka4MtSdNRUotfW9BOihqE93VvhPeksC4d ifK0QUkyZJUIwxg3kz6rocZpcroKEAzHfCeDTh0BXrGnZ+d7f+RAUm+B7G8uNvcBWVgJ On0A== MIME-Version: 1.0 X-Received: by 10.112.90.170 with SMTP id bx10mr25063346lbb.69.1421593541471; Sun, 18 Jan 2015 07:05:41 -0800 (PST) Received: by 10.25.206.144 with HTTP; Sun, 18 Jan 2015 07:05:41 -0800 (PST) In-Reply-To: References: <54B93AAD.6080308@gmail.com> Date: Sun, 18 Jan 2015 15:05:41 +0000 Message-ID: To: Yasuo Ohgaki Cc: "internals@lists.php.net" Content-Type: multipart/alternative; boundary=001a1134694e0df39e050cee8a11 Subject: Re: [PHP-DEV] Fixing strange foreach behavior. From: rowan.collins@gmail.com (Rowan Collins) --001a1134694e0df39e050cee8a11 Content-Type: text/plain; charset=UTF-8 On 18 January 2015 at 01:01, Yasuo Ohgaki wrote: > Hi Rowan, > > On Sat, Jan 17, 2015 at 8:43 PM, Rowan Collins > wrote: > >> My concern is, at what cost? Given how rarely used the internal pointer >> is, >> are we carrying around a chunk of extra memory with every array just on >> the >> off-chance that it will be used, or is there some magic that makes it >> zero-width until it's needed? >> >> Reusing it for foreach makes perfect sense if it increases performance for >> the majority of cases, and the only way to cover every edge-case like the >> one at the top of this thread would be to ban that optimisation outright. >> If there's some way of separating things such that the rarely used >> constructs take the performance hit, I'm all for it, though. >> > > External position pointer needs a little more memory for sure. However, > external position pointer is used all over the place in standard and other > modules. > > I agree that some benchmark should be taken before we proceed. > I meant more that the internal pointer takes up memory which is unused by 99% of PHP applications, so we might as well get some benefit from it, but it comes to the same thing. > Alternatively, we could achieve consistency the other way round, by making >> foreach() reset the internal pointer even when it *doesn't* use it, and >> documenting that fact like we do for certain array functions. Code relying >> on the current behaviour when mixing them is probably buggy anyway, >> because >> it is not well-defined, so the BC concern should be low. >> > > IIRC, there were discussions when foreach is added that point out internal > position > pointer usage. Before foreach, everyone was using > current()/next()/reset(). I think > the reason foreach sets internal position pointer to the end was the code > used in > those days. It was not a technical/performance reasons, wasn't it? I don't > remember > well because it was more than 10 years ago. Anyone? > > IIRC, foreach was introduced by Andi. I think foreach used external > position pointer and > didn't touch internal position pointer at all with his first proposal. > Please correct me if I'm > wrong. > > As for nesting, I think PHP is doing the right thing for plain arrays and >> non-rewindable integrators, because I would expect a for each loop to >> start >> at the beginning, thus have an implicit reset/rewind. The rewindable >> behaviour is awkward, though - intuitively, the iteraror needs to be able >> to track multiple positions simultaneously, which isn't guaranteed by the >> interface design. Maybe an error should be issued if the integrator is >> already subject of a foreach loop? >> > > Iterator is headache, I agree. > Iterator nesting may be detected by a flag easily, but it may be better to > generate > independent iterators for each "foreach". > > I don't think that's an either/or situation: in most cases, it would be up to the user to create that independent iterator, because there's no general algorithm for cloning one that the engine could use. (Think of an iterator proxying a database cursor, for instance - it could be rewindable directly, but cloning it would imply issuing a new query to create a new cursor with separate state.) So the engine needs to issue an error telling the user that they're reusing an object in an dangerous way. An extended interface could be created later for those cases that can handle the situation, although I doubt it would be that common a use case. -- Rowan Collins [IMSoP] --001a1134694e0df39e050cee8a11--