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]]
On 22/10/2015 2:44 PM, david.kaethner at gmail.com wrote:> 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:You never get to the search list.> > <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.You seem to have ignored my explanation. Duncan Murdoch> > >> Am 22.10.2015 um 19:05 schrieb Duncan Murdoch >> <murdoch.duncan at gmail.com <mailto: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>). >>> >>> 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 19:10 UTC
[R] expression evaluation during recursion
> You seem to have ignored my explanation.True, sorry. Thanks for sticking with me. Making sense now.> > Duncan Murdoch > >> >> >>> Am 22.10.2015 um 19:05 schrieb Duncan Murdoch <murdoch.duncan at gmail.com <mailto: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>). >>>> >>>> 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 >> >