david.kaethner at gmail.com
2015-Oct-22 14:20 UTC
[R] expression evaluation during recursion
Hello, I?m trying to solve an exercise, where I want to walk through the search path recursively (http://adv-r.had.co.nz/Environments.html <http://adv-r.had.co.nz/Environments.html>). I?m puzzled by a certain behavior and hope somebody can give me an explanation. This code works: listenv <- function(env = parent.frame()) { if (identical(env, emptyenv())) { #stop("reached emptyenv", call. = FALSE) return(env) } else { print(env) listenv(parent.env(env)) } } Here, the calling environment is determined with a default parameter in the function?s formals. However, if I want to assign the calling environment within the function?s body, I get the error message ?infinite recursion?. Also, I never get actual environments (with attributes, that is), only memory addresses like this: <environment: 0x10da46630>. listenv <- function(env) { env <- parent.frame() if (identical(env, emptyenv())) { #stop("reached emptyenv", call. = FALSE) return(env) } else { print(env) listenv(parent.env(env)) } } Any explanation of what?s going on here would be greatly appreciated. I suspect it has to do with when exactly the parent.frame()-expression is evaluated, but that?s not an actual explanation. [[alternative HTML version deleted]]
On 22/10/2015 10:20 AM, david.kaethner at gmail.com wrote:> Hello, > > I?m trying to solve an exercise, where I want to walk through the search path recursively (http://adv-r.had.co.nz/Environments.html <http://adv-r.had.co.nz/Environments.html>). > > I?m puzzled by a certain behavior and hope somebody can give me an explanation. > > This code works: > > listenv <- function(env = parent.frame()) { > if (identical(env, emptyenv())) { > #stop("reached emptyenv", call. = FALSE) > return(env) > } else { > print(env) > listenv(parent.env(env)) > } > } > > Here, the calling environment is determined with a default parameter in the function?s formals. > > However, if I want to assign the calling environment within the function?s body, I get the error message ?infinite recursion?. Also, I never get actual environments (with attributes, that is), only memory addresses like this: <environment: 0x10da46630>.I'm not sure what you were looking for, but "<environment: 0x10da46630>" is the normal way to print an environment, unless it happens to be one of the special named ones (like .GlobalEnv).> > listenv <- function(env) { > env <- parent.frame() > if (identical(env, emptyenv())) { > #stop("reached emptyenv", call. = FALSE) > return(env) > } else { > print(env) > listenv(parent.env(env)) > } > } > > Any explanation of what?s going on here would be greatly appreciated. I suspect it has to do with when exactly the parent.frame()-expression is evaluated, but that?s not an actual explanation.Your function completely ignores the "env" argument. It never recurses. In the first case, "parent.frame()" is only a default value, so recursion happens properly. If you change the first line in the body to these two lines if (missing(env)) env <- parent.frame() it would be equivalent. Duncan Murdoch
david.kaethner at gmail.com
2015-Oct-22 18:44 UTC
[R] expression evaluation during recursion
Hi, I?m sure there?s a ton I don?t understand about environments, but I?m afraid your answer doesn?t make sense to me. If it?s on the search path, the ?print(env)? should yield something like: <environment: package:pryr> attr(,"name") [1] "package:pryr" attr(,"path") [1] "/Library/Frameworks/R.framework/Versions/3.2/Resources/library/pryr? I agree that there would only be an address if it was an unnamed environment such as the ones constructed during function execution. But I?m walking the search path here, so these should all contain information on packages. My question wasn?t so much about how to retrieve information on environments, there are plenty functions concerning that. I just don?t understand why it makes that much of a difference if I put the parent.frame() in the arguments list, or in the function body.> Am 22.10.2015 um 19:05 schrieb Duncan Murdoch <murdoch.duncan at gmail.com>: > > On 22/10/2015 10:20 AM, david.kaethner at gmail.com <mailto:david.kaethner at gmail.com> wrote: >> Hello, >> >> I?m trying to solve an exercise, where I want to walk through the search path recursively (http://adv-r.had.co.nz/Environments.html <http://adv-r.had.co.nz/Environments.html> <http://adv-r.had.co.nz/Environments.html <http://adv-r.had.co.nz/Environments.html>>). >> >> I?m puzzled by a certain behavior and hope somebody can give me an explanation. >> >> This code works: >> >> listenv <- function(env = parent.frame()) { >> if (identical(env, emptyenv())) { >> #stop("reached emptyenv", call. = FALSE) >> return(env) >> } else { >> print(env) >> listenv(parent.env(env)) >> } >> } >> >> Here, the calling environment is determined with a default parameter in the function?s formals. >> >> However, if I want to assign the calling environment within the function?s body, I get the error message ?infinite recursion?. Also, I never get actual environments (with attributes, that is), only memory addresses like this: <environment: 0x10da46630>. > > I'm not sure what you were looking for, but "<environment: 0x10da46630>" > is the normal way to print an environment, unless it happens to be one > of the special named ones (like .GlobalEnv). > >> >> listenv <- function(env) { >> env <- parent.frame() >> if (identical(env, emptyenv())) { >> #stop("reached emptyenv", call. = FALSE) >> return(env) >> } else { >> print(env) >> listenv(parent.env(env)) >> } >> } >> >> Any explanation of what?s going on here would be greatly appreciated. I suspect it has to do with when exactly the parent.frame()-expression is evaluated, but that?s not an actual explanation. > > > Your function completely ignores the "env" argument. It never recurses. > In the first case, "parent.frame()" is only a default value, so > recursion happens properly. If you change the first line in the body to > these two lines > > if (missing(env)) > env <- parent.frame() > > it would be equivalent. > > Duncan Murdoch[[alternative HTML version deleted]]