Live data from Hacker News

If Inheritance is so bad, why does everyone use it?

buttondown.email

261–270 of 389 posts

Re: If Inheritance is so bad, why does everyone use it?

#261
post #198

Earlier quoted context omitted.

The term is unintuitive to me in that usage, because to me a protocol implies an exchange or a sequence of steps between two or more parties, such as in network or cryptographic protocol or a diplomatic protocol. Interfaces, however, only specify one endpoint of an interchange, in an inherently asymmetric way, and they primarily specify operation signatures, where there are often few constraints on the possible seque…

I don’t share your distinction, but it does make me curious: how would an interface representing a state machine fit into your mental model?

An interface representing a state machine usually does not directly represent the concrete state machine, but presents an interface to interact with the state machine. E.g. for a parser state machine, submit the next token that will advance the state machine; or an operation to read out the current state, or an operation to obtain a list of the currently possible transitions.

Of course it's not impossible for the preconditions for each operation of the interface to map exactly to a protocol so that the operations permitted in each state correspond 1:1 to the state transitions of a protocol. But that is not the general case, and not how people usually think about interfaces.

I don't know if you are familiar with the term interface description language (IDL), but generally IDLs are not suitable for specifying a protocol, in the sense of specifying (among other things) the protocol's state machine. It would be misleading to call them protocol description languages.

There are other ways in which "interface" and "protocol" differ. For example, we call HTTP a protocol, and things like SOAP and REST and CORBA. But we call a concrete REST API an interface, not a protocol, and we call what is defined by a WSDL an interface, not a protocol. A protocol can be used to access an interface (I use SOAP to access a monitoring API). An interface may support different protocols (I can operate different protocols through the Unix socket interface). We talk about Linux kernel interfaces, not about Linux kernel protocols (and if we would, we would mean something different by that). The two words are not interchangeable.

An interface describes the boundary between two things. A protocol describes a behavior between multiple entities. By the implementation of an interface we mean the implementation of one specific side, the one that exposes the interface, not the one that uses the interface. An interface can exist even if no one uses it (only one side exists). The implementation of a protocol, on the other hand, is split between both sides. You can't have only a one-sided protocol. If no one uses the protocol, neither side exists, so to speak.

Re: If Inheritance is so bad, why does everyone use it?

#262

As a programmer with likely less experience than most of these commenters, the main question that always feels under addressed in these kinds of posts is that of code deduplication. Most specifically, often when encountering a situation in which I have two slightly different classes/types that need to be polymorphic with each other, all the standard non-inheritance based approaches seem to require a lot of outright i…

It's always possible to 'deconstruct' objects with methods into just dumb structs with functions acting on them. This is the direction Julia takes for instance.

One advantage of this is that it exposes that 'inheriting' a method is really just applying the same base function to all classes that support a particular interface. You can override a method by specialising the function for a subinterface. This interface can just be a marker that says 'this struct has these fields, and semantically is a 'IMyInterface').

Of course object oriented programming languages tend to encourage private and protected properties and such, which force all of this to take place inside the class. At first I though that that was the best way to avoid a mess, but it prevents you from doing this, possibly leading to more code duplication. And after some more experience with python there's something to be said for python's approach of just using name conventions to point out when to be careful.

Re: If Inheritance is so bad, why does everyone use it?

#263

Earlier quoted context omitted.

I'm inclined to semi-agree with this, although I'm not sure I'd be quite as adamant about it myself. But I do generally think that CSS is taught in a way that encourages some bad practice around cascade/inheritance. I will point out though that (at least in my experience), BEM solved the majority of these problems for me even without a preprocessor. The language is definitely oriented towards inheritance/cascade, but…

Do you have a CSS component framework that you can recommend for use with BEM?

I could link you to a few (I think Bootstrap adopted BEM at some point, Material Design Lite I think uses a variant of it), but I can't recommend them with confidence because generally I don't use extensive style frameworks when I work on large applications. I feel like CSS frameworks are largely useful for bootstrapping projects and for keeping control of large projects where styling starts to break down. A lot of projects I work on are past the point where I need the bootstrapping help, and BEM itself helps me keep control of the CSS code as the projects grow so I don't need to have a strict framework to help me organize everything.

----

In general though, I would actually suggest that you can kind of use anything if you're not planning on forking the component library. Most of these 3rd-party libraries you're not going to be restyling, so long-term maintenance and scalability isn't really a concern, you're never touching that code.

And BEM is just a naming convention, so if you're pulling in a React component and it has a hook for you to attach your own classes, then attach a BEM-style class, otherwise pass in the styling information into the props the way that most JS components want. I've used BEM with React components, with Material design, with Angular components, etc... I don't know, I haven't really run into issues. I've even worked on a codebase that was a mixture of BEM CSS, 3rd-party CSS, and Tailwind. It was fine, I didn't notice any major issues. Typically 3rd-party component dependencies are not a major source of cascade bugs in my experience, but maybe I've just been lucky. Most components I've seen lock down their styles to the point where it's kind of a pain to even try to override them with CSS, and the specificity required to do so forces you to effectively isolate those overrides anyway.

Whatever component framework you're using will have its own customization API, and in my experience that usually won't be handled through CSS. If it is handled through CSS, it will probably be handled by attaching classes, and then when you attach those classes you can use BEM. The major annoyance in my experience is that (for me) BEM often works better than whatever customization system that the 3rd-party components is using and I get frustrated that I'm mixing more straightforward CSS that's easier to debug and design in-browser in with whatever property-based thing that the components expose. But I don't usually think I run into many bugs?

What BEM helps with is dealing with cascade, code organization, naming, and debugging/search. With a 3rd-party component framework, most of that stuff is out of your control, so just use whatever the framework wants and then use BEM for the stuff that is in your control.

If you have to do some kind of CSS-based override of a 3rd-party component that isn't being handled through a component-specific API, wrap it in a BEM-style class for your actual component so that it's a one-time customization:

  .Input__Username .some_component_depencency input {
      /* This is not ideal, but (imo) you'll still effectively never really see cascade bugs from doing it this way, and specificity will rarely be a concern. */
   }
One thing that is nice about BEM is that because your own CSS is being scoped to specific named components, it actually becomes a bit easier to have a lot of 1st-party CSS living alongside 3rd-party CSS and know that your CSS is not going to break the 3rd-party CSS. So I tend to worry a lot less about what other parts of the code/dependencies are using when I'm using BEM, because I more confident while writing BEM that I'm not introducing bugs into the other CSS.

Re: If Inheritance is so bad, why does everyone use it?

#264

Earlier quoted context omitted.

> Where I think inheritance works best is when the state in base classes is limited and the interface is quiet clear. Ideally where you are meant to override is also well defined. What benefit is inheritance providing here? What you described sounds mostly like a struct, at which point the only value the interface provides is possibly some computed fields.

When you scratch deep enough at programming, everything is structs and interfaces defining how you interact with them and how they interact with the world. The best example of this (IMO) is how `AbstractMap` works in Java. [1] In order to make a new object which implements the `Map` interface, you just have to inherit from the `AbstractMap` base class and implement 1 method, `entrySet`. This allows for you to have a…

This works with Rust's traits as well, for example, Iterator. Or Ruby's mixins (which are inheritance, I guess, heh). It is super useful, but doesn't actually require inheritance, even if you can use inheritance to do it.

Re: If Inheritance is so bad, why does everyone use it?

#265
I look mostly at JS and some Rust codebases and almost nobody uses inheritance!

I believe it doesn't make any sense, you can use different patterns to have the benefits without creating a complicated type hierarchy where state and functions are mixed across different files.

Whenever I would use inheritance I use the builder pattern.

Re: If Inheritance is so bad, why does everyone use it?

#266

Earlier quoted context omitted.

>It looks like composition over inheritance has caught on as the better default in other languages, but in the CSS world people still cling to the cascade as a best practice for some reason I find this falls into generally two camps, those who want to fight the browser and those who don’t. Those that tend to hate the cascade tend to fight the browser a lot, whether they realize it or not. Generally speaking, they wan…

Two camps I see are (1) those who want to hold the program in their head and be able to answer ever more obscure questions about the program using their understanding. And (2) those who try things until it works and then address problems as needed. Do these two camps align with your two camps? Those who want control fight the cascade, others just fiddle with it until it looks good? I don't mean to disparage either ca…

I don’t think these are two separate camps. Rather everyone has a value - let’s call it S - which is the maximum size and complexity of a program they can hold in their head. When the program’s size is smaller than S then they use strategy 1, when it’s larger they use strategy 2.

When you are a beginner your S is close to zero, as you gain experience you develop increasingly better compression to be able to grow your effective S, but it’s never infinite. There’s always some size program where you will devolve to strategy 2, and all programs tend to grow in complexity until they reach the point where nobody understands them, like some kind of complexity Peter principle.

Re: If Inheritance is so bad, why does everyone use it?

#267

Earlier quoted context omitted.

I'll never understand why a lot of CSS devs are opposed to it. I can understand the initial gut reaction, but I've been writing CSS for 14 years and I love Tailwind. The cascade is a wonderful idea that has unfortunately not played out well in practice. Anyone who thinks it's just a skill issue is deluding themselves. In all my years, I've never seen CSS that (a) leverages the cascade, and (b) scales elegantly. It al…

Mainly because nobody is a "CSS Dev". If someone's entire job was developing CSS, you might expect that they would be willing to learn one new slightly different way of doing it. But in reality the pushback comes from full stack developers who already have a million other things to worry about, such that relearning all the basic CSS they already know, to achieve benefits that are rather minuscule in the grand scheme…

Inline styles don't work with a strict CSP. Have you ever had to work with such a restriction?

Re: If Inheritance is so bad, why does everyone use it?

#268

Earlier quoted context omitted.

> Where I think inheritance works best is when the state in base classes is limited and the interface is quiet clear. Ideally where you are meant to override is also well defined. What benefit is inheritance providing here? What you described sounds mostly like a struct, at which point the only value the interface provides is possibly some computed fields.

When you scratch deep enough at programming, everything is structs and interfaces defining how you interact with them and how they interact with the world. The best example of this (IMO) is how `AbstractMap` works in Java. [1] In order to make a new object which implements the `Map` interface, you just have to inherit from the `AbstractMap` base class and implement 1 method, `entrySet`. This allows for you to have a…

>In order to make a new object which implements the `Map` interface, you just have to inherit from the `AbstractMap` base class and implement 1 method, `entrySet`

Used to think that way, but I now prefer the alternative - passing function(s)/lambda(s) for the necessary functionality of the dependent class.

This way is actually more flexible, as you can change behavior without modifying the override or having a bunch of switches/if-else in your required function.

So instead of 'entrySet' being defined inside MyClass, you would define it outside it, or possible as a static method, and pass it to AbstractMap when you create it.

So you don't need to have every class implement a bunch of interfaces like or Hashable, Orderable, etc. in order get the desired behavior.

Now I guess you would come back about you shouldn't be able to able to do that outside the class, but I also think those are also bad ideas. Python famous gets away with not having private/protected (although there is a way you can kinda of get something similar).

Re: If Inheritance is so bad, why does everyone use it?

#269

Earlier quoted context omitted.

if i were writing an intro to programming book, i would introduce OO as a means of building encapsulation. i'd only get into inheritance in later chapters.

You can have encapsulation without oop. Polymorphism is the real benefit of oop imho

Which kind of polymorphism? Subtype polymorphism I'm guessing?

Re: If Inheritance is so bad, why does everyone use it?

#270

Earlier quoted context omitted.

Inheritance doesn't work well for games, that's why so many games take a component based approach like Unity, or full blown ECS.

The implementation of inheritance (more specifically, polymorphism and dynamic dispatch via vtables) is a problem in games, because it adds an extra layer of indirection, and screws with cache locality. But the semantics of inheritance ( X ISA Y ) still apply. In an ECS, the implementation is different (struct-of-arrays) but you can still think of an entity as "inheriting from" the various components its built from.

> you can still think of an entity as "inheriting from" the various components its built from.

If it's based on components, wouldn't that mean you would think of it as being... _composed_? I typically don't hear "it's made of many components" and think of inheritance

Post reply on HN