[R] [newbie] stack operations, or functions with side effects (or both)

William Dunlap wdunlap at tibco.com
Wed Jan 4 23:54:41 CET 2012


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.



More information about the R-help mailing list