Live data from Hacker News

Global variables are not the problem

codestyleandtaste.com

61–70 of 165 posts

Re: Global variables are not the problem

#61
post #36

Global variables (in languages where they otherwise make sense and don't have footguns at initialization and whatnot) have two main problems: 1. They work against local reasoning as you analyze the code 2. The semantic lifetime for a bundle of data is rarely actually the lifetime of the program The second of those is easy to guard against. Just give the bundle of data a name associated with its desired lifetime. If y…

I don't think #1 is necessarily true. Take a common case for a global variable, a metric your app is exposing via prometheus. You have some global variable representing its value. Libraries like to hide the global variable sometimes with cuteness like MetricsRegistey.get_metric("foo") but they're globally readable and writable state. And in your function you do a little metric.observe_event() to increment your counter. I think having this value global helps reasoning because the alternative is going to be a really clunky plumbing of the variable down the stack.

Re: Global variables are not the problem

#62

From the article> "Static Function Variable: In C inside a function, you can declare a static variable. You could consider this as a local variable but I don't since it's on the heap, and can be returned and modified outside of the functions. I absolutely avoid this except as a counter whose address I never return." These variables are not on the heap. They are statically allocated. Their visibility is the only thing…

static variable addresses are an extremely important tool in static analysis, for proving certain program invariants hold. In C, a const static often will be able to tell you more about the structure of your code at runtime than a #define macro ever could!

though unless you're programming extremely defensively (eg trying to thwart a nation state), I see no reason why you would use them at runtime

Re: Global variables are not the problem

#63

Earlier quoted context omitted.

You know it is /currently/ accessed on one thread. These are little landmines that add up over time.

The burden is on the programmer adding a new thread to know what they can safely access. The conclusion of your argument looks like 2000s Java - throw a mutex on every property because you never know when it will need to be accessed on a thread. Designs that spread complexity rather than encapsulate it are rarely a good idea.

> Designs that spread complexity rather than encapsulate it are rarely a good idea.

Exactly, globals spread complexity.

You need to look at the implementation of each function to know if you can call it. That’s the landmine.

Re: Global variables are not the problem

#65

Earlier quoted context omitted.

Why are singletons better? That's just a global object. > wrap a mutex What if my program has one thread? Or the threads have clearly defined responsibilities?

Global objects need to be initialized. And if two are ever initialized you run into problems like the above. Singleton is a pattern to ensure that a global objects is only ever initialized once.

Most programming languages written after 1990 let you initialize global variables lazily. The main problem is that the initialization order might be unexpected or you may run into conflicts. Singletons make the order slightly more predictable (based on first variable access), although it is till implicit (lazy).

But singletons are still a terrible idea. The issue with global variables is not just initialization. I would argue it's one of the more minor issues.

The major issues with global variables are:

1. Action at distance (if the variable is mutable)

2. Tight coupling (global dependencies are hard-coded, you cannot use dependency injection)

3. Hidden dependency. The dependency is not only tightly-coupled, it is also hidden from the interface. Client code that calls your function doesn't know that you rely on a global variable and that you can run into conflict with other code using that variable or that you may suddenly start accessing some database it didn't even know about.

Singleton does not solve any of the above. The only thing it ensures is lazy initialization on access.

Re: Global variables are not the problem

#67

This assertion made in the article invalidates the premise of same: With a little encapsulation, you can make globals error-proof ...

What do you suppose is the recommended way to use the encapsulation? ;) This is partly why there's a "defining global variables" section, I know people will will consider some usage as not using a global

> What do you suppose is the recommended way to use the encapsulation? ;) This is partly why there's a "defining global variables" section, I know people will will consider some usage as not using a global

What the post discusses can be distilled into the concept of Referential Transparency[0]:

  A linguistic construction is called referentially 
  transparent when for any expression built from it, 
  replacing a subexpression with another one that denotes the 
  same value[b] does not change the value of the expression.
Any construct which is not referentially transparent can be classified as potentially effectual, which is not a Bad Thing(TM) as if there were no observable effects of a program, it would be useless.

What makes programs easier to prove correct and reason about is when effects are localized to well-defined areas often "at the edges" of the architecture.

What makes programs impossible to prove correct and very difficult to reason about is when effectual logic is pervasive throughout, such as most of the "Global Variable Use Cases" the post advocates.

0 - https://en.wikipedia.org/wiki/Referential_transparency

Re: Global variables are not the problem

#68

The bug in the program reveals a poor understanding of object lifecycles by whoever wrote it. The `obj` argument to `simple` is not globally unique and so it makes a poor location to store global state information (a count of how often `simple` is called, in this example). Never tie global state information to ephemeral objects whose lifetime may be smaller than what you want to track. In this case, they want to know…

[dead]

Re: Global variables are not the problem

#70

Earlier quoted context omitted.

> That one person that creates threads haphazardly will wreak havoc What if someone comes along and starts adding threads and doesn't check what they are accessing? And doesn't read the documented invariants of the design? Well I don't think any project can succeed if that's the level disorganization. Are there certain kinds of bugs that are easy to regress last minute? Yes. A brand new thread without limited state i…

> Who then is responsible for making sure the program is correct? I’d say this is mostly a function of the language or framework. After that, it’s up to the tech leads to provide access patterns/examples that align with the needs of a particular project. My point is not so much that you shouldn’t ever think about the implications of your code, just that contributors are humans and any project with enough contributors…

> I’d say this is mostly a function of the language or framework.

frameworks cannot ensure your program does what it's supposed to. People are responsible, not tools.

> contributors are humans

Yes - which is why I would discourage haphazard thread usage, and document existing thread architecture.

That's safer than "hey I threw on a mutex because who knows where this is accessed from".

Post reply on HN