I think that this is a good example of where dynamic scope is helpful.
We’re used to lexical scope: it’s easy to reason about, and it is a really good default. But sometimes it makes sense for one function to apply settings for all the functions it calls, without interfering with other functions, scopes, threads or processes (like setting a global would).
It’d be nice to be able to say ‘this function should timeout within 10 ms’ and then any function called will just automatically timeout.
Go’s contexts integrate timeouts and cancellation, and permit one to add any value, should one wish to, but you have to be disciplined and add a context argument to every single function. It’d be better, I think, to support it natively in the language. Lisp does this: any variable declared with DEFPARAMETER or DEFVAR is dynamic, and you can locally declare something dynamic too.
One can fake dynamic scoping with thread-local storage and stacks or linked lists, if one needs it, but it can get ugly.
Dynamic scoping doesn’t get the attention or respect I think it deserves. It’s arguably the wrong thing by default, but when it’s useful, it’s really useful.
[1] https://vorpus.org/blog/timeouts-and-cancellation-for-humans...