Last active
February 19, 2018 10:48
-
-
Save JonasMoss/30a5b2d3c65f62988d691cd8d500380d to your computer and use it in GitHub Desktop.
C++-style functors in R.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## 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