Heh ... These self-referential constructs are certainly puzzles... Does this help: fun1 <- function() { 1 body(fun1)[[2]] <<- 'one' 'hi' }> fun1function() { 1 body(fun1)[[2]] <<- 'one' ## note the double '<<" assigning to the parent env 'hi' }> fun1()[1] "hi"> fun1function () { "one" ## the change was made body(fun1)[[2]] <<- "one" "hi" } The point is that assignments within a function occur *within* the function environment unless otherwise specified (either by <<- or the use of the 'environment' argument in 'body<-'() ). This is, of course, central to the functional programming paradigm of no side effects (unless explicitly invoked). NOTE: Correction to this requested if this is wrong in any way!! Cheers, Bert Bert Gunter "The trouble with having an open mind is that people keep coming along and sticking things into it." -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) Bert Gunter "The trouble with having an open mind is that people keep coming along and sticking things into it." -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) On Fri, Apr 1, 2022 at 12:50 PM Grzegorz Smoli?ski <g.smolinski1 at gmail.com> wrote:> > Hi, > > I'm working on a presentation regarding the modification of the > function body on-the-fly and just discovered something I don't > understand. I would like to modify a body of the function within a > function, but I see that it is possible only when explicitly referring > to the environment where the function is defined: > > fun1 <- function() { > 1 > body(fun1)[[2]] <- "one" > } > fun1() > body(fun1) > #> { > #> 1 > #> body(fun1)[[2]] <- "one" > #> } > > fun2 <- function() { > 2 > env <- environment(fun2) > body(env$fun2)[[2]] <- "two" > } > fun2() > body(fun2) > #> { > #> "two" > #> env <- environment(fun2) > #> body(env$fun2)[[2]] <- "two" > #> } > > Can I get some explanation or some links / articles about this, > please? I thought it won't be a difference and I should be able to > modify a function body also in the first case, because I'm changing > something in the parent environment being in the child environment. > > Best regards, > > Grzegorz > > ______________________________________________ > 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.
Grzegorz SmoliĆski
2022-Apr-02 09:31 UTC
[R] Modificatio of function body within a function
Thank you, I think I can say that I get it, especially when reading this explanation: "assignments within a function occur *within* the function environment unless otherwise specified", so this is just like in the example below: a <- 4 fun2 <- function() { a <- 2 } fun2() a #> [1] 4 a <- 4 fun2 <- function() { env <- .GlobalEnv env$a <- 2 } fun2() a #> [1] 2 I would like to ask about one more thing, also regarding the modification of the body of function. There is one phenomenon which I'm actually using during my work with R, but I'm not sure why this happens. Below is an example of this: fun1 <- function() { 1 env <- environment(fun1) body(env$fun1) <- body(env$fun1)[-5] "one" } fun1() #> [1] "one" body(fun1) #> { #> 1 #> env <- environment(fun1) #> body(env$fun1) <- body(env$fun1)[-5] #> } Within a function, I'm removing the last line of code in that function (string "one") and what happens here is that when I use this function (first time), that string is actually returned, so this line of code which is removed is executed. I don't have a good background in computer science and would like to know why this last line of code is executed. Why not - well, I could imagine that when the function is called, it is executed line by line (of course), so before the last line ("one"), this line will be removed and this string won't be returned. However, when Bert mentioned functional paradigm, I have started to think that it may looks like this: a) function is defined b) function is called and in the one before last line of code, some object (fun1) is modified and when something is modified, the copy is made, so the modified function lives in a different memory address. c) the original function (not changed) continues computation and returns the string d) when the execution is finished, then the modified fun1 is bind to the name "fun1" and because this happens in the same environment where the original fun1 was defined and the objects are now different, garbage collector removes original (not modified) fun1 object. Is that, more or less, what happens? Best, Grzegorz pt., 1 kwi 2022 o 23:12 Bert Gunter <bgunter.4567 at gmail.com> napisa?(a):> > Heh ... These self-referential constructs are certainly puzzles... > > Does this help: > > fun1 <- function() { > 1 > body(fun1)[[2]] <<- 'one' > 'hi' > } > > > fun1 > function() { > 1 > body(fun1)[[2]] <<- 'one' ## note the double '<<" assigning to the parent env > 'hi' > } > > > fun1() > [1] "hi" > > > fun1 > function () > { > "one" ## the change was made > body(fun1)[[2]] <<- "one" > "hi" > } > > The point is that assignments within a function occur *within* the > function environment unless otherwise specified (either by <<- or the > use of the 'environment' argument in 'body<-'() ). This is, of > course, central to the functional programming paradigm of no side > effects (unless explicitly invoked). > > NOTE: Correction to this requested if this is wrong in any way!! > > Cheers, > Bert > > > > > Bert Gunter > > "The trouble with having an open mind is that people keep coming along > and sticking things into it." > -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) > > Bert Gunter > > "The trouble with having an open mind is that people keep coming along > and sticking things into it." > -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) > > > On Fri, Apr 1, 2022 at 12:50 PM Grzegorz Smoli?ski > <g.smolinski1 at gmail.com> wrote: > > > > Hi, > > > > I'm working on a presentation regarding the modification of the > > function body on-the-fly and just discovered something I don't > > understand. I would like to modify a body of the function within a > > function, but I see that it is possible only when explicitly referring > > to the environment where the function is defined: > > > > fun1 <- function() { > > 1 > > body(fun1)[[2]] <- "one" > > } > > fun1() > > body(fun1) > > #> { > > #> 1 > > #> body(fun1)[[2]] <- "one" > > #> } > > > > fun2 <- function() { > > 2 > > env <- environment(fun2) > > body(env$fun2)[[2]] <- "two" > > } > > fun2() > > body(fun2) > > #> { > > #> "two" > > #> env <- environment(fun2) > > #> body(env$fun2)[[2]] <- "two" > > #> } > > > > Can I get some explanation or some links / articles about this, > > please? I thought it won't be a difference and I should be able to > > modify a function body also in the first case, because I'm changing > > something in the parent environment being in the child environment. > > > > Best regards, > > > > Grzegorz > > > > ______________________________________________ > > 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.