Skip to content

Instantly share code, notes, and snippets.

@JonasMoss
Last active February 19, 2018 10:48
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/30a5b2d3c65f62988d691cd8d500380d to your computer and use it in GitHub Desktop.
Save JonasMoss/30a5b2d3c65f62988d691cd8d500380d to your computer and use it in GitHub Desktop.
C++-style functors in R.
## A simple example of a functor in R.
## A simple function of one argument. Since y is neither defined inside the function body or
## given as an argument, R will search the enclosing environment for y. Since R is lazy, it
## won't do this when the function is defined, but only when the function is called (and y
## is needed.)
f = function(x) x^2 + y^2
## This changes the enclosing environment of f to a new environment. It was the global
## environment before, and we don't want that.
environment(f) = new.env()
## Adding a class attribute to f is needed to make the generics below work.
class(f) = "f"
## The magic is here. The generic system R allows you to define class-specific methods for most
## common functions, even $ and [].
`$.f` = function(f, y) environment(f)[[y]]
`$<-.f` = function(f, y, value) {
environment(f)[[y]] = value
invisible(f)
}
## Finally we can assign a value to y.
f$y = 5
f(3)
## Note that the approach of using attr(f, "y") = 5 would not work, since the function
## would not be able to access the attribute directly. Furthermore, the call by reference
## semantics can have a large effect on performance.
## This idea could probably be mixed with R6 in order to make callable objects in that
## framework as well.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment