← Back to context

Comment by zozbot234

6 days ago

> This ‘90s API, and it set the core of the web stack. And it’s super object-oriented, and it’s just hard to express all that stuff in Rust, because Rust doesn’t lend itself to object-oriented programming. It doesn’t have inheritance, for example, which is a very fundamental building block.

That's a rather strange criticism, seeing as the only thing about objects that's slightly involved to express in Rust is implementation inheritance; and even then, it can be phrased in a very reasonable way by using the generic typestate pattern. I.e. expressing a class that can be inherited from as a generic object MyBaseClass<T>, where T holds the "derived" object state (and can itself be generic in turn, thereby extending the type hierarchy) and methods can either be implemented for any MyBaseClass<T> or for some specific MyBaseClass<MyDerivedObject>.

(This aims to do the right thing whenever a method on the base class relies on some method implementation that's defined deeper in the hierarchy, i.e. there is an indirection step, aka open recursion. That's the part that is missing when using simple composition.)

> I.e. expressing a class that can be inherited from as a generic object MyBaseClass<T>, where T holds the "derived" object state (and can itself be generic in turn, thereby extending the type hierarchy)

Interesting approach! Have you used this in larger project (i.e. for a larger type hierarchy)?

I suspect it might at least take some getting used to (readability-wise), plus it might lead to additional boilerplate in case some child "classes" only want to override some methods, but not others. (The parent will have to implement some switching logic.)

Overall I agree, though, I can't think of any OOP use case that could not be covered by this.