The distinction between 'lexical scope' (where a name has meaning in the text of a program) and 'lifetime' (runtime duration between when object is created and destroyed) can sometimes be confusing, since often these two are highly correlated. However the technique demonstrated by this example is common in functional languages: you give an implementation detail a small lexical scope (that hides the implementation details from callers), but extend its lifetime by capturing it in a closure (so that its lifetime becomes the lifetime of the enclosing object - in this instance the 'incr' function). This is a common way to do encapsulation in functional programming (contrasted with the usual encapsulation technique of public/private in classes in object-oriented programming).
Now, in this particular example, it looks like 'incr' is a top-level function, which means its value lasts for the lifetime of the program (or interactive session if typing into fsi.exe). You could call this a 'leak', but it depends on intent. If you have some unique id counter you need for the entire lifetime of your entire program, then you are going to have to store that counter varable somewhere that it lasts for the whole program. So either this is 'a leak' or 'a by design feature' depending on how 'incr' will be used (will you need to use that function for the whole rest of the program?). In any case, the key point here is that 'incr' holds memory resources, so if you won't need those resources forever, you should arrange for the closure referenced by 'incr' to become unreachable when it is no longer needed. Commonly this might be by making it local to some other function, e.g.
let MyComplicatedFuncThatNeedsALocalCounter args =
let incr =
// as before
// other code that uses incr
// return some result that does not capture incr