Is there a package or language construct in R that facilitates or provides the implementation of "Python-like generators"?
By "Python-like generators" I mean functions that keep state between calls, in R syntax and borrowing the keyword yield from Python will be something like:
iterable.fun <- function(){ yield list('a','b','c') }
With yield instead of a return, then calling the function three consecutive times would give:
> iterable.fun() 'a' > iterable.fun() 'b' > iterable.fun() 'c'
Edit: I left out an aspect of Python generators that makes them different from iterators. It is that the whole list of objects to iterate on is not built on the first call and then iterated, but each function call creates the one element that will return for that call.
Generator functions provide a powerful alternative: they allow you to define an iterative algorithm by writing a single function whose execution is not continuous. Generator functions are written using the function* syntax. When called, generator functions do not initially execute their code.
Generator Functions are memory efficient, as they save a lot of memory while using generators. A normal function will return a sequence of items, but before giving the result, it creates a sequence in memory and then gives us the result, whereas the generator function produces one output at a time.
Simply speaking, a generator is a function that returns an object (iterator) which we can iterate over (one value at a time).
The ES6 generator is a new type of function that can be paused in the middle or many times in the middle and resumed later. In the standard function, control remains with the called function until it returns, but the generator function in ES6 allows the caller function to control the execution of a called function.
The iterators
package has this functionality
library(iterators) abc <- iter(c('a','b','c')) nextElem(abc) ## [1] "a" nextElem(abc) ## [1] "b" nextElem(abc) ## [1] "c"
Or you could use lambda.r
and <<-
. This example is modified from
http://cartesianfaith.wordpress.com/2013/01/05/infinite-generators-in-r/
there are more examples in the blog post
library(lambda.r) seq.gen(start) %as% { value <- start - 1L function() { value <<- value + 1L return(value) } } foo <- seq.gen(1) foo() ## [1] 1 foo() ## [1] 2 foo() ## [1] 3
note that you could also use a regular function to do this.
seq.gen <-function(start) { value <- start - 1L function() { value <<- value + 1L return(value) } } foo2 <- seq.gen(1) foo2() ## [1] 1 foo2() ## [1] 2 foo2() ## [1] 3
If you want to select from a possible list, then you could perhaps do so using switch
seq.char(start) %as% { value <- start - 1L function() { value <<- value + 1L return(switch(value,'a','b','c')) } } foo.char <- seq.char(1) foo.char() ## [1] "a" foo.char() ## [1] "b" foo.char() ## [1] "c"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With