Hello Andrew,
On 9/15/2021 6:53 AM, Andrew Simmons wrote: > names(x) <- c("some names") > > if different from > > `names<-`(x, value = c("some names")) > > because the second piece of code does not ever call `<-`. The first > piece of code is (approximately) equivalent to > > `*tmp*` <- x > `*tmp*` <- `names<-`(`*tmp*`, value = c("some names")) > x <- `*tmp*` This is my question: Would there be any negative impact if the code is changed to: x <- 'names<-'(x, value=...); The "x" will be evaluated inside 'names<-' and this function outputs & assigns "x". The "creation" of "x" in the current environment is done only after the call to 'names<-' (if it did not exist before). Leonard > > Another example, > > y <- `names<-`(x, value = c("some names")) > > now y will be equivalent to x if we did > > names(x) <- c("some names") > > except that the first will not update x, it will still have its old names. > > On Mon, Sep 13, 2021 at 4:33 PM Leonard Mada <leo.m...@syonic.eu > <mailto:leo.m...@syonic.eu>> wrote: > > > On 9/13/2021 11:28 PM, Andrew Simmons wrote: >> In the example you gave : r(x) <- 1 >> r(x) is never evaluated, the above calls `r<-`, >> in fact r does not even have to be an existing function. > > > I meant: > > '*tmp*' <- x; # "x" is evaluated here; > > 'r<-' is called after this step, which makes sense in the case of > subsetting; > > > But I am wondering if changing this behaviour, when NO subsetting > is performed, would have any impact. > > e.g. names(x) = c("some names"); > > # would it have any impact to skip the evaluation of "x" and call > directly: > > 'names<-'(x, value); > > > Leonard > > >> >> On Mon, Sep 13, 2021, 16:18 Leonard Mada <leo.m...@syonic.eu >> <mailto:leo.m...@syonic.eu>> wrote: >> >> Hello, >> >> >> I have found the evaluation: it is described in the section >> on subsetting. The forced evaluation makes sense for subsetting. >> >> >> On 9/13/2021 9:42 PM, Leonard Mada wrote: >>> >>> Hello Andrew, >>> >>> >>> I try now to understand the evaluation of the expression: >>> >>> e = expression(r(x) <- 1) >>> >>> # parameter named "value" seems to be required; >>> 'r<-' = function(x, value) {print("R");} >>> eval(e, list(x=2)) >>> # [1] "R" >>> >>> # both versions work >>> 'r<-' = function(value, x) {print("R");} >>> eval(e, list(x=2)) >>> # [1] "R" >>> >>> >>> ### the Expression >>> e[[1]][[1]] # "<-", not "r<-" >>> e[[1]][[2]] # "r(x)" >>> >>> >>> The evaluation of "e" somehow calls "r<-", but evaluates >>> also the argument of r(...). I am still investigating what >>> is actually happening. >>> >> >> The forced evaluation is relevant for subsetting, e.g.: >> expression(r(x)[3] <- 1) >> expression(r(x)[3] <- 1)[[1]][[2]] >> # r(x)[3] # the evaluation details are NOT visible in the >> expression per se; >> # Note: indeed, it makes sens to first evaluate r(x) and then >> to perform the subsetting; >> >> >> However, in the case of a non-subsetted expression: >> r(x) <- 1; >> It would make sense to evaluate lazily r(x) if no subsetting >> is involved (more precisely "r<-"(x, value) ). >> >> Would this have any impact on the current code? >> >> >> Sincerely, >> >> >> Leonard >> >> >>> >>> Sincerely, >>> >>> >>> Leonard >>> >>> >>> On 9/13/2021 9:15 PM, Andrew Simmons wrote: >>>> 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 <mailto: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 <mailto: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 <mailto:R-help@r-project.org> >>>>> mailing list -- To UNSUBSCRIBE and more, see >>>>> https://stat.ethz.ch/mailman/listinfo/r-help >>>>> <https://stat.ethz.ch/mailman/listinfo/r-help> >>>>> PLEASE do read the posting guide >>>>> http://www.R-project.org/posting-guide.html >>>>> <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.