Live data from Hacker News

Global variables are not the problem

codestyleandtaste.com

161–165 of 165 posts

Re: Global variables are not the problem

#161
post #147

Earlier quoted context omitted.

The situation is ugly because there is global state by design. But I don't see why the fact that the closure is stored in a mutable location would be a concern for you. Can you think of any conditions where someone would modify it? I'm not really seeing it, and I don't know what your alternative suggestion is going to be to stop them technically. I can tell you when someone would modify a counter variable - every tim…

I think we're talking past each other here. The issue is that the enclosed state of counter is exposed globally and can be accessed without synchronization. I suppose yes one could also reassign counter to a different function (and you'd need to be aware of that) but my point is that you still need some kind of sync if you're calling counter all over the place, just like you would with a global variable

> The issue is that the enclosed state of counter is exposed globally and can be accessed without synchronization.

Maybe throw up a code example? I don't follow what you're getting at.

Re: Global variables are not the problem

#162
post #103

> Global Variables Are Not the Problem It should have been "Mutability is the Problem, Globalness is not".

I'm the author. No, I completely disagree. No one ever complains about logs and malloc except having too much of them - A line I removed from this article The next article has examples and IMO much better, but makes no mention of action at a distance, and currently makes no mention of how people use clone to prevent mutability.

I dont understand how your comment relates to my comment, beyond that you disagree.

Re: Global variables are not the problem

#163
post #162

Earlier quoted context omitted.

I'm the author. No, I completely disagree. No one ever complains about logs and malloc except having too much of them - A line I removed from this article The next article has examples and IMO much better, but makes no mention of action at a distance, and currently makes no mention of how people use clone to prevent mutability.

I dont understand how your comment relates to my comment, beyond that you disagree.

I like mutation in global variables. I don't think it's the problem. I'm explaining it in my next article

Re: Global variables are not the problem

#164

I find the concept of a context structure passed as the first parameter to all your functions with all your "globals" to be very compelling for this sort of stuff.

Hard disagree. If I have 500 functions, I don't want to extrapolate out the overhead of passing a state object around to all of them. That's a waste of effort, and frankly makes me think you want to code using an FP paradigm even in imperative languages. Module-level and thread-level "globals" are fine. You gain nothing (other than some smug ivory tower sense of superiority) by making your functions pure and passing…

It's one register. You gain that much performance from the single optimization of not updating rbp in release builds.

Re: Global variables are not the problem

#165

Earlier quoted context omitted.

I did not say you are targeting OP. I meant that you are degrading your parent commenter. This: "You gain nothing (other than some smug ivory tower sense of superiority) by making your functions pure and passing around a global state object to every single method invocation." ...is neither productive nor actually true. But I'll save the latter part for your other reply.

I'll take my medicine. :) I'm not above being put in my place and being shown the light. (And when I said OP, I did mean the parent poster) You should also understand that the "you" in my comment you quoted is the colloquial you and not necessarily the parent poster. So lay it on me.

Alright now. Let's have a quick go at this:

"You gain nothing (other than some smug ivory tower sense of superiority) by making your functions pure and passing around a global state object to every single method invocation."

So, we already cleared it up that using that tone is not inviting discussion and shows emotional bias and that has no place in technical discussions, I believe. You said you are open to have your mind changed. Let me give you a few loosely separate (but ultimately bound to each other) arguments in favor of passing around state to each function individually.

- All functions that operate on such state are trivially testable in isolation. This is not a theoretical benefit, I've experienced it hundreds of times ever since I started working mainly with Elixir for almost 9 years now (though I still code Golang and Rust). The amount of bugs I ended up being paid to fix was confusing even to me, just for utilizing this one way of working.

- Explicit dependencies, though this one is muddy because f.ex. in Elixir that's strongly but dynamically typed this benefit is nearly non-existent; I am talking mostly about statically typed languages here, especially Rust. If you have to operate on stuff that implements this or that trait then that's a very clear contract and the code becomes that much clearer with scarcely any need for documenting those functions (though docs do help in other ways there f.ex. "how do we use this so it's, you know, useful" -- but that still means that you get to skip documenting trivia which is still a win).

- LANGUAGE-DEPENDENT: ability to construct pipes (specific to Elixir, OCaml, F# and probably a few others). Consider this:

    websocket
    |> check_for_bearer_token(req.headers)
    |> authenticate()
    |> authorize(can_edit_orders?())
...while passing around the same state (piping passes the first function argument down akin to currying) makes for a super terse and readable code. It was and still is a game changer for many. Piping is what I sorely miss in Golang and Rust; gods, the code is so much uglier without it though their method chaining gets you almost there as well -- fair is fair.

Also, piping almost completely negates the inconvenience that you hinted at.

- Generally giving you a better idea of the dependency graph in your code. Again, a game changer for me. In my 9 years with Java this was my biggest pain. At one point you just give up and start throwing crap at the wall until something works (or doesn't). Not that I did mind the longer dev times of Java but the productivity was just abysmal with all the DI frameworks. I am aware that things improved since then but back when I finally gave up on Java back in 2009-2011 (gradually) it was still terrible.

OK, I don't have much to go on from your otherwise fairly small comment and I already extrapolated quite a lot. Let me know what you think.

But, one rule: "I don't like it" is not allowed. It's not about "liking" stuff, it's about recognizing something that helps productivity and increases clarity.

Post reply on HN