I'm not sure how this is different than introducing a block in C.
What would be the C equivalent of:
(let ((last-response))
(defun get-response ()
(print last-response)
(setf last-response (read))))
(print (get-response))
(print (get-response))
Notice that no other function can use last-response. It only exists for get-response, but it exists outside the scope of get-response. Does C have this?Since the variable in question is only used in one function, you could declare the variable static to that function. It takes some care to make this reentrant, but that's possibly the case in lisp as well.
To share between multiple top-level functions, you can only limit scope to the individual file.
The bigger thing C can't do that lisp can here is defining new functions in arbitrary places. In C variants where you can define local functions, you can indeed capture variables in local scope. And within a function, you can limit scope by creating a new block:
int test() {
int foo = 7;
{
int foo = 9;
}
return foo; // returns 7
}
Even in those C variants, you can't place a new function in global scope from within a function. (let ((x))
(defun func1 ())
(defun func2 ()))
This is what I mean when I say explicit scoping. And it means that the reader/debugger/maintainer knows that this variable only exists for these functions. A static variable's scope is implied by the scope of whatever it's defined in (not sure if that's limited to functions in C), in this case X exists outside of C and has it's own scope, not just it's own extent.Yes, I mentioned that static variables in a function would not extend to multiple functions.
You can share a variable between a restricted set of top level functions by grouping those functions in a single object file that does not expose the variable in question.
I think my only objection is that your phrasing implied what's different is the explicitness of the scoping, when it's actually the flexibility of how functions can be defined (unsurprising, from a lisp).