Skip to content

Instantly share code, notes, and snippets.

@JonasMoss
Last active February 19, 2018 12:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JonasMoss/4d705f730b04f1246c5da26f0584a20a to your computer and use it in GitHub Desktop.
Save JonasMoss/4d705f730b04f1246c5da26f0584a20a to your computer and use it in GitHub Desktop.
A generator variant of "i:j".
## These are generic functions for extracting and assigning values to the enclosing
## environment of a function. It needs class(f) = "function" to work.
`$.function` = function(f, y) environment(f)[[y]]
`$<-.function` = function(f, y, value) {
environment(f)[[y]] = value
invisible(f)
}
## Makes a 'generator' out of the most simple case of the i:j function in R. The
## enclosing environment is the environment generated by i, so it is disjoint from
## any "interesting" environment.
i = function(input) {
input_ = deparse(substitute(input))
input_vec = as.numeric(unlist(strsplit(input_, ":")))
start = input_vec[1]
end = input_vec[2]
generator = function() {
index = generator$index
if(index > generator$end) stop("Iterator end reached.")
generator$index = index + 1
index
}
class(generator) = c("generator", "function")
generator$index = start
generator$end = end
generator
}
gen = i(1:4)
gen$end
gen()
gen()
gen()
gen()
gen()
## The next step is to make replicate, sapply, etc. compatible with such generators.
## This can be very when running simulations, say apply(replicate(N, rnorm(N)), 1, mean)
## when N is large.
## Here's an incomplete variant of sapply. Ideally it should return a generator itself?
gen = i(1:100)
isapply = function(generator, fun) {
length = generator$end - generator$start
list_ = rep(NA, length)
for(i in 1:length) list_[i] = fun(generator())
list_
}
isapply(gen, function(x) x^2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment