Memoisation with RStudio's "Go to function" - r

I'm frequently use Rstudio's "Go To Function Definition" (shortcut is F2) in order to navigate between many files and quickly access a function's definition / make changes (printing the function's definition is usually not enough).
In order to make my analysis quicker, many of my functions are memoised with the package 'memoise'. This is all and well, but when I use the "Go To Function Definition" button (or F2), it takes me to the memoise function. This is the result:
function (Date = Sys.Date(), Symbol)
{
hash <- `_digest`(c(list(Date, Symbol), lapply(`_additional`,
function(x) eval(x[[2L]], environment(x)))), algo = "sha512")
if (`_cache`$has_key(hash)) {
res <- `_cache`$get(hash)
}
else {
res <- withVisible(`_f`(Date = Date, Symbol = Symbol))
`_cache`$set(hash, res)
}
if (res$visible) {
res$value
}
else {
invisible(res$value)
}
}
One note - I tried defining the function and giving it its memoisation below it as follows:
foo <- function(x) { return(x) }
foo <- memoise::memoise(foo)
But when I run this on linux, any time I call foo I get an infinite loop. Oddly, it works well on Windows (and the F2 function works on windows with this method!). I need something that will work on a linux system as well as having F2 functionality work.

Related

Defaults of function argument which name correspond to existing function name

Is there a way to prevent a promise already under evaluation error when
you want the name of a function argument to be the name of an existing function
and you want to set a default for this particular argument
and you want to be able to call the outer function with its defaults only (i.e. without the need to pass an explicit value to each argument)?
In my example below, while foo(1:5, bar) works, foo(1:5) throws such an error.
Of course I could go and change the argument name from bar to, say, bar_fun, but I would rather stick with the actual function's name if possible.
foo <- function(x, bar = bar) {
bar(x)
}
bar <- function(x) {
UseMethod("bar")
}
bar.default <- function(x) {
sum(x)
}
foo(1:5)
#> Error in foo(1:5): promise already under evaluation: recursive default argument reference or earlier problems?
foo(1:5, bar)
#> [1] 15
Motivation (first order)
The real-world use case is that bar() is actually settings(), a function which returns a list of settings. I'd like to version those settings. So there'd be e.g. methods like settings.v1, settings.v2, ..., and settings.default.
And I thought of using settings.default to define the "runtime version" of settings to use, so e.g.:
settings <- function(x) {
UseMethod("settings")
}
settings.v1 <- function(x) {
list(system = "dev")
}
settings.v2 <- function(x) {
list(system = "production")
}
settings.default <- function(x) {
settings.v2(
}
foo <- function(x, settings = settings) {
settings()
}
foo()
#> Error in foo(): promise already under evaluation: recursive default argument reference or earlier problems?
foo(settings = settings)
#> $system
#> [1] "production"
Since settings.default() calls the settings method I want to use, it'd be great if I could just call foo() with its defaults (which would then always pick up the settings.default() method).
Motivation (second order)
I'm experimenting with adhering more to principles of functional programming (see e.g. chapter from Advanced R or wikipedia link) and its distinction of pure and effectful/side-effecty functions.
Previously, I probably would have implemented settings via some sort of a global variable that thus each foo() had access to, so I could be lazy and not define it as an argument of function foo(), but foo() then would depend on things outside of its scope - which is a very bad thing in FP.
Now I want to at least state the dependency of foo() on my settings by handing it a function that returns the settings values - which is sort of my lazyness at least complying to some extend with top-level FP principles.
Of course the non-lazy (and arguably best) solution would be to carefully state all actual settings dependencies one by one as function arguments in foo(), e.g. foo(settings_system = settings()$system) ;-)
1) Try explicitly getting it from the parent:
foo <- function(x, bar = get("bar", 1)) {
bar(x)
}
2) Another possibility is to use an argument name such as bar.. The user can still write foo(1:15, bar = whatever), e.g. any of these three calls work:
foo <- function(x, bar. = bar) {
bar.(x)
}
foo(1:5)
foo(1:5, bar)
foo(1:5, bar = bar)

Debugging R closures

To debug a function foo in a file foo.R
foo <- function() {
a <- c(2, 3)
}
one can write a "driver" file
source("foo.R")
debug(f)
f()
This can trivially be extended for many such functions in the same scope.
Debugging a function bar() inside the body of foo is a bit tedious
foo <- function() {
bar <- function() {
a <- c(2, 3)
}
bar()
}
one can start from the same driver file (a test file, in practice), load bar() without actually running it, type debug(bar) at the debug prompt, and then run bar(). I'm wondering if there is a better way for multiple closures.
Is there a way to specify in the driver/test file that I want to debug the inner function bar, something along the lines of debug(foo::bar)?
Does R provide a standard syntax to refer to inner functions (aka nested functions, aka closures, etc.)?
Related questions:
Advanced debugging functionality in R?
You can just put a browser() at a point you want a debugger to be evoked:
foo <- function() {
print("In foo")
bar()
return(NULL)
}
bar <- function() {
print("In bar")
dash()
return(NULL)
}
dash <- function() {
print("In dash")
browser()
return(NULL)
}
foo()

Why expression after return's parenthesis is checked for lexical correctness, but is not evaluated?

Consider the following code:
a = function() {
return (23)
}
b = function() {
return (23) * 23
}
c = function() {
return (23) * someUndefinedVariable
}
All of the above runs successfully (if called) and return 23.
I assumed that R ignores everything that goes after the closing parenthesis of return, but it does not really, because this code fails during code loading:
d = function() {
return (23) something
}
My assumption is that in the latter example some lexer or parser fails. But in the former, expression is parsed as (return(23))*some (because return is treated like a function), but evaluation stops at return and therefore R does not try to find some.
Does that sounds ok? Is that the reason? Is such behavior intended? Can I enable some warnings so that interpreter tells me about such 'unreachable code'?
The failure of this code:
d = function() {
return (23) something
}
... has nothing to do with the prior code and everything to do with the inability to parse: return (23) something. Unlike the earlier misguided attempt to redefine c which had a valid/parseable function body, the d-body is incapable of being put into a functional form. The parser doesn't really stop at return(23) but rather after it tokenizes something and "realizes" that it is not a semicolon or an infix function name. So the R interpreter now has two expressions and no valid connector/separator between them.
The referenced objects inside R function bodies at the time of definition do not get evaluated or even checked for existence in the parameter list or outside the function. (R is not a compiler.)
R parses the statement before it is evaluated:
parse(text = "funky <- function(x) {
return(x) * dog
}")
returns:
expression(funky <- function(x) {
return(x) * dog
})
However,
parse(text = "funky <- function(x) {
return(x) dog
}")
returns:
Error in parse(text = "funky <- function(x) {\n return(x) dog\n}") :
<text>:2:19: unexpected symbol
1: funky <- function(x) {
2: return(x) dog
^
In the above example, even though the variable dog doesn't exist (and comes after return), R is still able to parse it as it correct code.
return is not just "treated like a function", it is a function. And anytime it's called, the code path will exit from whatever function you're in at that moment.
So that means that by the time R would have gotten to multiplying the result of return by 23, it's all over, that evaluation stops, and there are no errors or warnings to report (just like there are no warnings or errors when you return inside some if condition).
Whereas your last function simply cannot be parsed (which more or less means that the expression is put into a function tree), and so that (function) object can't be created.

How to subclass a function in R?

I was wondering if it is possible to use Reference Classes to subclass a function in R. For instance, the following
> CustomFunction <- setRefClass("CustomFunction", contains = "function")
> foo <- CustomFunction()
> foo()
NULL
works OK (does not throw an error), but how can I customise the behaviour (i.e. other than returning NULL)? How can I define function arguments?
I also tried
> setMethod("(",
> signature(x = "CustomFunction"),
> function(...) {
> "Hello!" # A function that always returns "Hello!"
> }
> )
Error in genericForPrimitive(f) :
methods may not be defined for primitive function ‘(’ in this version of R
but that doesn't seem to work.
I was hoping that being able to subclass functions means that I could implement custom behaviour before and after function calls. E.g. to have functions that automatically logs the call expression each time it is called (for audit purposes), or to create functions that automatically throws an error if NULL is returned etc etc.
You don't need Reference Classes for this, you can just enclose the function of interest
logger <- function(f) {
force(f)
function(...) {
print("running function...")
f(...)
}
}
printhello <- function(name="Al") print(paste("hello", name))
printhello_logged <- logger(printhello)
printhello()
# [1] "hello Al"
printhello_logged("Zed")
# [1] "running function..."
# [1] "hello Zed"
If this is for auditing/testing type purposes, you might be interested in trace() which allows you to attach code to various parts of functions.

automatic redirection of functions

The language is R.
I have a couple of files:
utilities.non.foo.R
utilities.foo.R
utilities.R
foo is an in-house package that has been cobbled together (for image processing, although this is irrelevant). It works great, but only on Linux machines, and it is a huge pain to try and compile it even on those.
Basically, utilities.foo.R contains a whole lot of functions that require package foo.
The functions in here are called functionname.foo.
I'm about to start sharing this code with external collaborators who don't have this package or Linux, so I've written a file utilities.non.foo.R, which contains all the functions in utilities.foo.R, except the dependency on package foo has been removed.
These functions are all called functionname.non.foo.
The file utilities.R has a whole heap of this, for each function:
functionname <- function(...) {
if ( fooIsLoaded() ) {
functionname.foo(...)
} else {
functionname.non.foo(...)
}
}
The idea is that one only needs to load utilities.R and if you happen to have package foo (e.g. my internal collaborators), you will use that backend. If you don't have foo (external collaborators), you'll use the non-foo backend.
My question is: is there some way to do the redirection for each function name without explicitly writing the above bit of code for every single function name?
This reminds me of how (e.g.) there is a print method, a print.table, print.data.frame, etc, but the user only needs to use print and which method is used is chosen automatically.
I'd like to have that, except the method.class would be more like method.depends_on_which_package_is_loaded.
Is there any way to avoid writing a redirection function per function in my utilities.R file?
As Dirk says, just use a package. In this case, put all your new *.non.foo functions in a new package, which is also called foo. Distribute this foo to your collaborators, instead of your in-house version. That way your utilities code can just be
functionname <- function(...) functionname.foo(...)
without having to make any checks at all.
Here is an idea: write a function that sets f to either f.foo or f.non.foo. It could be called in a loop, over all functions in a given namespace (or all functions whose name ends in .foo).
dispatch <- function(s) {
if ( fooIsLoaded() ) {
f <- get( paste(s, "foo", sep=".") )
} else {
f <- get( paste(s, "non.foo", sep=".") )
}
assign( s, f, envir=.GlobalEnv ) # You may want to use a namespace
}
f.foo <- function() cat("foo\n")
f.non.foo <- function() cat("non-foo\n")
fooIsLoaded <- function() TRUE
dispatch("f")
f()
fooIsLoaded <- function() FALSE
dispatch("f")
f()
A simpler solution would be to give the same name
to both functions, but put them in different namespaces/packages.
This sounds quite inefficient and inelegant, but how about
funify = function(f, g, package="ggplot2") {
if(paste("package:", package, sep="") %in% search()) f else
{ message("how do you intend to work without ", package) ; g}
}
detach(package:ggplot2)
foo = funify(paste, function(x) letters[x])
foo(1:10)
library(ggplot2)
foo = funify(paste, function(x) letters[x])
foo(1:10)

Resources