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-boun...@r-project.org [mailto:r-help-boun...@r-project.org] On > Behalf Of Tom Roche > Sent: Wednesday, January 04, 2012 1:23 PM > To: r-help@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_ro...@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. ______________________________________________ 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.