Hacker News new | ask | show | jobs
by asavinov 3455 days ago
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 is that we actually need two different relations: 1) membership relation, and 2) inheritance (or inclusion in more general case). Unfortunately, we cannot reduce them to one relation. If we do (in prototype-based languages) then normally we will still distinguish the role of this one relation depending on the context.

Mathematically, we have the membership relation '∈' between an element and a set, and we have the subset relation '⊆'. Just as we need both of them, we need both class instances and classes. In other words, if somebody argues that classes are not needed, then it is analogous to the statement that sets are not needed and it is enough to have only membership relation among elements. It is possible to develop such a theory but then we will get an alternative mathematics. Or we will implicitly treat some elements as sets.

5 comments

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.

> "It's not about objects and classes, it's all about messages"

Often cited, but somewhat meaningless without the context in which Kay originally made that statement.

One should instead consider that object-orientation is "… the insight that everything we can describe can be represented by the recursive composition of a single kind of behavioral building block that hides its combination of state and process inside itself and can be dealt with only through the exchange of messages." - Alan Kay

It is primarily an approach to representing complex problems and systems in code. It is an alternative to modular programming (procedures and subroutines) organized using functional decomposition (structured programming), or an information or data-flow modeling approach. It is not primarily about organizing code.

I agree with you in that I don't agree with the author. I felt that the strongest point of the paper was that it was critical of something that is assumed to be a good thing. That value was that it challenged one of my assumptions that I had never questioned.
You've got the mathematics 180° wrong! In standard mathematical foundations, ∈ is the only primitive relation, from which all others (including ⊆) derive.
Why do we need inheritance? Embedding and delegating can handle any task but the silly ISA pretend game.
Embedding and delegating don't deal very well with virtual dispatch afaik. Declaring different implementations for arbitrary sub-classes seems harder and less elegant without inheritance.
But virtual dispatch is trivial to add where you actually need it, a bunch of function pointers in a struct and you're good to go. And once you stop viewing the world through the OOP filter there aren't that many real hierarchies and interfaces left to deal with. The curse of OOP is that it turns problem solving into day dreaming, with expected results.
OOP isn't the solution to every problem. Your proposed replacement to inheritance would would work nicely in some cases. As far as I can tell, it doesn't address the use case of generic classes at all, at least in a type-safe way.
Generics and OOP are orthogonal, one does not depend on the other. So let's say you declare your vtbl struct with a generic parameter, what's the difference?
Hm. I think you're right. It's probably my classical OOP conditioning causing me to conflate them.
> But virtual dispatch is trivial to add where you actually need it, a bunch of function pointers in a struct and you're good to go.

Or let the compiler do it for you? It's like saying I shouldn't use first-class closures, because they're also trivial to implement manually where I actually need them.

It is a convenient extra piece of flexibility. When you want to extend code in the future, inheritance can make it easier.
Sorry, not buying that one. There's nothing in inheritance that makes extending code easier. You either design for extension or not, has nothing to do with OOP.
Inheritance creates an extra extension point automatically. You don't need to design for it.

A good, thoughtful design is better, of course.

http://conceptoriented.org/savinov/publicat/arxiv_1501_00720...

Just skimmed the 'Cross-Cutting Concerns' in your paper above. Isn't AOP far more general than what you propose there? Please correct any misunderstanding but per the parent based approach you describe -- "cross-cutting concerns are modularized in parent incoming methods and this functionality is injected in child methods" -- you would need to duplicate a CCC e.g. logging in each distinct 'parent'.

> Isn't AOP far more general than what you propose there?

Yes, definitely AOP provides much more freedom in injecting behavior to other parts of the code - it is its main goal while COP has different goals.

> you would need to duplicate a CCC e.g. logging in each distinct 'parent'

No, because in COP, "Parents are Shared Parts of Objects" [1], that is, a parent may have many children. Inheritance in COP is inclusion. If a parent implements a method then it will be reused by all its children.

[1] http://bibliography.selflanguage.org/_static/parents-shared-...