> For the entire app? You'd end up with a "god object" that would make the app unmaintainable. OO gives you compartmentalization that you don't get with FP.
Well, not quite; take a look at the Elm architecture [0]. It's basically what Redux gives you, but more explicit.
The idea is, that yes, while you have a god object in the top-most component, child components don't know anything about it; they operate on their piece of state completely independently. This makes UI elements perfectly composable and reusable, since in the end, a UI element is just a pure function and nothing more.
Not to mention other nice side-effects (sorry :)) of pure UI architectures, like time-travelling debugging, sane logging and so on.
> FP is great for problems up to a certain complexity. After that it falls apart.
I disagree completely. FP, and moreover pure FP, is especially well suited for complex problems. Pure functions are testable (if you haven't heard of QuickCheck / generative testing, you've missed out) and as I said above, composable.
If anything, I've never seen a big OO program made out of truly reusable components. Because classes and methods are often impure, before calling a method one must make sure that the correct environment is set up in the right way (if you've ever forgotten calling initSubsystem() before subsytemDoSomething() you know what I mean).
One can rip out a pure function from one codebase and reuse it, as-is, no modification necessary, in another one without any problems. How often does this happen in a big OO project?
> Is "instance" adding an interface to TileMap/HexMap so that either can be passed in as a parameter that requires a RectIterable? Can other interfaces be added that way to TileMap/HexMap?
Yes, and yes. In Java, when you have a class like this:
class A implements B, C {
...
}
in some library, you can't add D to the list of implemented interfaces.
In Haskell, you can:
instance D A where
...
Haskell assumes an "open world" - i.e. everybody can add instances to a data type even after it has been defined already.
I can't give you a complete overview of the differences between ad-hoc and parametric polymorphism, but there are plenty of resources online if you are interested.
> In my editor, can I say something like myTileMap.iterateRect after doing this, or do I need to know that iterateRect exists and remember exactly what it's called?
I can only speak for Haskell here. It's a static language, so things like autocompletion, show type at cursor, jump to definition etc are not a problem. The tooling could be a whole lot better, no doubt, but it's not bad. The REPL helps a lot, too.
[0] https://guide.elm-lang.org/architecture/