#' Preparation of Stack
#'
#' 
#' @details
#' This is a function  factory which makes  the following list of functions.\cr
#'   \code{push, pop,  inspect,  length} and \code{clear}
#'
#' In the usual image of a stack, the newest object will be placed
#' on top of the older objects.
#' However, in this R version, the newest object will be placed
#' at the end of a hidden list named \code{valueList} in the function factory
#' environment.
#'
#' It enables LIFO (Last-In First-Out) or  FILO (First-In Last-Out).
#'
#'
#' @return
#'  A list of functions \cr
#'   \code{push, pop,  inspect,  length} and \code{clear}
#'
#' @examples
#'  # generate functions
#'  stack <- makeStack()
#'
#'  stack$push(3)
#'  stack$push(5)
#'  stack$push(9)
#'  stack$length()
#'  stack$inspect(1:stack$length())
#'  stack$pop()
#'  stack$inspect(1:stack$length())
#'  stack$pop()
#'  stack$inspect(1:stack$length())
#'  stack$pop()
#'
#'  # Below causes error.
#'  # stack$inspect(1:stack$length())
#'
#'
#'  STACK=makeStack()
#'  PUSH <- STACK$push
#'  POP <- STACK$pop
#'  LEN <- STACK$length
#'  INSP <- STACK$inspect
#'  CLEAR <- STACK$clear
#'  PUSH( list(a=1,b=2,c="C"))
#'  PUSH( list(a=12,b=22,c="C2"))
#'  PUSH( list(a=13,b=23,c="C3"))
#'  INSP(1:LEN())
#'  POP()
#'  INSP(1:LEN())
#'  POP()
#'  INSP(1:LEN())
#'
#'
#' @references
#'  The original version is from the answer by Matt: \cr
#'   https://stackoverflow.com/questions/28687806
#'   /a-better-way-to-push-and-pop-to-from-lists-in-r
#'
#'
#' @export
#'

makeStack <- function() {
 # stack generator
 # Shin-ichi Mayekawa
 # inspect, length, clear: 20230908
 # list added in append: 20230908
 # in lazy.tools: 20230921
 #
 # The original version is from the answer by Matt:
 # https://stackoverflow.com/questions/28687806
 # /a-better-way-to-push-and-pop-to-from-lists-in-r
 #
 # This is a function factory which returns functions
 #  push, pop,  inspect,  length and clear.
 #
 # In the usual image of a stack, the newest object will be placed
 # on top of the older objects.
 # However, in this R version, the newest object will be placed
 # at the end of a list.
 # Anyway, the newly put object will be popped first.
 #
 #

 #
 # The objects in the stack will be stored in the following list.
 # This list can be accessed only from the functions generated in this
 # environment.
 #
 valueList <- list()

 # return the following list of functions.
 list(
  push = function(value) {
   valueList <<- append(valueList, list(value) )
  },
  pop = function() {
   value <- utils::tail(valueList, 1)[[1]]
   valueList <<- utils::head(valueList, -1)
   value
  },
  inspect = function(loc){
    if( any(loc <= 0) || any(loc > length(valueList)) ){
      cat("\nerror1:(makeStack:show) loc must be positive and less than"
          , length(valueList),".\n")
      stop()
    }
    return(valueList[loc])
  },
  length = function(){
    length(valueList)
  },
  clear=function(){
    valueList <<- list()
  }
 )
} # end of makeStack


