I mean, I understand that classes which are open to extension with new methods is useful, and the right way to do OOP and all.
If it was CLOS with multiple dispatch, it would be easier to swallow. Because it would look like:
(to-json { hello: "world" })
;; error: no such function!
Then load the module, and you have a generic to-json function now, with a method specialized to handle the dictionary object and all. (I still wouldn't want to be doing this if it's supposed to be a language built-in).
I regard the ability to add new methods to a class as good, but with a valid use case, like extending some third party piece with new methods in your own application. And the fact of not having to declare methods in a class definition, which is cumbersome. Just write a new method in that class's file, at the bottom, and there it is.
I ideally don't want that third-party piece itself to be divided into three pieces that I have to separately load to get all of the methods. Or worse, pieces from separate third parties that add methods to each other.
I copied a thing or two from Ruby in TXR Lisp. The object system as a derived hook, and that was inspired by something in Ruby:
1> (defstruct foo ()
(:function derived (super sub) (prinl `derived @super @sub`)))
#<struct-type foo>
2> (defstruct bar foo)
"derived #<struct-type foo> #<struct-type bar>"
#<struct-type bar>
3> (defstruct xyzzy bar)
"derived #<struct-type bar> #<struct-type xyzzy>"
#<struct-type xyzzy>
The derived hook is inherited (like any other static slot), so it fires in bar also. The function can distinguish which class is being derived by the super argument.