R's parser doesn't work the way you're expecting it to. When doing an assignment like:
padding(right(df)) <- 1 it is broken into small stages. The guide "R Language Definition" claims that the above would be equivalent to: `<-`(df, `padding<-`(df, value = `right<-`(padding(df), value = 1))) but that is not correct, and you can tell by using `substitute` as you were above. There isn't a way to do what you want with the syntax you provided, you'll have to do something different. You could add a `which` argument to each style function, and maybe put the code for `match.arg` in a separate function: match.which <- function (which) match.arg(which, c("bottom", "left", "top", "right"), several.ok = TRUE) padding <- function (x, which) { which <- match.which(which) # more code } border <- function (x, which) { which <- match.which(which) # more code } some_other_style <- function (x, which) { which <- match.which(which) # more code } I hope this helps. On Mon, Sep 13, 2021 at 12:17 PM Leonard Mada <leo.m...@syonic.eu> wrote: > Hello Andrew, > > > this could work. I will think about it. > > But I was thinking more generically. Suppose we have a series of functions: > padding(), border(), some_other_style(); > Each of these functions has the parameter "right" (or the group of > parameters c("right", ...)). > > > Then I could design a function right(FUN) that assigns the value to this > parameter and evaluates the function FUN(). > > > There are a few ways to do this: > 1.) Other parameters as ... > right(FUN, value, ...) = value; and then pass "..." to FUN. > right(value, FUN, ...) = value; # or is this the syntax? (TODO: explore) > > 2.) Another way: > right(FUN(...other parameters already specified...)) = value; > I wanted to explore this 2nd option: but avoid evaluating FUN, unless the > parameter "right" is injected into the call. > > 3.) Option 3: > The option you mentioned. > > > Independent of the method: there are still weird/unexplained behaviours > when I try the initial code (see the latest mail with the improved code). > > > Sincerely, > > > Leonard > > > On 9/13/2021 6:45 PM, Andrew Simmons wrote: > > I think you're trying to do something like: > > `padding<-` <- function (x, which, value) > { > which <- match.arg(which, c("bottom", "left", "top", "right"), > several.ok = TRUE) > # code to pad to each side here > } > > Then you could use it like > > df <- data.frame(x=1:5, y = sample(1:5, 5)) > padding(df, "right") <- 1 > > Does that work as expected for you? > > On Mon, Sep 13, 2021, 11:28 Leonard Mada via R-help <r-help@r-project.org> > wrote: > >> I try to clarify the code: >> >> >> ### >> right = function(x, val) {print("Right");}; >> padding = function(x, right, left, top, bottom) {print("Padding");}; >> 'padding<-' = function(x, ...) {print("Padding = ");}; >> df = data.frame(x=1:5, y = sample(1:5, 5)); # anything >> >> ### Does NOT work as expected >> 'right<-' = function(x, value) { >> print("This line should be the first printed!") >> print("But ERROR: x was already evaluated, which printed >> \"Padding\""); >> x = substitute(x); # x was already evaluated before substitute(); >> return("Nothing"); # do not now what the behaviour should be? >> } >> >> right(padding(df)) = 1; >> >> ### Output: >> >> [1] "Padding" >> [1] "This line should be the first printed!" >> [1] "But ERROR: x was already evaluated, which printed \"Padding\"" >> [1] "Padding = " # How did this happen ??? >> >> >> ### Problems: >> >> 1.) substitute(x): did not capture the expression; >> - the first parameter of 'right<-' was already evaluated, which is not >> the case with '%f%'; >> Can I avoid evaluating this parameter? >> How can I avoid to evaluate it and capture the expression: "right(...)"? >> >> >> 2.) Unexpected >> 'padding<-' was also called! >> I did not know this. Is it feature or bug? >> R 4.0.4 >> >> >> Sincerely, >> >> >> Leonard >> >> >> On 9/13/2021 4:45 PM, Duncan Murdoch wrote: >> > On 13/09/2021 9:38 a.m., Leonard Mada wrote: >> >> Hello, >> >> >> >> >> >> I can include code for "padding<-"as well, but the error is before >> that, >> >> namely in 'right<-': >> >> >> >> right = function(x, val) {print("Right");}; >> >> # more options: >> >> padding = function(x, right, left, top, bottom) {print("Padding");}; >> >> 'padding<-' = function(x, ...) {print("Padding = ");}; >> >> df = data.frame(x=1:5, y = sample(1:5, 5)); >> >> >> >> >> >> ### Does NOT work >> >> 'right<-' = function(x, val) { >> >> print("Already evaluated and also does not use 'val'"); >> >> x = substitute(x); # x was evaluated before >> >> } >> >> >> >> right(padding(df)) = 1; >> > >> > It "works" (i.e. doesn't generate an error) for me, when I correct >> > your typo: the second argument to `right<-` should be `value`, not >> > `val`. >> > >> > I'm still not clear whether it does what you want with that fix, >> > because I don't really understand what you want. >> > >> > Duncan Murdoch >> > >> >> >> >> >> >> I want to capture the assignment event inside "right<-" and then call >> >> the function padding() properly. >> >> >> >> I haven't thought yet if I should use: >> >> >> >> padding(x, right, left, ... other parameters); >> >> >> >> or >> >> >> >> padding(x, parameter) <- value; >> >> >> >> >> >> It also depends if I can properly capture the unevaluated expression >> >> inside "right<-": >> >> >> >> 'right<-' = function(x, val) { >> >> >> >> # x is automatically evaluated when using 'f<-'! >> >> >> >> # but not when implementing as '%f%' = function(x, y); >> >> >> >> } >> >> >> >> >> >> Many thanks, >> >> >> >> >> >> Leonard >> >> >> >> >> >> On 9/13/2021 4:11 PM, Duncan Murdoch wrote: >> >>> On 12/09/2021 10:33 a.m., Leonard Mada via R-help wrote: >> >>>> How can I avoid evaluation? >> >>>> >> >>>> right = function(x, val) {print("Right");}; >> >>>> padding = function(x) {print("Padding");}; >> >>>> df = data.frame(x=1:5, y = sample(1:5, 5)); >> >>>> >> >>>> ### OK >> >>>> '%=%' = function(x, val) { >> >>>> x = substitute(x); >> >>>> } >> >>>> right(padding(df)) %=% 1; # but ugly >> >>>> >> >>>> ### Does NOT work >> >>>> 'right<-' = function(x, val) { >> >>>> print("Already evaluated and also does not use 'val'"); >> >>>> x = substitute(x); # is evaluated before >> >>>> } >> >>>> >> >>>> right(padding(df)) = 1 >> >>> >> >>> That doesn't make sense. You don't have a `padding<-` function, and >> >>> yet you are trying to call right<- to assign something to padding(df). >> >>> >> >>> I'm not sure about your real intention, but assignment functions by >> >>> their nature need to evaluate the thing they are assigning to, since >> >>> they are designed to modify objects, not create new ones. >> >>> >> >>> To create a new object, just use regular assignment. >> >>> >> >>> Duncan Murdoch >> > >> >> ______________________________________________ >> R-help@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. >> > [[alternative HTML version deleted]] ______________________________________________ R-help@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.