user3474009
user3474009

Reputation: 311

Is it unwise to modify the class of functions in other packages?

There's a bit of a preamble before I get to my question, so hang with me!

For an R package I'm working on I'd like to make it as easy as possible for users to partially apply functions inline. I had the idea of using the [] operators to call my partial application function, which I've name "partialApplication." What I aim to achieve is this:

dnorm[mean = 3](1:10) 
# Which would be exactly equivalent to:
dnorm(1:10, mean = 3)

To achieve this I tried defining a new [] method for objects of class function, i.e.

`[.function` <- function(...) partialApplication(...)

However, R gives a warning that the [] method for function objects is "locked." (Is there any way to override this?)

My idea seemed to be thwarted, but I thought of one simple solution: I can invent a new S3 class "partialAppliable" and create a [] method for it, i.e.

`[.partialAppliable` = function(...) partialApplication(...)

Then, I can take any function I want and append 'partialAppliable' to its class, and now my method will work.

class(dnorm) = append(class(dnorm), 'partialAppliable')
dnorm[mean = 3](1:10)
# It works!

Now here's my question/problem: I'd like users to be able to use any function they want, so I thought, what if I loop through all the objects in the active environment (using ls) and append 'partialAppliable' to the class of all functions? For instance:

allobjs = unlist(lapply(search(), ls))
#This lists all objects defined in all active packages

for(i in allobjs) {
     if(is.function(get(i))) {
        curfunc = get(i)
        class(curfunc) = append(class(curfunc), 'partialAppliable')
        assign(i, curfunc)
     }
}

Voilà! It works. (I know, I should probably assign the modified functions back into their original package environments, but you get the picture).

Now, I'm not a professional programmer, but I've picked up that doing this sort of thing (globally modifying all variables in all packages) is generally considered unwise/risky. However, I can't think of any specific problems that will arise. So here's my question: what problems might arise from doing this? Can anyone think of specific functions/packages that will be broken by doing this?

Thanks!

Upvotes: 4

Views: 63

Answers (1)

Joshua Ulrich
Joshua Ulrich

Reputation: 176648

This is similar to what the Defaults package did. The package is archived because the author decided that modifying other package's code is a "very bad thing". I think most people would agree. Just because you can do it, does not mean it's a good idea.

And, no, you most certainly should not assign the modified functions back to their original package environments. CRAN does not like when packages modify the users search path unnecessarily, so I would be surprised if they allowed a package to modify other package's function arguments.

You could work around that by putting all the modified functions in an environment on the search path. But then you have to ensure that environment is always searched first, which means modifying the search path every time another package is loaded.

Changing arguments for functions in other packages also has the potential to make it very difficult for others to reproduce your results because they must have all your argument settings. Unless you always call functions with all their arguments specified, which defeats the purpose of what you're trying to do.

Upvotes: 1

Related Questions