Tom Roche
2012-Jan-04 21:22 UTC
[R] [newbie] stack operations, or functions with side effects (or both)
summary: Specifically, how does one do stack/FIFO operations in R? Generally, how does one code functions with side effects in R? details: I have been a coder for years, mostly using C-like semantics (e.g., Java). I am now trying to become a scientist, and to use R, but I don't yet have the sense of "good R" and R idiom (i.e., expressions that are to R what (e.g.) the Schwartzian transform is to Perl). I have a data-assimilation problem for which I see a solution that wants a stack--or, really, just a pop(...) such that * s <- c(1:5) * print(s) [1] 1 2 3 4 5 * pop(s) [1] 1 * print(s) [1] 2 3 4 5 but in fact I get> pop(s)Error: could not find function "pop" and Rseek'ing finds me nothing. When I try to write pop(...) I get pop1 <- function(vector_arg) { + length(vector_arg) -> lv + vector_arg[1] -> ret + vector_arg <<- vector_arg[2:lv] + ret + }> > pop1(s)[1] 1> print(s)[1] 1 2 3 4 5 i.e., no side effect on the argument pop2 <- function(vector_arg) { + length(vector_arg) -> lv + vector_arg[1] -> ret + assign("vector_arg", vector_arg[2:lv]) + return(ret) + }> > pop2(s)[1] 1> print(s)[1] 1 2 3 4 5 ditto :-( What am I missing? * Is there already a stack API for R (which I would expect)? If so, where? * How to cause the desired side effect to the argument in the code above? TIA, Tom Roche <Tom_Roche at pobox.com>
Justin Haynes
2012-Jan-04 21:31 UTC
[R] [newbie] stack operations, or functions with side effects (or both)
do s[1] and s[-1] do what you're looking for? those are just to display... if you want to change s, you need to reassign it or fiddle with namespacing. however, I'd say it is better to write R code as though data structures are immutable until you explicitly re-assign them rather than trying to deal with side effects and state...> pop <- function(vec){+ print(vec[1]) + print(vec[-1]) + return(vec[-1]) +}> s <- 1:5 > s <- pop(s)[1] 1 [1] 2 3 4 5> s[1] 2 3 4 5>On Wed, Jan 4, 2012 at 1:22 PM, Tom Roche <Tom_Roche@pobox.com> wrote:> > summary: Specifically, how does one do stack/FIFO operations in R? > Generally, how does one code functions with side effects in R? > > details: > > I have been a coder for years, mostly using C-like semantics (e.g., > Java). I am now trying to become a scientist, and to use R, but I don't > yet have the sense of "good R" and R idiom (i.e., expressions that are > to R what (e.g.) the Schwartzian transform is to Perl). > > I have a data-assimilation problem for which I see a solution that > wants a stack--or, really, just a pop(...) such that > > * s <- c(1:5) > * print(s) > [1] 1 2 3 4 5 > * pop(s) > [1] 1 > * print(s) > [1] 2 3 4 5 > > but in fact I get > > > pop(s) > Error: could not find function "pop" > > and Rseek'ing finds me nothing. When I try to write pop(...) I get > > pop1 <- function(vector_arg) { > + length(vector_arg) -> lv > + vector_arg[1] -> ret > + vector_arg <<- vector_arg[2:lv] > + ret > + } > > > > pop1(s) > [1] 1 > > print(s) > [1] 1 2 3 4 5 > > i.e., no side effect on the argument > > pop2 <- function(vector_arg) { > + length(vector_arg) -> lv > + vector_arg[1] -> ret > + assign("vector_arg", vector_arg[2:lv]) > + return(ret) > + } > > > > pop2(s) > [1] 1 > > print(s) > [1] 1 2 3 4 5 > > ditto :-( What am I missing? > > * Is there already a stack API for R (which I would expect)? If so, where? > > * How to cause the desired side effect to the argument in the code above? > > TIA, Tom Roche <Tom_Roche@pobox.com> > > ______________________________________________ > R-help@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. >[[alternative HTML version deleted]]
William Dunlap
2012-Jan-04 22:54 UTC
[R] [newbie] stack operations, or functions with side effects (or both)
R functions should not alter their arguments, except for 'replacement' functions that are called on the left side of an assignment operators (e.g., x[1]<-10 calls the replacement function `[<-`). R functions cam use their enclosing environments to save state. E.g., the following makeStack function make an object whose state (consisting of the variable 'stack') is accessible from the functions in the list that it returns: makeStack <- function () { stack <- list() list(pop = function() { if (length(stack) == 0) { # get from an enclosing env. retval <- NULL } else { retval <- stack[[length(stack)]] # get from an enclosing env. stack <<- stack[-length(stack)] # assign in an enclosing env. } retval }, push = function(x) { stack[[length(stack) + 1]] <<- x # assign in an enclosing env. invisible(x) }) } The following calls make two stack objects and use them: > aStack <- makeStack() > anotherStack <- makeStack() > aStack$push("one") > anotherStack$push(as.roman(1)) > anotherStack$push(as.roman(2)) > aStack$push("two") > aStack$push("three") > anotherStack$pop() [1] II > anotherStack$pop() [1] I > anotherStack$pop() NULL > aStack$pop() [1] "three" > aStack$pop() [1] "two" There are various encapsulations of this method in R. See, e.g., "reference classes" or the "proto" package. Bill Dunlap Spotfire, TIBCO Software wdunlap tibco.com> -----Original Message----- > From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf Of Tom Roche > Sent: Wednesday, January 04, 2012 1:23 PM > To: r-help at r-project.org > Subject: [R] [newbie] stack operations, or functions with side effects (or both) > > > summary: Specifically, how does one do stack/FIFO operations in R? > Generally, how does one code functions with side effects in R? > > details: > > I have been a coder for years, mostly using C-like semantics (e.g., > Java). I am now trying to become a scientist, and to use R, but I don't > yet have the sense of "good R" and R idiom (i.e., expressions that are > to R what (e.g.) the Schwartzian transform is to Perl). > > I have a data-assimilation problem for which I see a solution that > wants a stack--or, really, just a pop(...) such that > > * s <- c(1:5) > * print(s) > [1] 1 2 3 4 5 > * pop(s) > [1] 1 > * print(s) > [1] 2 3 4 5 > > but in fact I get > > > pop(s) > Error: could not find function "pop" > > and Rseek'ing finds me nothing. When I try to write pop(...) I get > > pop1 <- function(vector_arg) { > + length(vector_arg) -> lv > + vector_arg[1] -> ret > + vector_arg <<- vector_arg[2:lv] > + ret > + } > > > > pop1(s) > [1] 1 > > print(s) > [1] 1 2 3 4 5 > > i.e., no side effect on the argument > > pop2 <- function(vector_arg) { > + length(vector_arg) -> lv > + vector_arg[1] -> ret > + assign("vector_arg", vector_arg[2:lv]) > + return(ret) > + } > > > > pop2(s) > [1] 1 > > print(s) > [1] 1 2 3 4 5 > > ditto :-( What am I missing? > > * Is there already a stack API for R (which I would expect)? If so, where? > > * How to cause the desired side effect to the argument in the code above? > > TIA, Tom Roche <Tom_Roche at pobox.com> > > ______________________________________________ > 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.
Patrick Burns
2012-Jan-05 08:39 UTC
[R] [newbie] stack operations, or functions with side effects (or both)
There is a crude implementation of stacks in 'S Poetry' (available on www.burns-stat.com). I haven't looked at it, but I'd guess that code would work in R as well. On 04/01/2012 21:22, Tom Roche wrote:> > summary: Specifically, how does one do stack/FIFO operations in R? > Generally, how does one code functions with side effects in R? > > details: > > I have been a coder for years, mostly using C-like semantics (e.g., > Java). I am now trying to become a scientist, and to use R, but I don't > yet have the sense of "good R" and R idiom (i.e., expressions that are > to R what (e.g.) the Schwartzian transform is to Perl). > > I have a data-assimilation problem for which I see a solution that > wants a stack--or, really, just a pop(...) such that > > * s<- c(1:5) > * print(s) > [1] 1 2 3 4 5 > * pop(s) > [1] 1 > * print(s) > [1] 2 3 4 5 > > but in fact I get > >> pop(s) > Error: could not find function "pop" > > and Rseek'ing finds me nothing. When I try to write pop(...) I get > > pop1<- function(vector_arg) { > + length(vector_arg) -> lv > + vector_arg[1] -> ret > + vector_arg<<- vector_arg[2:lv] > + ret > + } >> >> pop1(s) > [1] 1 >> print(s) > [1] 1 2 3 4 5 > > i.e., no side effect on the argument > > pop2<- function(vector_arg) { > + length(vector_arg) -> lv > + vector_arg[1] -> ret > + assign("vector_arg", vector_arg[2:lv]) > + return(ret) > + } >> >> pop2(s) > [1] 1 >> print(s) > [1] 1 2 3 4 5 > > ditto :-( What am I missing? > > * Is there already a stack API for R (which I would expect)? If so, where? > > * How to cause the desired side effect to the argument in the code above? > > TIA, Tom Roche<Tom_Roche at pobox.com> > > ______________________________________________ > 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. >-- Patrick Burns pburns at pburns.seanet.com twitter: @portfolioprobe http://www.portfolioprobe.com/blog http://www.burns-stat.com (home of 'Some hints for the R beginner' and 'The R Inferno')