[Rd] An iteration protocol

Tomasz Kalinowski k@||now@k|t @end|ng |rom gm@||@com
Mon Aug 11 21:23:49 CEST 2025


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



More information about the R-devel mailing list