The Devil's Advocate

I think this question deserves a devil's advocate (but of course I'm biased). I think @KarlBielefeldt is making very good points and I'd like to address them. First I want to say that his points are great.

Since he mentioned this isn't a good pattern even in functional programming, I'll consider JavaScript and/or Clojure in my replies. One extremely important similarity between these two languages is they're dynamically typed. I'd be more agreeable with his points if I were implementing this in a statically typed language like Java or Haskell. But, I'm going to consider the alternative to the "Everything is a Map" pattern to be a traditional OOP design in JavaScript and not in a statically typed language (I hope I'm not setting up a strawman argument by doing this, please let me know).

For example, try to answer the following questions about each subprocess function: Which fields of state does it require?

Which fields does it modify?

Which fields are unchanged?

In a dynamically typed language, how would you normally answer these questions? A function's first parameter may be named foo , but what is that? An array? An object? An object of arrays of objects? How do you find out? The only way I know of is to

read the documentation look at the function body look at the tests guess and run the program to see if it works.

I don't think the "Everything is a Map" pattern makes any difference here. These are still the only ways I know of to answer these questions.

Also keep in mind that in JavaScript and most imperative programming languages, any function can require, modify and ignore any state it can access and the signature makes no difference: The function/method could do something with global state or with a singleton. Signatures often lie.

I'm not trying to set up a false dichotomy between "Everything is a Map" and poorly designed OO code. I'm just trying to point out that having signatures that take in less/more fine/coarse grained parameters doesn't guarantee you know how to isolate, setup and call a function.

But, if you would allow me to use that false dichotomy: Compared to writing JavaScript in the traditional OOP way, "Everything is a Map" seems better. In the traditional OOP way, the function may require, modify or ignore state that you pass in or state that you don't pass in. With this "Everything is a Map" pattern, you only require, modify or ignore state that you pass in.

Can you safely rearrange the order of the functions?

In my code, yes. See my second comment to @Evicatos's answer. Perhaps this is only because I'm making a game though, I can't say. In a game that's updating 60x a second, it doesn't really matter if dead guys drop loot then good guys pick up loot or vice versa. Each function still does exactly what it's supposed to do regardless of the order they're run. The same data just gets fed into them at a different update calls if you swap the order. If you have good guys pick up loot then dead guys drop loot , the good guys will pick up the loot in the next update and it's no big deal. A human won't be able to notice the difference.

At least this has been my general experience. I feel really vulnerable admitting this publicly. Maybe considering this to be okay is a very, very bad thing to do. Let me know if I've made some terrible mistake here. But, if I have, it's extremely easy to rearrange the functions so the order is dead guys drop loot then good guys pick up loot again. It will take less time than the time it took to write this paragraph :P

Maybe you think "dead guys should drop loot first. It would be better if your code enforced that order". But, why should enemies have to drop loot before you can pick loot up? To me that doesn't make sense. Maybe the loot was dropped 100 updates ago. It's not necessary to check if an arbitrary bad guy has to pick up loot that's already on the ground. That's why I think the order of these operations is completely arbitrary.

It's natural to write decoupled steps with this pattern, but it's difficult to notice your coupled steps in traditional OOP. If I were writing traditional OOP, the natural, naive way of thinking is to make the dead guys drop loot return a Loot object that I have to pass into the good guys pick up loot . I wouldn't be able to reorder those operations since the first returns the input of second.

In an object oriented language, the pattern makes even less sense, because tracking state is what objects do.

Objects have state and it's idiomatic to mutate the state making its history just disappear... unless you manually write code to keep track of it. In what way is tracking state "what they do"?

Also, the benefits of immutability go way down the larger your immutable objects get.

Right, as I said, "It's rare that any of my functions are pure". They always only operate on their parameters, but they mutate their parameters. This is a compromise I felt I had to make when applying this pattern to JavaScript.