Live data from Hacker News

Fifty Shades of OOP

lesleylai.info

81–90 of 119 posts

Re: Fifty Shades of OOP

#81

> OOP-bashing seems fashionable nowadays. Yes, and for just cause. OOP was invented in Simula76 (1976) and popularized in C++ (1982). OOP solved a very real problem of allowing applications to logically scale in memory constrained systems by allowing logic to grow independently and yet retain access to memory already claimed by a parent structure. Amazing. Now fast forward and you get languages like Java, Go, and Jav…

I don't follow. Java is mega object oriented. Can you even write a standalone function? I get the impression you are focusing on a single aspect of OOP that has gone out of fashion without realizing by and large every application developer is doing OO development 99% of the time.

Re: Fifty Shades of OOP

#82

Earlier quoted context omitted.

> why most of us use Java at all Java was the first popular language to push static analysis for correctness. It was the "if it compiles, it runs" language of its day, what meant that managers could hire a couple of bad developers by mistake and it wouldn't destroy the entire team's productivity. I'm not sure that position lasted for even 5 years. But it had a very unique and relevant value proposition at the time.

OCaml would like to have a word with you. In 2005 it already had better static analysis and correctness on object oriented stuff than what Java struggles to approach today. But Java has better marketing.

Java is from 1996...

It got really useful by 1998.

Re: Fifty Shades of OOP

#84
post #69

Earlier quoted context omitted.

I think the biggest mistake was to teach inheritance as a main feature of OOP. I have done some stuff with inheritance but it was very specialized and it would have been fine without inheritance.

But OOP needs something to distinguish it from the rest, otherwise it's just P. Do people honestly think other languages don't do whatever definition OOP has today? Encapsulation & polymorphism? Message-passing & late-binding? Inheritance is the one thing that the other languages took a look at and said 'nope' to. (Also, the OOP texts say to prefer composition anyway)

IME with this sort of thread there is a huge correlation between praising OOP and believing that encapsulation is an identifying feature of OOP. Also polymorphism to a much lesser extent, but the other two almost none.

It is very difficult to tell whether this is a definitional problem - people believe any kind of encapsulation is OOP - or if some people can't wrap their heads around how to do encapsulation without message passing and the rest.

Re: Fifty Shades of OOP

#85
post #29
post #8

Earlier quoted context omitted.

> Basically your objects are data-only, so there's no benefit. This makes me wonder why most of us use Java at all. In your typical web app project, classes just feel like either: 1) Data structures. This I suspect is a result of ORM's not really being ORM's but actually "Structural Relational Mappers". - or - 2) Namespaces to dump functions. These are your run-of-the-mill "utils" classes or "service" classes, etc. T…

Service classes are the thing I hate most. They’re just namespaces for functions. They’re a product of Java not being able to have top level functions.

They're just namespaces for functions, and... why is that so bad? Of all the reasons I hate Java, this isn't one of them, it's whatever.

Re: Fifty Shades of OOP

#86
post #40
post #5

My OO projects were usually in Java with a DB. They all ran afoul of what Martin Fowler calls the Anemic Domain Model. Basically your objects are data-only, so there's no benefit. In addition Spring injection became ubiquitous, and further killed objects with behavior. The only project using a DB and had objects with behavior was an old one that happened to use TopLink as an OR mapping.

Why did you create an anemic domain model? Java has had "data carriers" in the form of records for a while now. Immutable(ish), low boilerblate, convenient. record User(String name){} Records are great when doing more "data oriented programming".

That's not object oriented though

Re: Fifty Shades of OOP

#87
I used "Open Recursion" in many large (ObjectPascal / C++) projects. With simple interfaces, a large project becomes a collection of smaller components. I noticed many programmers do not understand it. Pure OOP languages (like Smalltalk or Ruby or Scala) are the best languages to understand how it could work. They usually have closures where other languages would have "patterns".

The problem is that the components are often connected to different interfaces/graphs. Components can never be fully separated due to debug, visualization and storage requirements.

In non-OOP systems the interfaces are closed or absent, so you get huge debug, visualization and storage functions that do everything. On addition to the other functionality. And these functions need to be updated for each different type of data. The complexity moves to a different part. But most importantly, any new type requires changes to many functions. This affects a team and well tested code. If your product is used by different companies with different requirements (different data types), your functions become overly complex.

Re: Fifty Shades of OOP

#88
post #8

Earlier quoted context omitted.

> Basically your objects are data-only, so there's no benefit. This makes me wonder why most of us use Java at all. In your typical web app project, classes just feel like either: 1) Data structures. This I suspect is a result of ORM's not really being ORM's but actually "Structural Relational Mappers". - or - 2) Namespaces to dump functions. These are your run-of-the-mill "utils" classes or "service" classes, etc. T…

You are so ready : https://fsharpforfunandprofit.com/rop/ The separation of functions and records..

I've read his book "Domain Modeling Made Functional" without much prior knowledge of F#. He provides some compelling examples and some of it ended up inspiring how I write OO code. F# seems cool but it felt like it was close to being extinct.

Re: Fifty Shades of OOP

#89

Earlier quoted context omitted.

OCaml would like to have a word with you. In 2005 it already had better static analysis and correctness on object oriented stuff than what Java struggles to approach today. But Java has better marketing.

Java is from 1996... It got really useful by 1998.

OCaml is also from 1996. And I say 2005 because that's when I started using it, not when it started being useful.

By that time it supported parametric generics, multiple inheritance, named parameters, optionals instead of nulls everywhere, compile to machine code and quite a few extra things that I couldn't understand at the time.

Re: Fifty Shades of OOP

#90
post #63
post #59

Earlier quoted context omitted.

> I don't see how it could be expressed in a different way without loosing that clarity. What value does the inheritance provide here? Can't you just use a flat interface per usecase without inheritance and it will work simpler with less mental overhead keeping the hierarchy in mind? Explicitly your graphic library sounds should be fine to have the interface DisplayObject which you can then add default implementation…

That would be way, way more verbose for everything. Every display object has a x y width and height for example. And there is basic validating for every object. Now a validate method can be conposited. But variables? Also the validating, there is some base validating every object share (called wih super) and the specific validating (or rendering) is done down in the subclasses. And even for simple things, you can com…

To avoid splitting the discussion by responding directly to your comment above, since I have thoughts about this one as well: I've written Rust professionally since 2019, which doesn't have inheritance, so I don't use it at all. I guess my point is that I don't miss having inheritance as a tool in my everyday coding, and I actively prefer not having it available in Rust.

In terms of what you're saying here, the extra verbosity is not really something that either bothers me or is impossible to work around in the context of Rust at least. The standard library in Rust has a trait called `Deref` that lets you automatically delegate method calls without needing to specify the target (which is more than sufficient unless you're trying to emulate multiple inheritance, and I consider not providing support for anything like that a feature rather than a shortcoming).

If I were extremely bothered by the need do do `a.po.x` in the example you give, I'd be able to write code like this:

    struct Point {
        x: i32,
        y: i32,
    }

    struct ThingWithPoint {
        po: Point,
    }

    impl Deref for ThingWithPoint {
        type Target = Point;

        fn deref(&self) -> &Self::Target {
            &self.po
        }
    }

    fn something(a: &mut ThingWithPoint, b: ThingWithPoint) {
        a.x = b.x * 2;
    }
Does implementing `Deref` require a bit more code than saying something like `ThingWithPoint: Point` as part of the type definition? Yes (although arguably that has as much to do with how Rust defines methods as part of `impl` blocks outside of the type definition, so defining a method that isn't part of a trait would still be a slightly more verbose, and it's not really something that I particularly have an issue with). Do I find that I'm unhappy with needing to be explicit about this sort of thing rather than having the language provide an extremely terse syntax for inheritance? Absolutely not; the extra syntax convenience is just that, a convenience, and in practice I find it's just as likely to make things more confusing if used too often than it is to make things easier to understand. More to the point, there's absolutely no reason that makes sense to me why the convenience of syntax needs to be coupled with a feature that actually changes the semantics of the type where I want that convenience; as comment I originally replied to stated, inheritance tries to address two very different concerns, and I feel pretty strongly that ends up being more trouble than it's worth compared to just having language features that address them separately.
Post reply on HN