Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:108773 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 25116 invoked from network); 26 Feb 2020 18:44:21 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 26 Feb 2020 18:44:21 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id E7078180550 for ; Wed, 26 Feb 2020 09:02:00 -0800 (PST) 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,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-io1-f50.google.com (mail-io1-f50.google.com [209.85.166.50]) (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, 26 Feb 2020 09:02:00 -0800 (PST) Received: by mail-io1-f50.google.com with SMTP id e7so4074721ioe.13 for ; Wed, 26 Feb 2020 09:02:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=datadoghq.com; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=Kv4HU6uZRKwCfK0Lz9Ridy+wKzcti3YD7Kf2pmdXO0c=; b=ZR71aX04TzqXe5eNIyYKmpRb1vNLASYrOLrzwQW7DtV9HYuC9TCTzBjjsVHJyNvAgK TXrwnUN/9RL4bY9Asn4YbjkwvB5tbDkNfuv2/SQ/PhsW7zA+dRUgtqiHGQX7GNUbVaKY H5NFnbHFFox0W3beeZvLPM/qU6Cyhnys9ca7A= 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=Kv4HU6uZRKwCfK0Lz9Ridy+wKzcti3YD7Kf2pmdXO0c=; b=WVh5f/53LhtFA6V2Vq/nM0sQJKQz10QRQz32kSfjLm/dVfDD6Of5ML+UiitE1HbEXL MXas+aL3XMfkWTcd+v78d63xUP+knK9mxcvlFwKm7h+VBZ3nK+LOUxImBe7r4Yh8tRqG 1beZBHfCFZKxNoNhyipIseYLGyYNESl0PlmnjlEITyVCErVoCOZGopnSyH39y7unP0IF f6NXW8JuRlhe0lOdJju1kqd6VyGb0uo4MFnGw4Ek9smg+0rmKhyoxBGMn2b7Yjz6xivf 4dIyZwTHgX5IWJMZXJ2pGO2CGcaV0u0zGmOpxDiEHd3NyciKZfQ8XorvM2EGmF5F/kg8 Aq+A== X-Gm-Message-State: APjAAAUZBbgGw3pCxtCaQNypdMwT6gWD82lOvvbXoH397NvBengwcYIt mPxsK7fF6c21TsnPsHEL7717g8ecOXxEWqQieE50PQ== X-Google-Smtp-Source: APXvYqx3OZjwVtYI+p1YdtkDh9B21ZhjVQtEMgiQT1OSt2ywhTZszDDDz0EC9ywlqnwjGT9IMRGQXP7ylWEZ7V/aWgc= X-Received: by 2002:a5d:8448:: with SMTP id w8mr5749799ior.161.1582736519926; Wed, 26 Feb 2020 09:01:59 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: Reply-To: Levi Morrison Date: Wed, 26 Feb 2020 10:01:49 -0700 Message-ID: To: Nikita Popov Cc: PHP internals Content-Type: text/plain; charset="UTF-8" Subject: Re: [PHP-DEV] Support rewinding of generators From: internals@lists.php.net ("Levi Morrison via internals") On Wed, Feb 26, 2020 at 4:47 AM Nikita Popov wrote: > > Hi internals, > > Generators currently do not support rewinding -- or rather, only support it > if the generator is at/before the first yield, in which case rewinding is a > no-op. > > Generators make it real breeze to implement primitives like > > function map(callable $function, iterable $iterable): \Iterator { > foreach ($iterable as $key => $value) { > yield $key => $function($value); > } > } > > without having to do through the whole Iterator boilerplate. However, if > you do this, you end up with an iterator that is not rewindable. If you > want to make map() rewindable, you need to go back to a manual Iterator > implementation. As iterators in PHP are assumed to be rewindable by > default, this is somewhat annoying. > > There is a relatively simple (at least conceptually) way to make generators > rewindable: Remember the original arguments of the function, and basically > "re-invoke" it on rewind(). > > I'm wondering what people think about adding this functionality. I think > the main argument against it is that not all generators may behave sensibly > if you re-run their code -- there's probably a reasonable expectation that > an iterator will return the same sequence of values are rewinding, > something which we cannot guarantee with generators, but also don't enforce > with normal iterators either. > > Regards, > Nikita Making generators "rewindable but don't really know if it's going to work" is worse than "not rewindable," in my opinion. It is true that it isn't very different from other iterators; you aren't going to know if it's going to work. At risk of hijacking the thread: can we extend the ability to always rewind an iterator as long as it has not been progressed to _all_ iterators? It's not something I've seen discussed much, but it actually has a really important characteristic: you can find out if the iterator will yield at least 1 value (aka it's not empty) if the iterator has this characteristic. Generators have this characteristic but there are iterators in core that don't do this, and I'm sure there are userland iterators that also don't do this. I'm wondering if we can somehow force it to occur so nobody has to actually code that semantic into every iterator. To me that would be even more valuable than making generators semi-rewindable.