> If you have different players who use different hit strategies how do you handle that with just a pure function? Lots of if statements in the function? Passing in lambdas in every case you call the function?
I'll list a few strategies I've seen in different contexts:
1) Clojure has "protocols", which is a strategy of doing polymorphism where the verb is charge instead of the noun.
2) Rust has trait objects, where you have to implement the polymorphic behavior you want for a separate player type but the data is separate from the behavior and not interlinked or owned by the class. You can implement the behavior in the scope of the module where it is used.
3) You already mentioned this, but lambdas in Javascript or functors in C++ satisfy a lot of specialization requirements.
All 3 of these approaches are different ways of approaching the problem of different behavior on the same data. The key thing with them is that it allows domain specific behavior to be decoupled from an owning object. There may be reasons that OO is more suited to a problem (as you mention), but I tend to agree with the author's post around the dogma of using OO everywhere.
In the article, the author also mentions a quote around encapsulation
> Encapsulation is an object-oriented programming concept that binds together the data and functions that manipulate the data, and that keeps both safe from outside interference and misuse.
In my opinion, this view of binding the data and behavior together stems from an idea that data is scary and can be changed at any time. In an immutable, pass-by-value, functional world, those getters and setters and indirection is just another thing in my way from composing the data together with collections tools I am very familiar with. I think it was Neal Ford who said that "OO encapsulates moving parts, whereas functional programming removes moving parts." I think that's very appropriate in this context. In a data-first view, you model what properties and data shapes you care about in your records, and then you create little functions that connect those things together; in OO, you create the links first through methods (even if those have interfaces), and you're stuck with those connections anywhere you want to pass the object.