Making variables immutable in R

There’s no way to get the same effect as with reserved names. A reserved name simply cannot be shadowed (you can assign to `NA` but it never shadows NA — evaluating NA simply never performs a variable lookup). Whereas variables always can.

Incidentally, your lockBinding call in .onLoad is redundant: Bindings for package symbols are locked by default.

You could override <-, this would be a very bad idea in general if done in the global environment, but done in a specific environement if you know what you're doing why not :

X <- new.env()
X$`<-` <- function(e1, e2) {
  sc <-
  if(identical(sc[[2]], quote(foo)))
     stop("invalid left-hand side to assignment")
    eval.parent(, list(sc, list(`<-` = base::`<-`))))

with(X, foo <- 42)
#> Error in foo <- 42: invalid left-hand side to assignment
with(X, bar <- 42)
#> [1] 42

Created on 2019-08-19 by the reprex package (v0.3.0)