Greetings, Occasionally, I desire to call a function with one argument set to equal to another. Here is a toy example: ?? f <- function(x, y) { ? ? ?? x + y ?? } ?? f(x = 3, y = x) # Error in f(x = 3, y = x) : object 'x' not found So far, the most concise way I found to accomplish this is: ?? f(x = 3, y = local(sys.frame(1)$x)) # evaluates to 6 but I dislike this solution because local() creates a new environment. Surely there must be a better way? Note: I'm not interested in solutions that require modifying or currying f. Regards, Ben
Hi Ben, How about something like this: f <- function(x, y = NULL) { if (is.null(y)) y <- x x + y }> f(3, 4)[1] 7> f(3)[1] 6 Regards, Marc Schwartz> On Jun 20, 2020, at 7:15 AM, Benjamin Tyner <btyner at gmail.com> wrote: > > Greetings, > > Occasionally, I desire to call a function with one argument set to equal to another. Here is a toy example: > > f <- function(x, y) { > > x + y > } > > f(x = 3, y = x) # Error in f(x = 3, y = x) : object 'x' not found > > So far, the most concise way I found to accomplish this is: > > f(x = 3, y = local(sys.frame(1)$x)) # evaluates to 6 > > but I dislike this solution because local() creates a new environment. Surely there must be a better way? > > Note: I'm not interested in solutions that require modifying or currying f. > > Regards, > Ben > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.
On 20/06/2020 7:15 a.m., Benjamin Tyner wrote:> Greetings, > > Occasionally, I desire to call a function with one argument set to equal > to another. Here is a toy example: > > ?? f <- function(x, y) { > > ? ? ?? x + y > ?? } > > ?? f(x = 3, y = x) # Error in f(x = 3, y = x) : object 'x' not found > > So far, the most concise way I found to accomplish this is: > > ?? f(x = 3, y = local(sys.frame(1)$x)) # evaluates to 6 > > but I dislike this solution because local() creates a new environment. > Surely there must be a better way? > > Note: I'm not interested in solutions that require modifying or currying f.How about g <- function(x, y = x) { f(x, y) } g(x = 3) or even yEqualsX <- function(f) function(x, y = x) f(x, y) yEqualsX(f)(x = 3) These are a lot like currying, but aren't currying, so they may be acceptable to you. Personally I'd choose the first one. Duncan Murdoch
On 6/20/20 9:00 AM, Duncan Murdoch wrote:> How about > > g <- function(x, y = x) { > ? f(x, y) > } > g(x = 3) > > or even > > yEqualsX <- function(f) function(x, y = x) f(x, y) > > yEqualsX(f)(x = 3) > > These are a lot like currying, but aren't currying, so they may be > acceptable to you.? Personally I'd choose the first one. > > Duncan Murdoch >Thank you Duncan; I should have been more explicit that I was also trying to avoid defining any new functions, but yes, it's hard to argue with the wrapper approach as a longstanding best practice. Basically I'm wondering if it would be theoretically possible to construct a function "g" (possibly it would have to be primitive/internal) such that f(x = 3, y = g(expr)) would evaluate expr in the evaluation environment of f? After rereading section 4.3.3 of the R Language Definition, it's clear that supplied arguments are evaluated in the calling environment; though trickery in f()'s body may be used to evaluate elsewhere, such options seem limited from within the argument list itself. Ben