Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:110134 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 31525 invoked from network); 12 May 2020 09:50:08 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 12 May 2020 09:50:08 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 8A8441804C2 for ; Tue, 12 May 2020 01:26:44 -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-f45.google.com (mail-lf1-f45.google.com [209.85.167.45]) (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 ; Tue, 12 May 2020 01:26:44 -0700 (PDT) Received: by mail-lf1-f45.google.com with SMTP id z22so9842556lfd.0 for ; Tue, 12 May 2020 01:26:43 -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; bh=rS+z/5FN29Q4LiLp4jk/CtBytxHIJvK+EyuCRSeXELs=; b=jrymUY9dgJa04WG1tLqXS4FFVuQa47xFVqpYJOe49f0D6oacsQh1tipJp23ExWagvB PnEcLfGWTCTUXq1yfVJdyj2yDxV4RM5jlFz5WoGhIYvltI6cldO5HM/PAskL5aj5tuOG JZGXe75xVpy4oRJW7cePnVQH1YJO29Opqlj4ZTeW6tQNiWsT+2k/83AWeg2N94gHk1QB FNxt0rP5tM2b4F7iQSMZFuYyT7hIg288xMskLXMw5havgisHWgHHf8uNdK95jNbAo+1x IWgLoDAcF6Qh+YqLruh92Q7NxR+izY71xui5WbYfl/81zV6445kDcQ25HZ8qp1XunS3X ETeA== 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; bh=rS+z/5FN29Q4LiLp4jk/CtBytxHIJvK+EyuCRSeXELs=; b=e/tj758TbvZ1RvyEEFZyChzaywqcA6Xupbcok21MQ7X9gP5QEtkuP+ipgsU4CnrVrp pHl0MsWbh/AUoK5RNQr26VRqtiEA0p+W8n+fqO7kkTihIaK8S5EstGzLoWE6eXcA3ymR 9yUtjiKsn7L8IgqCXjap6dSKJ5F8LSimsm/hZw6FomaD21LHFGAVOG49K5ILasdRrP3k OzfSFESJnsYbv1s/V2ZJroShjvpKb/Yu4DMWMVxINCLkgT5n8kgktB74YSXUWJMqgVQA rgPwx+3Lgk1uFZwft8hH15r7I87cpwmSW8NomM1QmMOSYlqN4XU0VoB2WgajOKoOhQTP 6gcw== X-Gm-Message-State: AOAM532dqG5B/Hc794/MzxMXthBE7VOWpXxTQ48JSt76JL5pfzPcQt8I G4GT91IlRGa9jygJHuZx3l/1gP8ygH6WeBDArR9dJ+7c X-Google-Smtp-Source: ABdhPJz7hkkScQuykD7cVk2VnViMz/104OERDMM7PMLCJUK54oiSDWY5k+aK0jVw4xGvBOkB72UFPfHQtBqOvksibyM= X-Received: by 2002:ac2:4c83:: with SMTP id d3mr14074968lfl.92.1589272000001; Tue, 12 May 2020 01:26:40 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Tue, 12 May 2020 10:26:24 +0200 Message-ID: To: PHP internals Content-Type: multipart/alternative; boundary="00000000000003042b05a56f3960" Subject: Re: Making all Traversables an Iterator or IteratorAggregate From: nikita.ppv@gmail.com (Nikita Popov) --00000000000003042b05a56f3960 Content-Type: text/plain; charset="UTF-8" On Wed, Mar 11, 2020 at 10:50 AM Nikita Popov wrote: > Hi internals, > > Userland classes that implement Traversable must do so either through > Iterator or IteratorAggregate. The same requirement does not exist for > 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 make 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() == FAILURE) { > return; > } > zend_create_internal_iterator_zval(return_value, ZEND_THIS); > } > > This allows internal classes to trivially implement IteratorAggregate, 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 for 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 over 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 picked "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. Regards, Nikita --00000000000003042b05a56f3960--