Live data from Hacker News

Premature Abstraction

arendjr.nl

71–80 of 116 posts

Re: Premature Abstraction

#71

Earlier quoted context omitted.

OO code for domain modeling might be, to date, the single greatest source of disillusionment in my career. There are absolutely use cases where it works very well. GUI toolkits come to mind. But for general line-of-business domain modeling, I keep noticing two big mismatches between the OO paradigm and the problem at hand. First and foremost, allowing subtyping into your business domain model is a trap. The problem i…

But, in a way, OO modeling and design was invented to solve the mess that "banging out" procedural code created in the first place. You have to model your business domain in software one way or another anyway. Why should it be bad to try to be more methodical about it using OO methods? We do it with relational databases all the time where tables are pretty similar to objects.

I actually have nothing against objects and methods, but that’s a very limited subset of OO. I prefer to use algebraic data types for domain modeling, and giving them methods is totally fine too. But I do prefer them to be immutable in most cases, which is also quite counterintuitive from an OO perspective.

Re: Premature Abstraction

#72
post #67

Gall’s law: “A complex system that works is invariably found to have evolved from a simple system that worked. The inverse proposition also appears to be true: A complex system designed from scratch never works and cannot be made to work. You have to start over, beginning with a working simple system.” Your theory of premature architecture reinforces Gall’s law. This is from the book Systemantics: How systems work an…

I like this one, thanks!

Re: Premature Abstraction

#73
post #37

I know HN doesn't like quibbles about site design, but I'm literally having difficulty reading the article due to the font size being forced to be at least 1.3vw. Zooming out doesn't decrease the font size! Downvote if this is boring, but (a) I've never seen a site that did that before, so it's just notable from a "Daily WTF" kind of perspective, and (b) just in case the submitter is on HN: it's actually preventing m…

That’s useful feedback, thanks!

Re: Premature Abstraction

#74
post #25

My general take (and w/ the caveat that every system is different) is as follows: - procedural code to enter into the system (and perhaps that's all you need) - object oriented code for domain modeling - functional code for data structure transformations & some light custom control flow implementation (but not too much) I like the imperative shell, functional core pattern quite a bit, and focusing on data structures…

If you think OOP is particularly well-suited to domain modelling, you should try the FP approach to domain modelling. You will never be able to unsee the complexity inherent to OOP.

You can try the FP approach today in most languages that are not even FP:

* Rust * Kotlin * Dart * Java

Yep, even Java. Check this out: https://blog.jdriven.com/2021/10/sealed-classes/

Re: Premature Abstraction

#75

Earlier quoted context omitted.

Oof. I know this is an example but all of those look like they would be better served as interfaces.

Yes. Did I mention there are interfaces too, with almost the same name, but it’s only used for the base classes. (Yes, there is only one implementation of all interfaces).

Having lots of interfaces for common things is not a bad thing. See how Rust traits work... even basic structs you create will probably implement lots of basic traits (some of which can be done automatically, thankfully) like `Display`, `Default`, several `From` or `Into` impls, `Clone`, `Copy` if your type is "light", `AsRef`, `Send` and many more!

This makes code much more reusable as so many functions are written based on those basic traits alone.

Of course, finding the right basic types is really hard and your company seems to have done that badly, but in principle, having some basic types to model very common "things" is a necessary thing.

Re: Premature Abstraction

#76

Though I agree about the point about not creating objects/instances where a pure function will get the job done, I disagree with the general stance against OOP. I think OOP is absolutely essential to simplicity. FP tends to lead to too many indirections with data traversing too many conceptual boundaries. FP (if used dogmatically) tends to encourage low cohesion. I want high cohesion and loose coupling. Some degree o…

Thanks! I would just like to clarify I’m actually not opposed to OOP at all, and at several points I tell people it’s fine to go in that direction for the problems where you need it. I do try to warn against it as a go-to solution before you’ve understood what are the problems that actually need fixing, which it sounds like we’re pretty aligned on.

Indeed if you pass by value/use immutability where feasible, you already avoid most of the issues I’m warning against, so it sounds like you found a sensible way to apply it while avoiding the pitfalls.

> If I have to give a taxi driver a jerrycan full of petrol, that's the definition of a leaky abstraction... Possibly literally in this case.

:D

Re: Premature Abstraction

#77
post #4

Although I agree with the recommendations, I cringe at the definition of abstraction. In a sane world, abstraction doesn't mean defining classes so much as it means identifying important unifying concepts. DRYing your code by moving a method to a common base class isn't abstraction in any important way, it's just adding a level of indirection. In fact, I'd argue that this example is the opposite of abstraction: it's…

I had to mull over this for a while, but I think I agree - abstractions at a conceptual level are much more powerful than object-level "compression".

Concepts/domain model/whatever tend to change over time though (at least in the business world, maybe not so much tooling etc). I think that's another source of leaky abstractions - things that conceptually made sense together at one point grow apart, and now you're left with common code that is deeply integrated but doesn't quite fit any more.

Re: Premature Abstraction

#78
post #15

Earlier quoted context omitted.

This is a strong argument against inheritance, but that isn't everything about OOP. Just one well supported advanced abstraction (That I would also argue should be rarely used.) I would argue that just having strong type system and bundling methods with data gets you the vast majority of the usefulness of OOP. Liskov, Open/Closed, Message Passing, and other theoretical abstractions be damned. EDIT - Where are the goo…

Agree 100%: static typing (for code completion) + method/data bundling is the major win in OO, and it rarely gets talked about for whatever reason. It's unfortunate that inheritance became such a major focus of practical OO languages. Would love to see a composition-first OO language. Might have its own problems, but would at least be interesting.

Typescript and it's structural typing my be what you're looking for.

Re: Premature Abstraction

#79

My general take (and w/ the caveat that every system is different) is as follows: - procedural code to enter into the system (and perhaps that's all you need) - object oriented code for domain modeling - functional code for data structure transformations & some light custom control flow implementation (but not too much) I like the imperative shell, functional core pattern quite a bit, and focusing on data structures…

> but the idea of gathering a data structure and the operations on that data structure in a single place, with data hiding, is a good one, particularly for domain modeling.

One can do this in a module without OOP.

The idea of mixing data and behaviour/state (OOP) instead of keeping data structure and functions transforming those (functional) is IMO the biggest mistake of OOP, together with using inheritance.

I believe making part of the program data instead of code (and thus, empty of bugs) is such a big advantage. Already lisp was talking about it. Mixing data with behaviour, without a clear delimitation creates a tight-coupled implementation full of implicit assumptions. Outside the class things are clean, but inside they ossify, and grow in complexity. Pure functions with data in data out are such a big improvement in clarity when possible.

Re: Premature Abstraction

#80

My general take (and w/ the caveat that every system is different) is as follows: - procedural code to enter into the system (and perhaps that's all you need) - object oriented code for domain modeling - functional code for data structure transformations & some light custom control flow implementation (but not too much) I like the imperative shell, functional core pattern quite a bit, and focusing on data structures…

James Gosling, who I'd consider the father of one of the most popular OO languages gave this advice:

"You should avoid implementation inheritance whenever possible"

My early days of Java where largely building unmaintainable inheritance trees into my code and then regretting it. This quote gave me comfort that it wasn't really that good an idea.

Decent discussion on inheritance Vs composition also found here: https://en.m.wikipedia.org/wiki/Composition_over_inheritance

Post reply on HN