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, ...)
An iteror
extra parameters specific to class methods.
If obj
is a function without an or
argument, specify
e.g. catch="StopIteration"
to interpret errors with that
message as end of iteration.
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
.
If obj
is a vector, and recycle
is TRUE, the
iterator will re-cycle the elements of obj
without stopping.
If the iteror has reached its end, an argument that will be forced and returned.
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.
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:
<- 0
sum <- iteror(in)
it repeat {
<- nextOr(iter, break)
val <- sum + val;
sum }
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:
<- 0
sum <- new.env()
stopped repeat {
<- nextOr(iter, stopped)
val if (identical(val, stopped)) break
<- sum + val
sum }