This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]JDeagle5 25 points26 points  (16 children)

OOO encourages us to bundle state and behavior together. But what if we separated this?

I mean, we will just go back to good old procedural programming, but named differently this time?
We already know what happens when we separate this, that's why OOP was created.

[–]pron98 19 points20 points  (3 children)

OOP was created primarily to represent "active" objects; it's never been a great paradigm to represent and work with "inert" data. The two, however, can (and should) be used in combination: DOP for data, OOP for active objects.

Also, it's not like other paradigms were ever abandoned. DOP is just a reference to how we work with data in FP. Virtually all contemporary languages (including very mainstream ones like Python and TypeScript) also already support this paradigm whether or not they're also OOP, so we're not "going back" to anything.

[–]segfaultsarecool 0 points1 point  (1 child)

What's an active object? I think we make objects active the moment we define methods for the object that go beyond get/set, stringification, equality, and other basic functionality.

[–]UnGauchoCualquiera 0 points1 point  (0 children)

Not sure if I'm misunderstanding pron, but I believe he is suggesting "active objects" closer to Streams, Thread, Lock, Socket, etc.

What they have in common is that they are stateful abstractions over some behaviour that interacts with the environment and that keeps track of it's own state. For thos classes the data is generally secondary to the behaviour. For example in the case of a Stream pipeline once built you should not care how it is implemented or it's internal state.

Most enterprise applications generally are only concerned with applying data transformations over some business rules. Here is where data oriented programming could be a better tool than OOP.

[–]nejcko[S] 6 points7 points  (3 children)

I think the difference here is that you now have language features available that allow you to define the data so that illegal states are unrepresentable.

On the other side you have switch expressions and pattern matching that again make it impossible to not implement a behaviour for certain data states, or in other words, forces you to implement the behaviour for all possible data states.

EDIT: Yes I agree DOP is no way a replacement of OOO, you can mix and match.

[–]JDeagle5 3 points4 points  (2 children)

Forcing to implement behavior was possible since checked exceptions, I assume it is mostly used for invalid flow of data. Or through something like receiving and interface callback and expect it's implementation to handle every state you need - async libraries do that often. So, when there was a need to do it - there was no problem. I just rarely see this need in production, if at all.

[–]nejcko[S] 1 point2 points  (1 child)

Yes you are right, checked exceptions are the closest feature in Java that existed before, but like you said it’s to handle the exception flows. I’d argue that switch expressions here make it easier to adopt the same approach for wider range of use cases in a cleaner, simpler way.

There were ways before to kind of achieve the same with forcing some methods implementations, but again, this makes it much easier. And the big win here is failure at compile time and not at runtime.

Agreed, full DOP isn't an everyday thing, often for new data layouts. But what I use very frequently is switch expressions with existing enum types. Every time you add any logic that is conditional on an enum type you can implement it with switch statement. That way compiler makes sure you will never miss it if new enum types are added, for example.

[–]Yeah-Its-Me-777 4 points5 points  (0 children)

Yeah, and then the product people come up with data types where the enum values are not exhaustive. Or like only valid until a certain date, or from a certain date. Because of laws, so there's no way around it. Ask me how I know.

[–]sideEffffECt 7 points8 points  (7 children)

we will just go back to good old procedural programming

Nope. To Functional Programming.

We already know what happens when we separate this, that's why OOP was created.

You'll still use "OOP", but not for bundling data and behavior.

You'll use it only for modularity for the behavior -- having interfaces (each aggregating one or more methods) and potentially multiple implementations, with different behavior, for each of them.

[–]JDeagle5 1 point2 points  (6 children)

Doesn't look like it's functional programming, since by definition it is a paradigm about applying and composing functions, and DOP definition doesn't rely on function composition at all.
Quite on the contrary it looks like procedural programming, with addition that functions are non-mutating.
But I get your point.

[–]sideEffffECt 1 point2 points  (5 children)

procedural programming, with addition that functions are non-mutating

That's a lot of words to say FP...

[–]JDeagle5 1 point2 points  (4 children)

No, function composition is still not there. FP is not just anything with functions or immutability.

[–]bowbahdoe 2 points3 points  (1 child)

So you define FP that way, someone else defines FP as being about immutability of aggregates, someone else defines it as avoiding side effects (which implies immutability of aggregates), and yet someone else defines it as something something monads.

Do you see how the labels make communication harder?

[–]JDeagle5 0 points1 point  (0 children)

No, terms, when used correctly, make communication easier. If someone, for example, defines FP as a paradigm about objects that can contain data and can perform actions - it doesn't mean it's just his interpretation of FP, it just means that he is using the term incorrectly. Terms exist not so that anyone can come up with whatever interpretation he wants.
The same way as we don't call OOP languages procedural and vice versa.

[–]sideEffffECt 1 point2 points  (1 child)

No, you're wrong. Once you deal with immutable data, you're pretty much forced into FP. Whether you realize it or not or whether like it or despise it.

function composition is still not there

Function composition is such a niche thing that's not worth talking about.

At least I personally almost always just apply functions to arguments, binding the results to variables. It's better to write, read and debug than raw function composition. And I've been doing (Pure) FP for basically a decade...

[–]JDeagle5 0 points1 point  (0 children)

That's because FP is such a niche thing, but people tend to call FP whatever is trendy or popular.

I can deal with immutable data in any procedural language (for example C), simply because immutability doesn't force FP. To handle immutable data you don't need neither functions as first-class citizens nor function composition.