That just rotates the problem 90 degrees - now adding new functions is easy, but adding new data is hard (requires rewriting every use site).

I really recommmend giving this a read: https://craftinginterpreters.com/representing-code.html#the-...

You should read the linked article to the end (or maybe you did but missed it)

The problem as explained in what you linked:

> an object-oriented language wants you to orient your code along the rows of types. A functional language instead encourages you to lump each column’s worth of code together into a function.

The point was that the final protocol implementation in Clojure solves this. There is no more lumping. The whole thing is freeform. You can extend an existing record (say it's coming from a library or somewhere outside your control) and add interfaces. Or you can make a new record and implement all the existing interfaces