[R] Modificatio of function body within a function

Grzegorz Smoliński g@@mo||n@k|1 @end|ng |rom gm@||@com
Sat Apr 2 11:31:35 CEST 2022


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 using 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 using 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 using 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.



More information about the R-help mailing list