6 ms·
This just reinforces my bias that OOP is what is really harmful. Really, what good reason is there to have data and behavior bound to the same object? I’ve neve
by dimal 3y ago
This just reinforces my bias that OOP is what is really harmful. Really, what good reason is there to have data and behavior bound to the same object? I’ve never seen a good argument for that. It’s just taken as a given. It seems nice and convenient, but that convenience seems to always lead to unexpected complexity like this.
A while ago I was looking for a color manipulation library, and I saw her Color.js, and loved all the features. Then I saw the bullet point, “Readable, object-oriented API”. Nope. I’m not touching that. I chose culori instead. It’s just a collection of functions that transform standardized color data objects. It’s like lodash for colors. It’s been great to work with.
- lioeters 3y agoI agree. Private class fields seem totally unnecessary when you can simply "hide" functions and variables in a local scope and not export/expose it. (Or use symbols as another comment suggested.) I also don't want a library for color manipulation to be using Proxy and other magic tricks, including "this". I prefer plain functions that take any values they need as explicit arguments, and simply return results - without maintaining state, having side effects, pretending to be a plain object, etc.
- simplotek 3y ago> I agree. Private class fields seem totally unnecessary when you can simply "hide" functions and variables in a local scope and not export/expose it. This is not true. Private members are a part of a class interface, while local/internal function/variables are not. They both serve totally different purposes. If you're using private members as a substitution to local/internal members, you're doing it in ways that are fundamentally wrong.
- dimal 3y agoI’m confused by this comment. How are private members part of the class interface? They are internal, not exposed to the outside, so how can they be part of the interface, which by definition is what the class exposes to the outside?
- kfajdsl 3y agoAt least in lower level languages like C or C++, private members are part of the interface since they affect how much memory needs to be allocated for an object.
- otikik 3y agoWell C++ had private, public and “friend” attributes. Classes that were “friends” could see and use their privates. I know it sounds bad. Not my fault
- ActorNightly 3y ago>Really, what good reason is there to have data and behavior bound to the same object? Building in code APIs for libraries.
- simplotek 3y ago> Really, what good reason is there to have data and behavior bound to the same object? Behavior is the interface/messages supported by the object, and data is an implementation detail that should not leak. What's wrong with that? And why are you pinning the blame on a whole paradigm from a problem caused by how a feature was implemented in a language renowned for being fundamentally broken ?
- dimal 3y ago> What's wrong with that? My question is, why is that necessary? Exactly what is the benefit, except for a tiny bit of convenience? Why is that better than functions that work on well-defined types? It adds coupling, and coupling adds complexity, so if I'm adding complexity, I want to know why it's better before I add it. > And why are you pinning the blame on a whole paradigm from a problem caused by how a feature was implemented in a language renowned for being fundamentally broken I think calling the JavaScript/TypeScript of today fundamentally broken is clearly untrue. But anyway, I'm not condemning OOP entirely because of this one feature in one language. I thought my comment made clear that I see this as just another in a long line of complexity I've seen that's caused by this unnecessary coupling of data and behavior. When I think of the OOP paradigm, I really think of Java, which I would call more fundamentally broken than JavaScript. It's improved over the years by pulling in ideas like lambdas that loosen the straightjacket imposed by its broken interpretation of OOP. Half of the revered "design patterns" that we're supposed to learn for OOP are just to work around this coupling when it's getting in the way. Patterns, even if they're repeatable, are complexity. Have you implemented the Visitor Pattern [0] lately? I did it once and I will never do it again. That kind of stuff ties my brain in knots. If you like pointless puzzles, maybe it's fun, but for me it's just more and more complexity. When I just work with data and functions, most things become much simpler. [0] https://en.wikipedia.org/wiki/Visitor_pattern#/media/File:Visitor_design_pattern.svg https://en.wikipedia.org/wiki/Visitor_pattern#/media/File:Vi...
- tomstuart 3y ago> My question is, why is that necessary? Exactly what is the benefit, except for a tiny bit of convenience? Why is that better than functions that work on well-defined types? The benefit is subtype polymorphism via dynamic dispatch. When values flow through the program they carry the implementations of their operations with them, so a caller can operate on a value without knowing how that operation is implemented; a newly-introduced value can bring a new implementation of an existing operation, and existing callers can use that implementation without knowing that it’s new. There are other ways of achieving this, but OOP is a good one.
- mathgladiator 3y agoReally, what good reason is there to have data and behavior bound to the same object? Caches which require specific invalidation logic. A good mental model is the query language for a database. The language provides a frontdoor for all the state, so you can't just poke around and mutate things.
- dimal 3y agoEh. I guess I don't see how `cache.invalidate()` is a drastic improvement over `invalidate(cache)`. And my experience with ORMs has also not been pleasant, although it's been a few years since I've used one. They seem very convenient for 80-90% of use cases, and a nightmare for the rest. And you don't know at what point your query will pass that invisible line into the nightmare zone. You start with something simple and it's very convenient, then as things change and get more complicated, the generated queries become more and more unperformant and confusing.
- mathgladiator 3y agoOnly if you understand the details of when the cache needs to be invalidated. I'm not sure where ORMs entered the picture, but my point is that the database uses the query engine to guard internal caches which are private via the process boundary. OOP is a technique which shouldn't prescribed for everything. I will say Javascript shouldn't have have classes, but I hope to never need to use JS much beyond glue.
- syntheweave 3y agoThings that resemble state machines tend to produce reasonable interfaces when exposed in OOP fashion. The problem is more one of, you don't want everything to be a state machine, and adding the boilerplate tends to overcouple the data. The maximally composable form will tend to extract a little FSM with one variable, while all other relevant data is simply passed into every method.
- pjmlp 3y agoAre you aware that private data hiding is also available in classical imperative languages, functional programming, logical programming?
- dimal 3y agoYes. I am not against data hiding. I love data hiding. My comment was not related to data hiding. It's simply pointing out that this kind of unexpected complexity seems to always come up in OOP in my experience.