An embedded and charset-unspecified text was scrubbed... Name: not available URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20081218/d42be6e0/attachment.pl>
understanding recursive functions
10 messages · joseph.g.boyer at gsk.com, Jeffrey Horner, (Ted Harding) +3 more
joseph.g.boyer at gsk.com wrote on 12/18/2008 04:22 PM:
I'm trying to understand the use of recursive functions described on page
45 of An Introduction to R by the R core development team.
A function is a list of expressions, which all get executed with only the
last being assigned to a global variable, right?
So if a function refers recursively to itself, it should simply start with
the first
expression and go from there. At least that is my understanding of why the
example given on page 45 works.
In light of the above, I would appreciate it if someone would understand
why the following example does not work:
q <- function(x,h) {if (x < 2) {x <<- x+1; return(q(x))} else return(x)}
If x < 1, this should add 1 to x and go back to the beginning of the if
expression, and the final result should be 2. So q(0) should return 2. But
it returns an error message.
All references to x save one (the assignment with the <<- operator) are
found within the current frame, not by lexical scoping, and hence is
never changed... producing infinite recursion. The following at least
fixes your example:
All references to x save one (the assignment with the <<- operator) are
found within the current frame, not by lexical scoping, and hence is
never changed... producing infinite recursion. The following at least
fixes your example:
q <- function(x,h) {if (x < 2) {x <<- x+1; x <- x+1; return(q(x))} else
return(x)}
ls() # no x in global env just yet
q(-10)
ls()
Jeff
Joe Boyer Statistical Sciences Renaissance Bldg 510, 3233-D Mail Stop RN0320 8-275-3661 cell: (610) 209-8531 [[alternative HTML version deleted]]
______________________________________________ R-help at r-project.org mailing list 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.
On 18-Dec-08 22:33:28, Jeffrey Horner wrote:
joseph.g.boyer at gsk.com wrote on 12/18/2008 04:22 PM:
I'm trying to understand the use of recursive functions described
on page 45 of An Introduction to R by the R core development team.
A function is a list of expressions, which all get executed with
only the last being assigned to a global variable, right?
So if a function refers recursively to itself, it should simply
start with the first expression and go from there. At least that
is my understanding of why the example given on page 45 works.
In light of the above, I would appreciate it if someone would
understand why the following example does not work:
q <- function(x,h) {if (x < 2) {x <<- x+1; return(q(x))} else
return(x)}
If x < 1, this should add 1 to x and go back to the beginning of
the if expression, and the final result should be 2. So q(0) should
return 2.
But it returns an error message.
All references to x save one (the assignment with the <<- operator)
are found within the current frame, not by lexical scoping, and
hence is never changed... producing infinite recursion. The following
at least fixes your example:
q <- function(x,h) {if (x < 2) {x <<- x+1; x <- x+1; return(q(x))} else
return(x)}
ls() # no x in global env just yet
q(-10)
ls()
The following fixes it even more simply (using the same principles):
q <- function(x,h){
if (x < 2) {u <- x+1; return(q(u))} else return(x)
}
Note that "<<-" is not necessary.
Just to test the method more thoroughly:
q <- function(x,h){
if (x < 2) {u <- x+h; return(q(u,h))} else return(x)
}
q(0,0.3)
# [1] 2.1
Ted.
--------------------------------------------------------------------
E-Mail: (Ted Harding) <Ted.Harding at manchester.ac.uk>
Fax-to-email: +44 (0)870 094 0861
Date: 18-Dec-08 Time: 22:51:41
------------------------------ XFMail ------------------------------
Jeffrey Horner wrote:
joseph.g.boyer at gsk.com wrote on 12/18/2008 04:22 PM:
I'm trying to understand the use of recursive functions described on
page 45 of An Introduction to R by the R core development team.
A function is a list of expressions, which all get executed with only
the last being assigned to a global variable, right? So if a function
refers recursively to itself, it should simply start with the first
expression and go from there. At least that is my understanding of
why the example given on page 45 works.
In light of the above, I would appreciate it if someone would
understand why the following example does not work:
q <- function(x,h) {if (x < 2) {x <<- x+1; return(q(x))} else return(x)}
If x < 1, this should add 1 to x and go back to the beginning of the
if expression, and the final result should be 2. So q(0) should
return 2. But
it returns an error message.
All references to x save one (the assignment with the <<- operator) are found within the current frame, not by lexical scoping, and hence is never changed...
i'd say all references in the code above are looked up by lexical
scoping. the catch is that the assignment operator <<- specifies that
the assignment should be made not to a local variable (in the current
environment), but to the appropriately named variable in the nearest
enclosing environment, starting with the direct parent, ending with the
global environment.
the closure environment of the function is the global environment, and
this is the parent environment for the environment within a call to q.
the assigned-to x is always looked up first in the parent (thus, global)
environment, and that's where the assignment is made. all other
occurrences of the identifier 'x' are looked up starting from the call
environment, and they are bound there, since x is a parameter of q. q
calls itself with the same value it receives, first assigning to the
global x, but with little sense, since it always assigns the same value.
it's a pity that <<- is not explained in ?`<<-` clearly enough:
" The operators '<<-' and '->>' cause a search to made through the
environment for an existing definition of the variable being
assigned. If such a variable is found (and its binding is not
locked) then its value is redefined, otherwise assignment takes
place in the global environment. Note that their semantics differ
from that in the S language, but are useful in conjunction with
the scoping rules of R. See 'The R Language Definition' manual
for further details and examples."
the search is made through the environment, but *starting at the parent*
(and this means the lexical parent as in parent.env, not the dynamic
parent as in parent.frame):
x = 0
foo = function(x) { x <<- 1; x }
foo(2)
# 2, not 1
x
# 1, not 0
clearly, in a call to foo x is found in the call environment, but is not
assigned there.
vQ
Wacek Kusnierczyk wrote:
it's a pity that <<- is not explained in ?`<<-` clearly enough:
" The operators '<<-' and '->>' cause a search to made through the
environment for an existing definition of the variable being
assigned. If such a variable is found (and its binding is not
locked) then its value is redefined, otherwise assignment takes
place in the global environment. Note that their semantics differ
from that in the S language, but are useful in conjunction with
the scoping rules of R. See 'The R Language Definition' manual
for further details and examples."
the description is further imprecise as to what happens if such a
variable is found but is locked:
foo = function() {
x = 0
lockBinding("x", environment())
(function() x <<- 1)()
unlockBinding("x", environment())
}
foo()
# error
if analysed logically (IF (found AND not locked THEN assign) ELSE assign
globally), the description is wrong.
vQ
Wacek Kusnierczyk wrote:
Wacek Kusnierczyk wrote:
it's a pity that <<- is not explained in ?`<<-` clearly enough:
" The operators '<<-' and '->>' cause a search to made through the
environment for an existing definition of the variable being
assigned. If such a variable is found (and its binding is not
locked) then its value is redefined, otherwise assignment takes
place in the global environment. Note that their semantics differ
from that in the S language, but are useful in conjunction with
the scoping rules of R. See 'The R Language Definition' manual
for further details and examples."
the description is further imprecise as to what happens if such a
variable is found but is locked:
foo = function() {
x = 0
lockBinding("x", environment())
(function() x <<- 1)()
unlockBinding("x", environment())
}
foo()
# error
if analysed logically (IF (found AND not locked THEN assign) ELSE assign
globally), the description is wrong.
Yes. If such a variable is found then its value is redefined (unless its binding is locked), otherwise assignment take place in the global environment.
O__ ---- Peter Dalgaard ?ster Farimagsgade 5, Entr.B c/ /'_ --- Dept. of Biostatistics PO Box 2099, 1014 Cph. K (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk) FAX: (+45) 35327907
Peter Dalgaard wrote:
Wacek Kusnierczyk wrote:
" The operators '<<-' and '->>' cause a search to made through the
environment for an existing definition of the variable being
assigned. If such a variable is found (and its binding is not
locked) then its value is redefined, otherwise assignment takes
place in the global environment. Note that their semantics differ
from that in the S language, but are useful in conjunction with
the scoping rules of R. See 'The R Language Definition' manual
for further details and examples."
the description is further imprecise as to what happens if such a
variable is found but is locked:
foo = function() {
x = 0
lockBinding("x", environment())
(function() x <<- 1)()
unlockBinding("x", environment())
}
foo()
# error
if analysed logically (IF (found AND not locked THEN assign) ELSE assign
globally), the description is wrong.
Yes. If such a variable is found then its value is redefined (unless its binding is locked), otherwise assignment take place in the global environment.
it might help the help to be have the help say that if the variable is found but locked then an error is raised. vQ
-----Original Message----- From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf Of Ted.Harding at manchester.ac.uk Sent: Thursday, December 18, 2008 2:52 PM To: r-help at r-project.org Cc: joseph.g.boyer at gsk.com Subject: Re: [R] understanding recursive functions On 18-Dec-08 22:33:28, Jeffrey Horner wrote:
joseph.g.boyer at gsk.com wrote on 12/18/2008 04:22 PM:
I'm trying to understand the use of recursive functions described
on page 45 of An Introduction to R by the R core development team.
A function is a list of expressions, which all get executed with
only the last being assigned to a global variable, right?
So if a function refers recursively to itself, it should simply
start with the first expression and go from there. At least that
is my understanding of why the example given on page 45 works.
In light of the above, I would appreciate it if someone would
understand why the following example does not work:
q <- function(x,h) {if (x < 2) {x <<- x+1; return(q(x))} else
return(x)}
If x < 1, this should add 1 to x and go back to the beginning of
the if expression, and the final result should be 2. So q(0) should
return 2.
But it returns an error message.
All references to x save one (the assignment with the <<- operator) are found within the current frame, not by lexical scoping, and hence is never changed... producing infinite recursion. The
following
at least fixes your example:
q <- function(x,h) {if (x < 2) {x <<- x+1; x <- x+1;
return(q(x))} else
return(x)} ls() # no x in global env just yet q(-10) ls()
The following fixes it even more simply (using the same principles):
q <- function(x,h){
if (x < 2) {u <- x+1; return(q(u))} else return(x)
}
Note that "<<-" is not necessary.
Just to test the method more thoroughly:
q <- function(x,h){
if (x < 2) {u <- x+h; return(q(u,h))} else return(x)
}
q(0,0.3)
# [1] 2.1
Ted.
I am by no means an expert in programming so I will defer to the experts. But assuming the OP was not intentionally trying to assign in a parent environment, couldn't the above function be written as
q <- function(x,h){if (x < 2) q(x+h,h) else return(x)
Hope this is helpful,
Dan
Daniel J. Nordlund
Washington State Department of Social and Health Services
Planning, Performance, and Accountability
Research and Data Analysis Division
Olympia, WA 98504-5204
-----Original Message----- From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf Of Nordlund, Dan (DSHS/RDA) Sent: Thursday, December 18, 2008 5:00 PM To: r-help at r-project.org Subject: Re: [R] understanding recursive functions
-----Original Message----- From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf Of Ted.Harding at manchester.ac.uk Sent: Thursday, December 18, 2008 2:52 PM To: r-help at r-project.org Cc: joseph.g.boyer at gsk.com Subject: Re: [R] understanding recursive functions On 18-Dec-08 22:33:28, Jeffrey Horner wrote:
joseph.g.boyer at gsk.com wrote on 12/18/2008 04:22 PM:
I'm trying to understand the use of recursive functions described on page 45 of An Introduction to R by the R core
development team.
A function is a list of expressions, which all get executed with
only the last being assigned to a global variable, right?
So if a function refers recursively to itself, it should simply
start with the first expression and go from there. At least that
is my understanding of why the example given on page 45 works.
In light of the above, I would appreciate it if someone would
understand why the following example does not work:
q <- function(x,h) {if (x < 2) {x <<- x+1; return(q(x))} else
return(x)}
If x < 1, this should add 1 to x and go back to the beginning of
the if expression, and the final result should be 2. So
q(0) should
return 2. But it returns an error message.
All references to x save one (the assignment with the <<-
operator)
are found within the current frame, not by lexical scoping, and hence is never changed... producing infinite recursion. The
following
at least fixes your example:
q <- function(x,h) {if (x < 2) {x <<- x+1; x <- x+1;
return(q(x))} else
return(x)} ls() # no x in global env just yet q(-10) ls()
The following fixes it even more simply (using the same principles):
q <- function(x,h){
if (x < 2) {u <- x+1; return(q(u))} else return(x)
}
Note that "<<-" is not necessary.
Just to test the method more thoroughly:
q <- function(x,h){
if (x < 2) {u <- x+h; return(q(u,h))} else return(x)
}
q(0,0.3)
# [1] 2.1
Ted.
I am by no means an expert in programming so I will defer to
the experts. But assuming the OP was not intentionally trying
to assign in a parent environment, couldn't the above
function be written as
q <- function(x,h){if (x < 2) q(x+h,h) else return(x)
Sorry, I forgot the final '}' . Or I think you can eliminate the leading '{' and final '}' in this case.
q <- function(x,h) {if (x < 2) q(x+h,h) else return(x)}
Hope this is helpful, Dan Daniel J. Nordlund Washington State Department of Social and Health Services Planning, Performance, and Accountability Research and Data Analysis Division Olympia, WA 98504-5204
______________________________________________ R-help at r-project.org mailing list 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.
An embedded and charset-unspecified text was scrubbed... Name: not available URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20081219/cb27a442/attachment.pl>