```{r}
library('biglm')

datn <- function(n) {
   d <- data.frame(x=runif(n))
   d$y <- d$x>=runif(nrow(d))
   d
}

d <- datn(100000)
formula <- 'y~x'

fitter <- function(formula,d) {
  model <- bigglm(as.formula(formula),d,family=binomial(link='logit'))
  list(predict=function(newd) {predict(model,newdata=newd,type='response')[,1]})
}

model <- fitter(formula,d)
print(head(model$predict(d)))

sizeTest1 <- function(d) {
  model <- fitter(formula,d)
  length(serialize(model, NULL))
}

for(n in c(1000,10000,100000)) {
  print(sizeTest1(datn(n)))
}

#' build a new funcion with a smaller environment
#' @param f input function
#' @param varaibles names we are allowing to be captured in the closere
#' @return new function with closure restricted to varaibles
#' @export
restrictEnvironment <- function(f,varList) {
  oldEnv <- environment(f)
  newEnv <- new.env(parent=parent.env(oldEnv))
  for(v in varList) {
    assign(v,get(v,envir=oldEnv),envir=newEnv)
  }
  environment(f) <- newEnv
  f
}

fitter <- function(formula,d) {
  model <- bigglm(as.formula(formula),d,family=binomial(link='logit'))
  model$family$variance <- c()
  model$family$dev.resids <- c()
  model$family$aic <- c()
  model$family$mu.eta <- c()
  model$family$initialize <- c()
  model$family$validmu <- c()
  model$family$valideta <- c()
  model$family$simulate <- c()
  environment(model$terms) <- new.env(parent=globalenv())
  list(predict=
         restrictEnvironment(function(newd) {
           predict(model,newdata=newd,type='response')[,1]
          },
          'model'))
}



model <- fitter(formula,d)
print(head(model$predict(d)))

for(n in c(1000,10000,100000)) {
  print(sizeTest1(datn(n)))
}
```

```{r}
# trying to observe address
f <- function() {
  a <- list(b = 1)
  print(pryr::address(a))
  a$b <- 2
  print(pryr::address(a))
  a$b <- 3
  print(pryr::address(a))
}
f()

# timing
f1c <- function(n,verbose,shadow) {
  v <- 1:n
  vLast <- c()
  if(shadow) {
    vLast <- v
  }
  if(verbose) {
    print(pryr::address(v))
  }
  for(i in 1:n) {
    v[i] <- v[i]^2
    if(shadow) {
       vLast <- v
    }
    if(verbose) {
       print(pryr::address(v))
    }
  }
  c()
}

f1c(5,TRUE,FALSE)

print(system.time(f1c(30000,FALSE,FALSE)))
print(system.time(f1c(30000,FALSE,TRUE)))
```

