4 ms·
> Given a block of code, it's impossible to tell what effect it (or its sub-calls) might have on the global state. That's true. The equivalent effect in the "a
by Udo 13y ago
> Given a block of code, it's impossible to tell what effect it (or its sub-calls) might have on the global state.
That's true. The equivalent effect in the "all local" paradigm is local objects the state of which can't meaningfully be understood or manipulated by neither the programmer nor other objects, leading again to unexpected behavior that is painful to track down.
A lot of the precautions that are common sense when working with global data are already instinctively followed (or at least understood) by most programmers I think. In effect the lenses are already working when there's an understanding when and where manipulation occurs. This mostly coincides with the notion that complex data should be manipulated by a well-defined model and wherever sensible there should be only one mechanism for doing it.
- mercurial 13y ago> That's true. The equivalent effect in the "all local" paradigm is local objects the state of which can't meaningfully be understood or manipulated by neither the programmer nor other objects, leading again to unexpected behavior that is painful to track down. def foo(x): x_plus_one = add_one(x) x_plus_one_times_two = times_two(x_plus_one) return x_plus_one_times_two Here is a function with some local state. Which part do you feel "can't meaningfully be understood or manipulated by [...] the programmer"? I'm not trying to bait you, but I'm struggling to grasp the argument you are making.
- Udo 13y agoOf course it's always possible to construct an infinite number of neat little functions that are not like that. However, I remember lots of times when I had to fight with some external libraries that had exactly the problem I'm describing. I don't quite understand how your illustration is relevant. The issue is not that simple and well-defined functions can't have any internal state that is easy to follow. I didn't argue this doesn't exist. I said that many times it's not what you find out there. Abstractly speaking, when I say "A often has the property B", you can't meaningfully counter that with "you're wrong, here's an example where !B".
- mercurial 13y agoI think I have misread your comment. I thought you were making sweeping statements about local state in general. That said, I'd still appreciate an example. I haven't noticed any special issues wrt to understanding programs made of immutable-from-the outside objects or local variables.
- usea 13y agoHi. I'm sorry to be pedantic, but the confusion here stems from your use of "equivalent" in responding to a quote that used "impossible." You never said "often," but you did imply you were describing an also-impossible thing. Fortunately the confusion is cleared up now.
- lomnakkus 13y agoImmutable local state is (as you've observed in that example) harmless, but once you start mutating closed-over state, you've given up completely on referential transparency[1] which gives you a lot of power when reasoning about what code does (and doesn't!) do. [1] https://en.wikipedia.org/wiki/Referential_transparency_%28computer_science%29 https://en.wikipedia.org/wiki/Referential_transparency_%28co...
- davexunit 13y agoI think closed-over mutable state certainly has its place. For example, delay and force in Scheme. Mutable local state is used to memoize the result of the delayed procedure. Of course, it would be terrible for a large program to keep all of its state within a closure. You eliminate the benefits of live-coding from your REPL at that point since you can only directly affect the top-level environment.
- mercurial 13y agoCertainly, but you don't even need closures for this: def foo(): a = [] append_foo(a) return a def append_foo(a): a.append('foo') But then I wouldn't call this "local mutability", in the sense that you modify your list in a different part of the code. Not a problem in a trivial example like this, definitively an issue when the actual action performed is ten levels deep.
- Gravityloss 13y agoIn a way, traditional static memory style C does this. You can't return locally created variables [beyond primitives]. Beyond simple primitive reading/returning functions, you often create some arrays or structs, then pass a pointer to the necessary arrays and structs to your functions, so it can read and write them. This way the functions can stay pure.
- chas 13y agoTaking pure to mean referentially transparent, I'm not sure I understand your point here. If you are mutating a statically allocated struct or array passed by reference, doesn't that have a very similar effect to global variables? It makes the dependence explicit rather than implicit which is useful, but it is still effectively global state.