5 ms·
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. Prac
by DecoPerson 6y ago
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 wires in a neat little set of in/out arguments and a return value (the format of which only needs the function’s declaration, not its definition), you are instead reaching out of and into the function’s body, like sprawling tendrils, as your function has free pickings of your variables.
It also strangely couples the names together. The outer function and the inner function may see the variable in completely different lights, yet dynamic scoping requires the outer use the name prescribed by the inner.
Optimization would be hard without WPO. You’d essentially need to keep a run-time “scope” object for every function. Though, the author’s proposed design for dynamic scoping in C++ means you don’t need it for every function; however that design has its own issues: how would you optimize such a design? It would a puzzling challenge.
- hibbelig 6y agoContext objects need to be passed around, with dynamic scoping you do not need to. You would normally use dynamic scoping for certain global parameters that apply to a lot of operations. Unix shell scripts provide something similar to dynamic scoping with environment variables: If you write a shell script that sets LD_LIBRARY_PATH or TMPDIR, then all programs invoked from that shell script will inherit the values. And if your shell script calls another shell script, then that shell script can again set environment variables, and those are visible until it returns. I would say that environment variables have been a great success story, and folks aren't too confused.
- jolmg 6y ago> 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 in case you want to override them for the configured pager or editor. 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.
- Konohamaru 6y agoThis is the best argument I've read for dynamic scoping thus far.
- masklinn 6y agoIncidentally that makes it super easy to mock out or intercept subsystems if they use dynamically scoped hooks e.g. in most languages intercepting stdio is a pain in the ass (you might have to swap out multiple globals, it's not thread-safe, etc…). If you're in CL however, you can just rebind standard-output and you'll capture what anyone downstack sends there.
- Jtsummers 6y agoOr rebind standard-input and feed an interactive program input from a file or other stream.
- kmonsen 6y agoIsn't it also the worst argument :-) In that it is well explained but I look a little bit in horror on it. For me it seems like dynamic scoping is very similar or at least related to dependency injection. Which seems to be one of those things that really have polarized opinions of developers. Some people love it because the code looks really neat and it is really easy to add new pieces. Other hates it because it is really hard to understand what is happening under the hood. I would say that dynamic scoping is a bit worse (in my opinion) in that it is like dependency injection that are supposed to be modified one or more times in between so it will be almost impossible to figure out why a value is what it is when it goes wrong.
- tome 6y ago> 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 in case you want to override them for the configured pager or editor. 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.