Tcl totally has lexical scoping, through proc and apply that create a new frame and thus new local bindings. Closures with explicit bindings (as opposed to tree-walking to find free variables to match with [info locals] which is something Tcl really can't do due to its "list == atom" thing) are easy to do through apply and a way to store the environment.
That last implementation is interesting, although it requires using the `applyc` command to invoke the closure because it has to take it by name instead of by value, which is an unfortunate limitation. The thing you can't do is make a closure that can be invoked just with `apply`. Offhand the only way I can think of to try that is to store the closure data globally under a unique name, but then there's no way to clean up that data when the closure goes away since Tcl doesn't have finalizers (you can run code when a variable goes out of scope, but you can't do it for the value itself).
Yeah, I've been thinking about it for a bit, and the "problem" is that the captured environment needs to be stored somewhere in order to be modified.
applyc could be bundled in the closure to use via `{*}$closure args...` but the fact that it needs to be named defeats the concept of anonymous functions, eh.
The last implementation in https://wiki.tcl-lang.org/page/Closures is pretty nice.