Live data from Hacker News

Classes Considered Harmful [pdf]

web.cecs.pdx.edu

91–100 of 129 posts

Re: Classes Considered Harmful [pdf]

#91

The E programming language, and its newer relatives like Monte, lack classes; instead, objects are defined by object literals and the extends keyword performs object composition by delegation.

You mean it's prototypal, like Self, IO, Javascript?

No, it's similar to creating an object this way in ES6:

    function makeVector(x, y) {
        return {
            norm: () => Math.sqrt(x*x + y*y),
            // ... more methods ...
        };
    }
but frozen so that consumers can't change it except by calling a method.

It's odd how this is the 'obvious' way to generalize lambda expressions from functions to objects, yet it's rare to see this style, and you always have to clarify that you're not talking about prototypes. (IIRC Emerald, mentioned in the paper, also works something like this.)

Re: Classes Considered Harmful [pdf]

#92

Earlier quoted context omitted.

>> but also provide implementation inheritance, which is bad. Inheritance isn't bad. Abusing inheritance is bad. For the record, you can also abuse composition, polymorphism, operator overloading, free functions, interfaces, records, and abstract data types. I've abused them all and seen them abused as well. Inheritance is just another tool. Like all tools, we are expected to use them wisely.

Do you know any situations where implementation inheritance is the best tool?

Yeah, inheritance is the best tool when I want a derived class to implement all the behavior of the super class.

Re: Classes Considered Harmful [pdf]

#93
post #48

Earlier quoted context omitted.

There really isn't a direct analog in Rust. The best approximation in Rust is actually a combination of constructs in the language: structs and traits. Structs are almost exactly like the C-objects of the same name: they define layout in memory for a data structure with discrete types as fields, and there are various packing options available. However in addition to this a struct-specific implementation can exist whi…

You say traits are a rough analogue for C++ base classes with virtual methods. What are the fundamental differences?

For one, traits are inherently static and their methods are statically dispatched, somewhat like a concept. Traits which satisfy certain conditions which make them "base class-like" can be reified as a trait object, which is a vtable ptr + data ptr pair, which dynamically dispatches through the vtable. The separation of the vtable ptr from the object means every trait object gives you dynamic dispatch for one trait only and you can have an unbounded number of trait objects, in contrast to C++ where you have dynamic dispatch through the finite number of base classes listed by the class author.

Re: Classes Considered Harmful [pdf]

#94

I like this kind of critical papers but I cannot agree with the author in this case. I have studied this problem quite deeply while working on concept-oriented programming and concept-oriented data model ( http://conceptoriented.org/ ) for many years by also trying to minimize the number of basic constructs. Yet, my conclusion is that classes are actually needed. There are several major reasons for that. One of them…

we actually need two different relations: 1) membership relation, and 2) inheritance (or inclusion in more general case). No. You don't need OO at all, let alone bolt-on conceptual baggage like this. The notion of object oriented programming is completely misunderstood. It's not about objects and classes, it's all about messages. - Alan Kay[0] [0] From my fortune clone @ https://github.com/globalcitizen/taoup

Message passing only takes you so far. As soon as you want to start reasoning you will structure your messages into groups and now you're back to what looks suspiciously like classes.

I'm not arguing for one or the other but that extreme late-binding as espoused in much of the smalltalk way of doing OO only takes you so far. Static reasoning about program structure is helpful and just message passing alone does not give you enough structure to do that.

Re: Classes Considered Harmful [pdf]

#95

Earlier quoted context omitted.

This applies to you, too. What controlled experiments have you performed to test productivity differences of different methods of programming?

Jackmott didn't make a claim. The linked PDF did. Why should someone have to support a claim that they didn't make?

Jackmott is the one who introduced the standard of "controlled experiments". Why doesn't he propose an experiment design which will shed light on the question of whether classes are harmful or not?

Re: Classes Considered Harmful [pdf]

#96
post #63
post #62

Earlier quoted context omitted.

Better why?

Superior composability with simpler semantics and sounder type systems. Class hierarchies are inherently unfriendly to strong, sound type systems. Interface composition isn't. Composing interfaces is clean and straightforward. Composing classes isn't, and you run into things like the diamond problem.

Classes do not imply inheritance. Classes are a means of defining an interface, albeit a heavy one.

The statement that it is better to separate data and behavior is far from self-evident IMO, and I would be very interested to understand why this is such a deeply held belief. Seriously, why?

Re: Classes Considered Harmful [pdf]

#97
post #78

Earlier quoted context omitted.

I'm not familiar enough with the internals of how Rust handles v-tables and the like in light of its other features to answer that competently. In practice, one defines an interface in C++ by having a (hopefully) stateless class with pure virtual method declarations, and then classes derived from this class must implement these methods (in order to instantiate them anyway). In Rust one defines a data structure (eithe…

The big difference is that when you have a trait object in Rust, it's a double pointer: a pointer to the vtable, and a pointer to the data. In C++, in my understanding, you'd have a single pointer to both the vtable and data laid out next to each other.

So rust traits are effectively/functionally abstract classes with restricted functionality and a different implementation?

Re: Classes Considered Harmful [pdf]

#98

I like this kind of critical papers but I cannot agree with the author in this case. I have studied this problem quite deeply while working on concept-oriented programming and concept-oriented data model ( http://conceptoriented.org/ ) for many years by also trying to minimize the number of basic constructs. Yet, my conclusion is that classes are actually needed. There are several major reasons for that. One of them…

You've got the mathematics 180° wrong! In standard mathematical foundations, ∈ is the only primitive relation, from which all others (including ⊆) derive.

Re: Classes Considered Harmful [pdf]

#99

I like this kind of critical papers but I cannot agree with the author in this case. I have studied this problem quite deeply while working on concept-oriented programming and concept-oriented data model ( http://conceptoriented.org/ ) for many years by also trying to minimize the number of basic constructs. Yet, my conclusion is that classes are actually needed. There are several major reasons for that. One of them…

Why do we need inheritance? Embedding and delegating can handle any task but the silly ISA pretend game.

It is a convenient extra piece of flexibility. When you want to extend code in the future, inheritance can make it easier.

Re: Classes Considered Harmful [pdf]

#100

Earlier quoted context omitted.

The big difference is that when you have a trait object in Rust, it's a double pointer: a pointer to the vtable, and a pointer to the data. In C++, in my understanding, you'd have a single pointer to both the vtable and data laid out next to each other.

So rust traits are effectively/functionally abstract classes with restricted functionality and a different implementation?

Sort of. The closest thing in C++ would be concepts. That is, even using traits in this way is the minority case; they're more usually used for monomorphized, statically dispatched code.

But, given the case where you want dynamic dispatch, then in a sense, they are, yes.

Post reply on HN