I don’t see how this is functionally different to passing an object that contains references to the relate to variables; which I’ll call a context object. Practically, dynamic scoping is more confusing than context objects. void main() { int x = 2; fn(); } Does fn access or change x? You need to inspect the body of fn to know. I would call dynamic scoping a poor form of coupling. Instead of bundling your coupling wir…
> I don’t see how this is functionally different to passing an object that contains references to the relate to variables; which I’ll call a context object. It's the same difference as using environment variables vs command line arguments. Imagine all programs having to pass TERM, DISPLAY, HOME, etc. as arguments in case some descendant process wants to use it and the user override. Like passing TERM, DISPLAY to git…
Interestingly this is exactly what I have been wishing was standard practice for a few years now! Otherwise you end up pickup up implicit configuration from the environment that you didn't intend at all.
> In other words, the issue is that when you have project A using project B using project C, project A has to manually carry around the context of B, and C in case the user wants to override them.
Yes please! That makes the most sense to me. I admit my years of experience with Haskell may have coloured this opinion.