To create an iteror, call the constructor iteror providing either a vector or a function as argument. The returned object will support the method nextOr(obj, or) to extract successive values.

iteror(obj, ...)

# S3 method for `function`
iteror(obj, ..., catch, sigil)

# S3 method for default
iteror(obj, ..., recycle = FALSE)

nextOr(obj, or, ...)

Arguments

obj

An iteror

...

extra parameters specific to class methods.

catch

If obj is a function without an or argument, specify e.g. catch="StopIteration" to interpret errors with that message as end of iteration.

sigil

If obj is a function without an or argument, specify which value to watch for end of iteration. Stop will be signaled if the function result is identical() to sigil.

recycle

If obj is a vector, and recycle is TRUE, the iterator will re-cycle the elements of obj without stopping.

or

If the iteror has reached its end, an argument that will be forced and returned.

Value

iteror(obj) returns an object of class c('iteror', 'iter').

nextOr returns the next element in the iteror, or else forces and returns its or argument.

Details

The main method for "iteror" is "nextOr" rather than "nextElem". Instead of using exceptions, "nextOr" uses a lazily evaluated "or" argument to signal the end of iteration. The "or" argument will only be forced when end of iteration is reached; this means the consumer can provide an action like "break", "next" or "return" to take at the the end of iteration. Summing over an iteror this way looks like:

sum <- 0
it <- iteror(in)
repeat {
  val <- nextOr(iter, break)
  sum <- sum + val;
}

Another way to use the "or" argument is to give it a sigil value; that is, a special value that will be interpreted as end of iteration. If the result of calling nextOr is identical() to the sigil value you provided, then you know the iterator has ended. In R it is commonplace to use NULL or NA, in the role of a sigil, but that only works until you have an iterator that needs to yield NULL. A safer alternative is to use a one-shot sigil value; the result of new.env() will work, as it returns a value that by construction is not identical to any other object in the R session. This pattern looks like:

sum <- 0
stopped <- new.env()
repeat {
  val <- nextOr(iter, stopped)
  if (identical(val, stopped)) break
  sum <- sum + val
}