Reducing OOP to implementation detail features will yield poor results. The flexibility stems from an improved means of analysis in that types and entities can be identified more easily. By using classes and objects you're retaining flexibility because they can be interchanged; It's easy to create an object that pretends to be a function; it's harder to make a function retain state later. The example is nice; it remo…
Why not make max or pow an object then? If you can model something as a pure function, then it should be a function. You can always add memorization later, if needed. OOP is fundamentally different from FP, objects are not just higher order functions, they are also coalgebras. There is no need to force every peg into a coalgebra hole.
`max` and `pow` can either run eagerly (as functions) or they can run lazily and allow for interesting lazy things. For example, if you put them into a lazy object graph, you could perform optimizing measures.
Check this out:
1/2 * 2/1 == 1
Would you actually calculate each intermediate result of that expression? Or would you just reduce the fraction? Should 1/2 be exectuted and yield 0.5 immediately, or could it be useful to have them hang around some more? FP vs. OOP is the difference of understanding / as "Please divide 1 by 2 now" vs "That IS a fraction; one half".
> There is no need to force every peg into a coalgebra hole.
True, but how awesome would it be if I did that anyway :D
Regarding `max` and `pow` as objects: Yegor Bugayenko argues for a similar thing in his book "Elegant Objects".