> So instead of doing objects, you're doing closures that act like objects?
No, I'm using using as-plain-as-possible data structures for my state, that I pass to functions that operate on it and return new state. Simple, composable, easy to test, easy to pass the state data elsewhere, serialize it or whatever else I might want to do. I'm not arguing against using classes or objects, but often its unnecessary and hiding mutable state in an implicit "this" variable is, in my opinion, something that often gets in the way of simplicity, as it often tends to imply mutable objects when in my opinion mutable data should be a careful decision rather than the default. Not necessarily of course, but even when you're operating on a constant "this", I feel that hiding the data that its acting on internally is still often not the right choice, especially if the object itself isn't constant/immutable: then its a coeffect instead of an effect, and if you're using truly immutable objects, then its really just a minor syntax difference to write obj.foo(bar) instead of obj(foo, bar). Object systems still carry around a whole bunch of other functionality that you may not want or need, but by using objects, a reader can't know if you are or not without reading the code or documentation. If its data and functions, it isolates the places things can happen somewhat. Classes and objects have their place, but I feel they shouldn't always be the default choice, just because.
That's my take at least, and a big reason I switched from Python and Java to Clojure, but to each their own :)
Fair enough. I agree with you that: "Classes and objects have their place, but I feel they shouldn't always be the default choice, just because."
Often the best things to do in an OOP language is to remember that you don't have to encapsulate everything, and sometimes it's just about bundling data/state.
I may have highlighted the wrong point that I was responding to. I was making a point about the behavioral equivalence of objects and closures in response to this:
There is nothing that you can do with an object that you can’t do with a closure, and the closure version will be 1/10th the size and have 1/10th the semantic programming language elements. That is why you see ‘object-hating’ all over the industry. It hasn’t lived up to its promise.
If you're using a closure where it would have made sense to use an object, it's likely that the closure has the same problems to solve with encapsulation, reasoning about hidden state, etc. that make many languages' object related syntax complex, but instead of dedicated object syntax sugar you're solving it with dedicated closure syntax sugar.
I agree with you. The only point in favour of using a closure that I want to point out (you already pointed out a big point in favour of objects: the dedicated and streamlined syntax) is that its a more a la carte way of doing objects: you choose how deep you want to go.
Of course in reality its not that bad because you can also use classes as much or little as you want and can use them simply for single dispatch, or namespacing, if you wish.
I do find that in practice syntax and features matter because they push you to think in a certain way and it can be hard to break away from that. For example, I write a lot of Clojure and really like functional languages, but when I use Java, Python or even C++, its all too easy to slip into the OOP mindset even when I set out to just "do functional" in those languages. Maybe that's my failing and its certainly not OOP's fault, but I think in practice (at least from observation) it seems most people are like this.
But yeah, I don't actually disagree with you on what you said.
No, I'm using using as-plain-as-possible data structures for my state, that I pass to functions that operate on it and return new state. Simple, composable, easy to test, easy to pass the state data elsewhere, serialize it or whatever else I might want to do. I'm not arguing against using classes or objects, but often its unnecessary and hiding mutable state in an implicit "this" variable is, in my opinion, something that often gets in the way of simplicity, as it often tends to imply mutable objects when in my opinion mutable data should be a careful decision rather than the default. Not necessarily of course, but even when you're operating on a constant "this", I feel that hiding the data that its acting on internally is still often not the right choice, especially if the object itself isn't constant/immutable: then its a coeffect instead of an effect, and if you're using truly immutable objects, then its really just a minor syntax difference to write obj.foo(bar) instead of obj(foo, bar). Object systems still carry around a whole bunch of other functionality that you may not want or need, but by using objects, a reader can't know if you are or not without reading the code or documentation. If its data and functions, it isolates the places things can happen somewhat. Classes and objects have their place, but I feel they shouldn't always be the default choice, just because.
That's my take at least, and a big reason I switched from Python and Java to Clojure, but to each their own :)