Live data from Hacker News

Inheritance was invented as a performance hack (2021)

catern.com

101–110 of 252 posts

Re: Inheritance was invented as a performance hack (2021)

#101
I always thought this was common knowledge. I guess it isn’t.

The only reason inheritance continues to be around is social convention. It’s how programmers are taught to program in school and there is an entire generation of people who cannot imagine programming without it.

Aside from common social practice inheritance is now largely a net negative that has long outlived its usefulness. Yes, I understand people will always argue that without their favorite abstraction everything will be a mess, but we shouldn’t let the most ignorant among us baselessly dictate our success criteria only to satisfy their own inability to exercise a tiny level of organizational capacity.

Re: Inheritance was invented as a performance hack (2021)

#102
post #79

I find that structural typing is the most useful thing and unfortunately few languages support it. I'd like a language where: - If I have a class Foo and interface Bar, I should be easily able to pass a Foo where Bar is required, provided that Foo has all the methods that Bar has (sometimes I don't control Foo and can't add the "implements Bar" in it). - I can declare "class Foo implements Bar", but that only means "…

TypeScript does supports all of these - `C implements I` is not necessary but gives compile errors if not fulfilled.

You can use `o satisfies T` wherever you want to ensure that any object/instance o implements T structurally.

To verify a type implements/extends another type from any third-party context (as your third point), you could use `(null! as T1) satisfies T2;`, though usually you'd find a more idiomatic way depending on the context.

Of course it's all type-level - if you are getting untrusted data you'll need a library for verification. And the immutable story in TS (readonly modifier) is not amazing.

Re: Inheritance was invented as a performance hack (2021)

#103

Earlier quoted context omitted.

"But there's a reason the crowd is moving against inheritance" Yes, in our fad-chasing industry the pendulum has moved in the other direction. Let's wait few years. There is nothing wrong with OOP, inheritance, FP, procedural, declarative or whatever. What is bad is religious dogma overtaking engineering work.

I’m surprised this is considered a controversial take. You can write spaghetti in any language or paradigm. People will go overboard on DRY while ignoring that inheritance is more or less just a mechanism for achieving DRY for methods and fields. FP wizards can easily turn your codebase into a complex organism that is just as “impenetrable” as OOP. But as you say, fads are fads are fads, and OOP was the previous fad…

I have a slightly different take:

I think every new technology or idea is created because it solves some problems, but in the long run, we'll discover that it creates other problems. For example, transpiling javascript, C++ OO, actors, coroutines, docker, microkernels, and so on.

When a new idea appears, we're much more aware of the benefits it brings. But we don't know the flaws yet. So we naively hope there are no flaws - and the new idea is universally good.

But its rare to change something and not have that cause problems. It just always takes awhile for the problems to really show up and spoil the party. I guess you could think of it as the hype cycle - first hype, then disillusionment, then steady state.

Sometimes I play this game with new technology. "In 10 years, people will be complaining about this on hackernews. What do I guess they'll be saying about it?". For rails, people complain about its deep magic. For rust, I think it'll be how hard it is to learn. For docker, that it increases the size of deployments for no reason. And that its basically static linking with more steps.

Calling everything a fad is too cynical for me, because it implies that progress is impossible. But plenty of tools have made my life as a software developer better. I prefer typescript over javascript. I prefer cargo over makefile / autotools / cmake / crying. Preemptive schedulers are better than your whole computer freezing. High level languages beat programming in assembly.

Its just hard to say for sure how history will look back on any particular piece of tech in 20 years time. Fortran lost to C, even though its better in some ways. I think C++ / Java style OO will die a slow death, in favour of data oriented design and interfaces / traits (Go / Rust style). I could be wrong, but thats my bet.

> I think it’s obvious that anyone passing around structs that contain data and functions that act on that data is the same concept as passing around objects.

I hear what you're saying - but there's some important differences about the philosophy of how we conceptualise our programs. OO encourages us to think of nouns that "do" some verb. Using structs and functions (like C and Rust) feels much more freeform to me. Yegge said it better: https://steve-yegge.blogspot.com/2006/03/execution-in-kingdo...

But lets see in 20 years. Maybe OO will be back, but I doubt it. I think if we can learn anything from the history of CS, its that functional programming had basically all the right ideas 40 years ago. Its just taking the rest of us decades to notice.

Re: Inheritance was invented as a performance hack (2021)

#104
post #85
post #73

Earlier quoted context omitted.

To me (as a Java programmer) inheritance is very useful to reuse code and avoid copy paste. There many cases in which decorators or template methods are very useful and in general I find it "natural" in the sense that the concepts of abstraction and specialization can be found in plenty of real world examples (animals, plants, vehicles etc etc). As usual there is no silver bullet, so it's just a tool and like any oth…

As a full stack developer who's current job is mostly Java on the backend - at least for the last 8 yrs: I'm not aware of anything you would lose by switching to interfaces with default implementations over inheritance... And that's the usual argument: use composition over inheritance.

But would switching to interfaces with default implementations fix any of the complaints that people have about inheritance? In my mind, they're pretty much equivalent, so it seems to me that anything you can do with inheritance that people complain about, you could also do with interfaces and complain about it in the same way.

Re: Inheritance was invented as a performance hack (2021)

#105
post #39

Earlier quoted context omitted.

> Literally think about it. How else do you merge two structs if not using inheritance? What? Using multiple inheritence? That's one of the worst ideas I've ever seen in all of computer science. You can't just glue two arbitrary classes together and expect their invariants to somehow hold true. Even if they do, what happens when both classes implement a method or field with the same name? Bugs. You get bugs. I've bee…

>What? Using multiple inheritence? You just threw this in out of nowhere. I didn't mention anything about "multiple" inheritance. Just inheritance which by default people usually mean single inheritance. That being said multiple inheritance is equivalent to single inheritance of 3 objects. The only problem is because two objects are on the same level it's hard to know which property overrides which. With a single cha…

The real major issue with multiple inheritance is that only a few languages (Eiffel, for one) seem to require declaring invariants for each class.

Then multiple inheritance is much cleaner because you can test constructor arguments against the union of these invariants before even hitting a constructor.

Note that I’ve never used it, but it did strike me that this was “the” way to include multiple inheritance in a language. But for some reason (run time performance maybe?) no one else seems to have done it this way.

Re: Inheritance was invented as a performance hack (2021)

#106
post #19

Earlier quoted context omitted.

Parent is correct - if the compiler has the information to devirtualize it becomes direct dispatch regardless of the mechanisms involved at the source level. This is also typically true for JITs.

This is true as long as the compiler actually can de-virtualize the method, that is, that it can prove that the objects it's handling at a particular call site do not override it. Quite often this is not the case, because of the pattern when the programmer is expected to override / implement an abstract method to plug in the desired functionality. The lookup can be fast if there are few classes involved, and their vt…

Even if you call a pure virtual function of an abstract base class, the compiler can devirtualize if it can determine the type anyway due to data flow analysis. There are limitations but with LTO you’d be surprised at how effective the compiler is here. Also in Rust you’re never going through the vtable unless it’s a &dyn Trait and the compiler fails to devirtualize.

Re: Inheritance was invented as a performance hack (2021)

#107
post #36

Earlier quoted context omitted.

Yeah ya... everyone likes to go on and on about how inheritance is the root of all evil and if you just don't use it, everything will be fine. Sorry, it won't be fine. Your software will still be a mess unless it is small and written three times by the same person who knows what they are doing. The bottom line is, no one ever really used inheritance that much anyway (other than smart people trying to outsmart themsel…

> The bottom line is, no one ever really used inheritance that much anyway If you think that, you have no idea how much horrible code is out there. Especially in enterprise land, where deadlines are set by people who get paid by the hour. I once worked on a java project which had a method - call a method - call a method - call a method and so on. Usually, the calls were via some abstract interface with a single imple…

> Usually, the calls were via some abstract interface with a single implementor

What's described here is over-generic code, instead of KISS and just keeping an eye on extensibility instead of generalizing ahead of time. This can happen in any paradigm.

Re: Inheritance was invented as a performance hack (2021)

#108
post #83

Earlier quoted context omitted.

Java wasn't the first to do that Objective-C (10? years before) had interfaces. Even C++ has that with multiple inheritance - some parents can just be interfaces. As to whether Smalltalk needs interfaces see https://stackoverflow.com/a/7979852/151019 and https://www.jot.fm/issues/issue_2002_05/article1/

Objective-C and Smalltalk were always niche languages, at least by comparison to Java and C#, and I think Smalltalk fans underestimate the value of many things. C++ does not (or at least did not at the time) have a concept of interfaces. There was a pattern in some development communities for defining interfaces by writing classes that followed particular rules, but no first-class support for them in the language.

> C++ does not (or at least did not at the time) have a concept of interfaces. There was a pattern in some development communities for defining interfaces by writing classes that followed particular rules, but no first-class support for them in the language.

Your distinction between "first class support for interfaces" and "C++ support for interfaces" looks like an artificial one to me.

Other than not requiring the keyword "interface", what is it about the C++ way of creating an interface that makes it not "first class support"?

Re: Inheritance was invented as a performance hack (2021)

#109
post #10

I'm not sold the evidence is there to show inheritance is a good idea - it basically says that constructors, data storage and interfaces need to be intertwined. That isn't a very powerful abstraction, because they don't need to be and there isn't an obvious advantage from doing so over picking up the concepts separately as required. And inheritance naturally suggests grouping interfaces into a tree in the way that se…

I'm not sold on the evidence of much in the way of programming language features from the "object oriented" era.

They were pushed by cultish types with little evidence. There was this assertion that all these things were wonderful and would reduce effort and therefore they must be good and we all must use them. We got object oriented everything including object oriented CPUs, object oriented relational databases, object oriented "xtUML". If you weren't object oriented you were a pile of garbage in those days.

For all that, I don't know if there was ever any good evidence at all that any of it worked. It was like the entire industry all fell for snakeoil salesmen and are collectively too embarrassed about it to have much introspection or talk about it. Not that it was the last time the industry has fallen for snakeoil...

Re: Inheritance was invented as a performance hack (2021)

#110
post #10

I'm not sold the evidence is there to show inheritance is a good idea - it basically says that constructors, data storage and interfaces need to be intertwined. That isn't a very powerful abstraction, because they don't need to be and there isn't an obvious advantage from doing so over picking up the concepts separately as required. And inheritance naturally suggests grouping interfaces into a tree in the way that se…

Like any map, the inheritance pattern is bad, except when it works. It’s a strategic capability to be able to guess well which is which in given context.

My first foray into serious programming was by way of Django, which made a choice of representing content structure as classes in the codebase. It underwent the usual evolution of supporting inheritance, then mixins, etc. Today I’d probably have mixed feelings about conflating software architecture with subject domain so blatantly: of course it could never represent the fundamental truth. However, I also know that 1) fundamental truth is not losslessly representable anyway (the map cannot be the territory), 2) the only software that is perfectly isolated from imperfections of real world is software that is useless, and 3) Django was easy to understand, easy to build with, and effectively fit the purpose.

Any map (requirement, spec, abstraction, pattern) is both a blessing that allows software to be useful over longer time, and a curse that leads to its obsolescence. A good one is better at the former than the latter.

Post reply on HN