3 ms·
If your game state is a global because every action in the game changes the global state, then that's great, your game will be alive. There are so many valid st
by cormacrelf 7y ago
If your game state is a global because every action in the game changes the global state, then that's great, your game will be alive. There are so many valid states and perhaps rather few invariants, or you are okay with invariants being enforced once every few seconds. You do what you have to.
Not every program is like this. Consider something like TeX, whose goal is perfect bit for bit reproducibility of documents across every run on every machine. Same with a compiler.
When you say globals, I imagine those kinds of programs having code like this:
add_to_current_doc_index();
fn document_map_overflow() {
ERROR_CODE = 46;
print_current_error();
exit();
}
literally_every_function_could_write_an_error_code();
do_not_call_another_one_without_checking_it();
if ERROR_CODE != 0 { return ...; }
This is what XeTeX code looks like. You don't have to do it like that! You can write this:
pub struct EnforcesOwnInvariants { private_data: [u8; 65536] }
impl EnforcesOwnInvariants {
fn get_first_something(&self) { ... }
fn flush_cache(&mut self) { ... }
}
static GLOBAL_DATA: Mutex<EnforcesOwnInvariants> = ...;
The second kind is better, because you can at least say that any internal invariants in the global data should be upheld in very specific code.
But when you use the first kind, you're completely giving up on being able to point to the line of code responsible for global data having bugs in it. Obviously you can use globals without this problem if you encapsulate them effectively, but you'd need your language to "shepherd" you towards this. All the C codebases that had no such shepherding seem to end up looking exactly like this, and it is truly awful trying to find the source of bugs. You'll notice the languages that shepherd you away from globals (Rust) do so because they want your programs to work when you decide one thread is not enough. This has the side benefit of shepherding you away from global data generally, and mutability rules restrict which code can modify, so there is a huge impact overall on how you look for bugs.
Essentially, you're having the same discussion the original article is saying is fruitless. Globals can be good or bad! You can make them accessible everywhere without actually accessing them everywhere and causing debug problems. But do they make good code easy to write and bad code hard? Absolutely not. They are bad shepherds, pied pipers that offer you easy solutions that make your codebase worse.