[Rd] An iteration protocol

Duncan Murdoch murdoch@dunc@n @end|ng |rom gm@||@com
Mon Aug 11 22:15:39 CEST 2025


1. I'm not sure I see the need for the syntax change.  Couldn't this all 
be done in a while or repeat loop?  E.g. your example could keep the 
same definition of SampleSequence, then

  iterator <- SampleSequence(2)
  repeat {
    sample <- iterator()
    if (is.null(sample)) break
    print(sample)
  }

Not as simple as yours, but I think a little clearer because it's more 
concrete, less abstract.

2. It's not clear to me how the for() loop chooses a value to pass to 
the iterator function. (Sorry, I couldn't figure it out from your 
patch.) Is "exhausted" a unique value produced each time for() is 
called?  Is it guaranteed to be unique?  What does a user see if they 
look at it?

Duncan Murdoch


On 2025-08-11 3:23 p.m., Tomasz Kalinowski wrote:
> Hi all,
> 
> A while back, Hadley and I explored what an iteration protocol for R
> might look like. We worked through motivations, design choices, and edge
> cases, which we documented here:
> https://github.com/t-kalinowski/r-iterator-ideas
> 
> At the end of this process, I put together a patch to R (with tests) and
> would like to invite feedback from R Core and the broader community:
> https://github.com/r-devel/r-svn/pull/130/files?diff=unified&w=1
> 
> In summary, the overall design is a minimal patch. It introduces no
> breaking changes and essentially no new overhead. There are two parts.
> 
> 1.  Add a new `as.iterable()` S3 generic, with a default identity
>      method. This provides a user-extensible mechanism for selectively
>      changing the iteration behavior for some object types passed to
>      `for`. `as.iterable()` methods are expected to return anything that
>      `for` can handle directly, namely, vectors or pairlists, or (new) a
>      closure.
> 
> 2.  `for` gains the ability to accept a closure for the iterable
>      argument. A closure is called repeatedly for each loop iteration
>      until the closure returns an `exhausted` sentinel value, which it
>      received as an input argument.
> 
> Here is a small example of using the iteration protocol to implement a
> sequence of random samples:
> 
> ``` r
> SampleSequence <- function(n) {
>    i <- 0
>    function(done = NULL) {
>      if (i >= n) {
>        return(done)
>      }
>      i <<- i + 1
>      runif(1)
>    }
> }
> 
> for(sample in SampleSequence(2)) {
>    print(sample)
> }
> 
> # [1] 0.7677586
> # [1] 0.355592
> ```
> 
> Best,
> Tomasz
> 
> ______________________________________________
> R-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



More information about the R-devel mailing list