3 ms·
The whole topic of global state is very interesting and one I approach cautiously. I'd love to hear what more experienced programmers have to saw. 1. Quake 3 r
by sillysaurus3 10y ago
The whole topic of global state is very interesting and one I approach cautiously. I'd love to hear what more experienced programmers have to saw.
1. Quake 3 relied heavily on global state. It was good design, and the engine produced billions in revenue.
2. Emacs relies heavily on global state. A global variable is a first-class citizen. When a package declares a global variable, it's a contract between the package author and the user that "You may configure the behavior of this package by binding this variable to a new value, then invoking one of my functions." Emacs lisp has language constructs which makes this easier: `(let* ((foo-state 42)) (foo-bar))` will update the global variable `foo-state` to 42, call the global function `foo-bar`, and ensures that `foo-state` is returned to its previous value even if an error occurs and an exception is propagated. In other words, global variables are the interface to a module, just like a module's functions, and global variables are almost never left in an unexpected or invalid state due to errors.
This system works shockingly well in practice. Emacs is basically a gigantic state simulation, and it parallels a game engine quite strongly.
The Emacs Lisp language itself is cumbersome, which has led many to dismiss it as ancient. The true power of emacs has little to do with lisp and almost everything to do with excellent design decisions.
3. The history of programming informs us that those who hold to dogma are quickly made obsolete. Every tool and pattern has its place. A technique that simplifies X in a certain domain will make X far more complicated in a different domain. Context matters.
- saurik 10y agoThe Emacs property you are demonstrating with let is "dynamic scoping" and not "global variables" (which is leading to a weird and essentially incorrect description, even if it is difficult to notice a behavior difference between that mental model and what really happens).
- sillysaurus3 10y agoA global variable is a variable with global scope, meaning that it is visible and accessible throughout the program, unless shadowed. Emacs added lexical scoping several years ago. When a global variable is declared in emacs using defvar, in addition to becoming globally accessible, the symbol is also flagged as special. This causes it to use dynamic binding whenever it is `let`-bound, even if lexical scoping is in effect. I pointed out dynamic binding in order to call attention to a technique that allows global variables to be composed into large-scale systems without being hindered by the problems traditionally associated with global state. But if you'd like more precision, feel free to ask.
- TeMPOraL 10y ago> The true power of emacs has little to do with lisp and almost everything to do with excellent design decisions. Those design decisions didn't come out of the vacuum. The ability to patch and modify almost everything at runtime is something that came out of Lisp and Smalltalk, and wasn't even on the map of the (currently) mainstream languages until very recently. Dynamic scoping is something that AFAIK has strong Lisp roots too. Emacs Lisp is less of an accident and more of an old, old language. Even Lisp family moved on to default to lexical scoping, though it didn't remove dynamic scoping - as in many cases, it's still extremely convenient.
- smaddox 10y agoDynamic scoping can easily be included when desired in the form of a key-value store. I can't think of any advantage to having it built into the language itself. I guess you could argue standardization, but most modern languages provide a standard kvstore.
- tcard 10y agoNow that you mention Quake 3, this article [1] by John Carmack himself on the subject is interesting, and then someone reviewed the source code from Doom 3 [2] where apparently they put some of that in practice. [1] https://web.archive.org/web/20130819160454/http://www.altdevblogaday.com/2012/04/26/functional-programming-in-c/ https://web.archive.org/web/20130819160454/http://www.altdev... [2] http://kotaku.com/5975610/the-exceptional-beauty-of-doom-3s-source-code?post=56177550 http://kotaku.com/5975610/the-exceptional-beauty-of-doom-3s-...
- bitexploder 10y agoAlso, there is a kind "scoping" as well in Emacs. By way of convention. package-foo-var, etc. It reduces the odds of namespace conflicts by a lot.