On Wed, May 30, 2018 at 5:31 AM João Távora <joaotavora@gmail.com> wrote:
> On Tue, May 29, 2018, 22:21 Philipp Stephani <p.stephani2@gmail.com>
wrote:
>> Please don't add global state to json.c. It's a low-level library that
shouldn't rely on global state (and global state should generally be
avoided in libraries). Not having global state was one of my explicit
design goals for json.c
> Well, it's not really "global state" in the sense I believe you're
talking about, because no part of the library is maintaining any state in
global variables -- it's read-only from json.c.
I think the objection to global state (or a global setting, as the case may
be) can be illustrated with the following scenario.
* Consider two independent Elisp packages ‘foo’ and ‘bar’, both of which
want to use the JSON library.
* ‘foo’ wants plists while ‘bar’ wants alists.
* ‘foo’ has a hook. The user adds to that hook a function that invokes
‘bar’.
* Result (after ironing out all bugs related to shared state): Every call
to the JSON library has to be wrapped in a (let ((json-serialize-use-plists
…)) …), which is more cumbersome than just passing an argument to a
function.
Yes, exactly. Any dynamic variable is effectively a hidden parameter. That's much worse than an explicit parameter because you have to remember that it's a parameter and explicitly bind it on every call.
Consider the Java equivalent:
class Json {
public static Object deserialize(String json) { ... } // uses useHashtables
public static bool useHashtables = false;
}
Very few people would consider such an interface good style: there's a subtle interaction between deserialize and useHashtables, and all callers need to be aware of the interaction. But interfaces should be easy to use correctly and hard to use incorrectly, and this interface is easy to use incorrectly and hard to use correctly. BTW, This has nothing to do with Java or ELisp, but is generally true for all (imperative) programming languages: avoid mutable global state, avoid "action at a distance" (seemingly unrelated parts of the code influencing each other). For ELisp, this means: avoid introducing dynamic variables if possible.