| I have heard this said, mainly because some patterns can be made unnecessary with first-class functions and pattern matching. Closures are emulated with explicit objects, and the visitor pattern is equivalent to pattern matching. Something that's pretty interesting, though, is that it's a transform called defunctionalization. There's an article about it [1] that has been shared before on HN. One form of defunctionalization is the well-known transformation of a recursive function into one that uses an explicit stack. The thing is, I don't think defunctionalization (from the equivalent functional form) present in object-oriented languages is strictly worse. Defining things with explicit objects may sometimes be more understandable, and more extensible; for example, the command pattern could be implemented as a closure, but then you can't later add an "undo" method to it later. Here's an example where defunctionalization makes the code more readable, not less. Haskell has a difference list [0] data structure; the purpose of it is that you can concatenate two difference lists in constant time, and then turn it into one long normal linked list in O(n) time. This gives much better performance than concatenating lists directly all the time. It's a lot like a rope, except for lists, not strings, and it's immutable. But the code is somewhat cryptic; it makes use of partial application and stores the tree in terms of partially applied functions. The "Demystifying DList" [0] article I shared shows a defunctionalized form explicitly defined as a tree in concrete data types. To those interested in it, if you're familiar with the syntax of ML-like languages, I'd recommend the papers [2], [3], and [4]. [0]: http://h2.jaguarpaw.co.uk/posts/demystifying-dlist/ [1]: https://blog.sigplan.org/2019/12/30/defunctionalization-ever... [2]: "Defunctionalization at work": https://www.cs.purdue.edu/homes/suresh/502-Fall2008/papers/d... [3]: "Refunctionalization at work": https://www.brics.dk/RS/07/7/BRICS-RS-07-7.pdf [4]: "Continuation-Passing Style, Defunctionalization, Accumulations,
and Associativity": https://www.cs.ox.ac.uk/jeremy.gibbons/publications/continue... |
A good language makes it easy to use both functions-as-values and structured-objects-as-callables, and use whichever representation is appropriate to the situation.