Live data from Hacker News

Inheritance was invented as a performance hack

catern.com

241–250 of 268 posts

Re: Inheritance was invented as a performance hack

#241
post #240
post #224

Earlier quoted context omitted.

In Java it isn't but this is specific to Java (and clones of Java like C#). This is because Java has single-inheritance enforcement for classes. C++ for example has multiple inheritance. So the way you do an interface is you just write an abstract class, then extend it to implement it.

In my experience, whether you use an abstract class or an interface class as your reference depends very much on the problem you are trying to solve - specifically, is there common code shared across all implementations?

A C++ pure abstract class is equivalent to a Java interface.

Re: Inheritance was invented as a performance hack

#242

Earlier quoted context omitted.

All code reuse creates coupling on some level. Creating more abstractions in between reduces coupling but creates code bloat. There is a trade off. For example, if you call the same function from many locations those locations are now coupled since if you change the function you change all of those locations behaviour. Many times that is desirable, in which case it is good coupling. The exact same rule applies to inh…

Can you elaborate a bit? How is there coupling between a thing which uses an interface and a thing which implements the interface of the two don’t know about each other? Especially if the interface is implicit à la Go interfaces or structural subtyping?

Every class implementing the interface needs to follow the same interface contract, that is coupling. If you want to change the interface contract for one of them you have to go and change it for all of them or you have buggy interfaces. Every time you create an interface you create a contract for it, if you have the same discipline with inheritance then inheritance isn't an issue.

The only problem with inheritance is that people can use it for classes that weren't written to be base classes, and therefore a ton of bad programmers use it for code reuse without thinking about the contract it is supposed to implement at all. With that in mind, allowing inheritance only for abstract classes isn't an issue at all.

Re: Inheritance was invented as a performance hack

#243

Earlier quoted context omitted.

Why create virtual methods in a class if you have no intention of it being a parent class? And if you intend for it to be a parent class you can design it so that these things aren't an issue.

Could you give a code example of how you would design things so that they aren't an issue?

The same way you design interfaces. If you can write good interfaces then you can write good base classes, its all about the contract between methods. Inheritance gets a bad rap because most programmers used it with classes that were never written to have interface contracts and therefore they create unintended coupling. Intended coupling is a good thing though, so as long as you have the same discipline when creating base classes as you have when creating interfaces then inheritance isn't an issue.

Re: Inheritance was invented as a performance hack

#244
post #238

Earlier quoted context omitted.

Reusing implementation is the point. Here is more specifically what I meant with my comment about specialization above. There is a class with four methods, three of which are exactly what you need but the fourth one, you need to modify. Solving this with inheritance is trivial (extend and override). Solving this with any other paradigm is... much harder and requires a lot more boilerplate.

In functional programming you'd just create a new function that takes a value of the same type of those other 3 methods. But anyway, creating a new method without changing any of the methods of the super class I think it's generally ok. The problems arise from modifying methods that the super class already implemented.

But code that uses the old function wouldn't magically start invoking your new function instead, something that inheritance and polymorphism give you for free.

Re: Inheritance was invented as a performance hack

#245
post #199

Earlier quoted context omitted.

I frequently hear people malign inheritance, and while it can obfuscate code in some circumstances, it can also produce code that is easily and clearly extendable. For example, a class with a static method that uses class properties to control behavior is cleaner than a function factory that takes a config object. Interface inheritance is also quite useful.

I think thanks to Java opting to use "implements" for interfaces, people no longer associate "inheritance" as the thing we do when we write a fully abstract class (i.e. interface) and then "inherit" this abstraction to implement it. Interfaces are, of course, crucial. Not sure I understood your example about the static class vs. function factory tbh though.

As a quick example...

class ServiceWrapper:

  service = ...

  v1 = ...

  v2 = ...

  @static

  def my_job():

    return service.call(v1, v2)
vs.

def create_service_wrapper(v1=..., v2=..., service=...):

  def f():

    return service.call(v1, v2);

  return f
The class can scale to multiple methods sharing parameters, but the semantics of the factory fall apart if you want to return more than one parameterized function.

Re: Inheritance was invented as a performance hack

#246
post #192

Earlier quoted context omitted.

Life is more than just self indulgences, I don't actually see a point in working or contributing to society at all if I can't build a foundation that will benefit my children. I'm certainly not working so I can drive a fancy car or whatever. Honestly not sure I'd even bother getting out of bed most days if the future of my children was just in the hands of the state, what would be the point.

Sounds like you may be depressed. My mom would tell us of how, similarly, us kids would be the only thing that helped her get through periods of depression. Life itself, even for those of us without children, is an incredible experience.

I just work myself to my limits but I do it for a reason, if that reason isn't there why not just be comfy instead?

Re: Inheritance was invented as a performance hack

#247
post #238

Earlier quoted context omitted.

In functional programming you'd just create a new function that takes a value of the same type of those other 3 methods. But anyway, creating a new method without changing any of the methods of the super class I think it's generally ok. The problems arise from modifying methods that the super class already implemented.

But code that uses the old function wouldn't magically start invoking your new function instead, something that inheritance and polymorphism give you for free.

Nothing will magically start calling your new function. If you are defining a new function that didn't exist before, then you'll have to actively call it somewhere. What you're describing instead is overriding an inherited function. However, that is full of pitfalls, I would not call that "for free" by any means. There are example of the problems in this very thread. Anyway, that's distinct from polymorphsim, which is present in functional programming.

You may be missing the point that's being made, though. No one is arguing against interfaces, but overriding concrete methods from a concrete class. Those need to be well thought out as extension points for you to have any chance of having stable software. Not quite for free.

Re: Inheritance was invented as a performance hack

#248

After reading all the comments of many confused and curious, here is when inheritance is bad and why so _in the absence of any performance considerations_. First, inheritance from an interface/trait is totally okay. The problem is class inheritance, meaning implementation inheritance. There are two cases: 1) you inherit from a class and only add methods but don't overwrite anything. This is the good case, you can do…

In your view, would this critique also apply to a trait-based version in Rust which supplies a default implementation for `push_all`? https://play.rust-lang.org/?version=stable&mode=debug&editio... trait Stack { fn push(&mut self, element: i32); fn push_all(&mut self, all: Vec ) { for element in all { self.push(element); } } fn pop(&mut self) -> Option ; } As far as I know it's impossible to invoke `super` to get at…

Your last point is the relevant here in this context. If the defauklt "push_all" has no access to member variables (how could it - it's defined on the trait) and only calls public methods (such as push) then it is no more powerful than a free function or extension function.

Hence it is okay.

However, if you where to have another private function "private_push_all" and "push_all" could decide whether to call "push" or "private_push_all" then we would have the same situation again.

Re: Inheritance was invented as a performance hack

#249

Earlier quoted context omitted.

Could you give a code example of how you would design things so that they aren't an issue?

The same way you design interfaces. If you can write good interfaces then you can write good base classes, its all about the contract between methods. Inheritance gets a bad rap because most programmers used it with classes that were never written to have interface contracts and therefore they create unintended coupling. Intended coupling is a good thing though, so as long as you have the same discipline when creatin…

The difference is that in one case, it is impossible to cause this error and in the other case (with contracts between methods) we now have to rely people on understanding what they are doing. Looking hat Java's hashCode&equals, I think history has shown that it is maybe not a good idea to rely on that too much.

Re: Inheritance was invented as a performance hack

#250
post #247

Earlier quoted context omitted.

But code that uses the old function wouldn't magically start invoking your new function instead, something that inheritance and polymorphism give you for free.

Nothing will magically start calling your new function. If you are defining a new function that didn't exist before, then you'll have to actively call it somewhere. What you're describing instead is overriding an inherited function. However, that is full of pitfalls, I would not call that "for free" by any means. There are example of the problems in this very thread. Anyway, that's distinct from polymorphsim, which i…

But that's what polymorphism does.

Somewhere deep in the code is calling a.foo(), but when you pass a subclass of A that overrides foo(), then this code "magically" calls that new implementation.

This is where specialization shines and no other paradigm allows this so elegantly and so simply.

Post reply on HN