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.

Reply via email to