Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:110712 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 78532 invoked from network); 24 Jun 2020 14:45:08 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 24 Jun 2020 14:45:08 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 48C121804F4 for ; Wed, 24 Jun 2020 06:32:35 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS15169 209.85.128.0/17 X-Spam-Virus: No X-Envelope-From: Received: from mail-lf1-f54.google.com (mail-lf1-f54.google.com [209.85.167.54]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Wed, 24 Jun 2020 06:32:34 -0700 (PDT) Received: by mail-lf1-f54.google.com with SMTP id g139so1271458lfd.10 for ; Wed, 24 Jun 2020 06:32:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=lC1gRpVDp3nd4XcE5yZPOgbnPxk1yEiaa+QwFfh635o=; b=HRaGa30zwkYyeyLZhwbtzvVUXDio+I74b7S/aACxtdlXkyVgZcGNZKvBnUeRyoWNGZ XET1BdWjf9AmFeUV7Tga+myEu/ULjZ5nmNTSSKYA5mG3EJaoQDDdhf88ofA6QyVIkwlN PDgtXj0DV0m6dujoc6uIIZhcWM1mcMkKLhh6D7ceM8+Z/dHciefXXt7unbHH9uPVgGT8 hLHwgrxkufu6eAI1p/LcdzhUvM8ddj6R3x2lpRJUVmZy2pHE3P6lRNjYxuTGONW3+9Q5 qiJ7AVfAZHuC59J+LIhlialynqK2DeMG1uU8mA/wh1ycGLQzpidU5TVIHCqiqLqpK996 qsXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=lC1gRpVDp3nd4XcE5yZPOgbnPxk1yEiaa+QwFfh635o=; b=HD+SRpwaKWquccs6lJO0VwbS8Ad7Rn4WxLol5Lmqt4iuXDQ0YIvUnG3t6faWMC6i8Z /T8q5Yve48CbZfVfcoo8wWEwN+7izQeySNqg3v7pC40GhrYVDynDjeVWSllAjiZMb7rU eabOMCNzVBk40DhSqspRPOdl5kcEBoJXD148gK88wb9JOQMtOc4YxP3ZDEEcgJWpGt8K Py8QOefEQ/mAWDHd2MnfYHpH6t6Ls8rHhXFf585gtSuu9nR55ofokhfnWESvsWTxUIfS WBjmDwKtjCn13ympZjAbONd1R2J6kZe4OatdOXFgC/k8+ZYiyxu4ob4Uub21twQk3Xku +XOA== X-Gm-Message-State: AOAM5306UEJETUFVeSVdGi6LxNY9Di4N2GmaYye3lvgh+3fqOm4DQJ1W 6lBoUi+dCXCAKPJZ+zd0aAd7SRYzWEbfNsvFq6Q= X-Google-Smtp-Source: ABdhPJyrrFoax1SpTL/FhhO57XAZeUodo4rBOgV/dOLztczpACBrAfBqwMM6ZXI6u7jiTuL3FvbmlZG5oGyeF5bg6yM= X-Received: by 2002:a19:ca11:: with SMTP id a17mr15423134lfg.120.1593005553229; Wed, 24 Jun 2020 06:32:33 -0700 (PDT) MIME-Version: 1.0 References: <25e60f0d-8057-73ed-9549-65ffaf06d376@telia.com> In-Reply-To: <25e60f0d-8057-73ed-9549-65ffaf06d376@telia.com> Date: Wed, 24 Jun 2020 15:32:15 +0200 Message-ID: To: =?UTF-8?Q?Bj=C3=B6rn_Larsson?= Cc: PHP internals Content-Type: multipart/alternative; boundary="00000000000020216605a8d482d3" Subject: Re: Making all Traversables an Iterator or IteratorAggregate From: nikita.ppv@gmail.com (Nikita Popov) --00000000000020216605a8d482d3 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Mon, Jun 22, 2020 at 5:56 PM Bj=C3=B6rn Larsson wrote: > Hi Nikita, > > Den 2020-06-19 kl. 12:32, skrev Nikita Popov: > > On Tue, Jun 9, 2020 at 3:33 PM Nikita Popov > wrote: > > > >> On Tue, May 12, 2020 at 10:26 AM Nikita Popov > >> wrote: > >> > >>> On Wed, Mar 11, 2020 at 10:50 AM Nikita Popov > >>> wrote: > >>> > >>>> Hi internals, > >>>> > >>>> Userland classes that implement Traversable must do so either throug= h > >>>> Iterator or IteratorAggregate. The same requirement does not exist f= or > >>>> internal classes: They can implement the internal get_iterator > mechanism, > >>>> without exposing either the Iterator or IteratorAggregate APIs. This > makes > >>>> them usable in get_iterator(), but incompatible with any Iterator > based > >>>> APIs. > >>>> > >>> This should have said: "This makes them usable in foreach(), but > >>> incompatible with any Iterator based APIs." > >>> > >>> A lot of internal classes do this, because exposing the userland APIs > is > >>>> simply a lot of work. I would like to add a general mechanism to mak= e > this > >>>> simpler: https://github.com/php/php-src/pull/5216 adds a generic > >>>> "InternalIterator" class, that essentially converts the internal > >>>> get_iterator interface into a proper Iterator. Internal classes then > only > >>>> need to a) implement the IteratorAggregate interface and b) add a > >>>> getIterator() method with an implementation looking like this: > >>>> > >>>> // WeakMap::getIterator(): Iterator > >>>> ZEND_METHOD(WeakMap, getIterator) > >>>> { > >>>> if (zend_parse_parameters_none() =3D=3D FAILURE) { > >>>> return; > >>>> } > >>>> zend_create_internal_iterator_zval(return_value, ZEND_THIS); > >>>> } > >>>> > >>>> This allows internal classes to trivially implement IteratorAggregat= e, > >>>> and as such allows us to enforce that all Traversables implement > Iterator > >>>> or IteratorAggregate. > >>>> > >>> Does anyone have thoughts on this change? Mostly this is a feature fo= r > >>> extensions, but also user-visible in that a bunch of classes will > switch > >>> from being Traversable to being IteratorAggregate. > >>> > >>> We may also want to convert some existing Iterators to > >>> IteratorAggregates. For example SplFixedArray currently implements > >>> Iterator, which means that it's not possible to have nested loops ove= r > >>> SplFixedArray. We could now easily fix this by switching it to use > >>> IteratorAggregate, which will allow multiple parallel iterators to > work on > >>> the same array. Of course, there is BC break potential in such a > change. > >>> > >>> There's some bikeshed potential here regarding the class name. I pick= ed > >>> "InternalIterator" as an iterator for internal classes, but "internal > >>> iteration" is also a technical term (the opposite of "external > iteration"), > >>> so maybe that name isn't ideal. > >>> > >> Unfortunately this bikeshed remains unpainted... The proposed names > were: > >> > >> 1. InternalIterator > >> 2. ZendIterator > >> 3. IteratorForExtensionClassImplementations > >> 4. EngineIterator > >> > >> I'm somewhat partial to the third option, with a less verbose name: > >> IteratorForExtensions. > >> > > I went ahead and changed the implementation to use IteratorForExtension= s. > > Is anyone overly unhappy with that one? > > > > @Michal: "ExtensionsIterator" to me sounds like an iterator that iterat= es > > over extensions. > > > > Regards, > > Nikita > > I'm actually in favour of the term InternalIterator like you first > proposed. Internal and external iteration is clearly something > different, so no need due to these to shy away here ;-) > > And today this iterator will be for extensions, but if somehow > that would change in the future (which I don't think), option > 3 is not ideal. > Okay ... I've now merged this using the original InternalIterator name. Nikita --00000000000020216605a8d482d3--