I am not sure what the promises are doing in R
If one runs
a = lapply(seq_len(2), function(n) { function() {n}})
b = lapply(seq_len(2), function(n)
I find it easier to understand in this form:
f=function(n) {function() {n}}
x=1
a=f(x)
x=2
a()
[1] 2
The key part of the documentation is
When a function is called the arguments are matched and then each of the formal arguments is bound to a promise. The expression that was given for that formal argument and a pointer to the environment the function was called from are stored in the promise.
After the call a=f(x), the function argument n is bound to a promise with the name x and a pointer to the global environment .GlobalEnv.
In your lapply examples, the anonymous function function(n) { function() {n}} is called from the global environment each time. This is why every element of the list a gets the same value of n: it's coming from the global environment. I don't see how it's possible to change this behaviour by rewriting lapply.
I posted a comment a while ago that this might be the case as of recent versions of R but here is an offical proof as well that lapply now behaves exactly like your lapply2 version, taken from the news release of R 3.2.0.