I'm thinking about tree structures, and I feel that I don't like them. It's like when you have a shop, then you try to put all products to tree-like catalog, and then you need to place one product to multiple categories, now you have multiple routing, bla-bla. I don't feel like everything in the world could be put to a tree.

Instead, I like idea of tags. I would like to store everything with tags. With tags I could do much more. I can even simulate trees if I want. I want to have tag-based filesystem!

But hey - modern OOP paradigm with inheritance is based on tree. I want to see how it is when you don't have such basement.

Closest thing I found is mixins in some languages. Do you know what else is also about this ideas?

  • 1
    Multiple dispatch? en.wikipedia.org/wiki/Multiple_dispatch – Maglob Feb 6 '11 at 21:07
  • @Desolate, as the OP wants an OO language, the relational model might be ruled out. – Péter Török Feb 6 '11 at 21:15
  • 1
    @Desolate With data it's not a problem, but I want a language, I want a tree-free environment, not affected by tree idea at all. I'm wondering if it's possible... – user16131 Feb 6 '11 at 21:33
  • Ok, cool, then I'd agree with Peter's answer, but I'd also put in annotations as a language feature that lets you do tagging – Desolate Planet Feb 6 '11 at 21:38
  • 1
    @kolupaev: Certain things are modelled well by trees, other things aren't. Inheritance has it's place, tags have other uses - take both where appropriate, everything else would be useless ideology ;) – Dario Feb 6 '11 at 21:56

Inheritance hierarchies represents "is-a" relationships - one object really is another object.

That's not what tags represent. The categories in a shop don't represent is-a relationships, it's more of a "belongs to" or, in programming terms, "supports feature xy". Tags can change, they can be added and removed as you need it - base classes can't, as the object needs it! Objects don't depend on the tags you give them, but they depend on their base classes to make sense.

You can put some car in category "green cars" or "cars from the 1960's" - no problem, it doesn't care - but it can never cease to be a vehicle!

So as you see, inheritance trees and your tags model entirely different things. One is about the object itself, the other one on how we relate objects together.

True, there are cases where it makes sense for an object to have more than one base class, but these are rare and as supporting true multiple inheritance causes many other problems (that's why lots of OO languages disallow it), it's a reasonable way to model is-a hierarchies through trees.

On the other hand, your tags are represented through interfaces (for which implementing multiple ones is allowed in practically every OO langauge I know) - or better - through typeclasses, which can be added or shadowed as you need it.

I agree with you that inheritance is often overused in places where interfaces would fit better, but as both are in principle orthogonal concepts, both have their appropriate use-cases.


I'm again stressing typeclasses or concepts as they're probably the answer you were searching for, though the question works on the false premise that tags are to replace inheritance.

  • Ok, anyhow you name this relationship, it's a directed link. Objects with such links are a directed graph. – user16131 Feb 6 '11 at 21:43
  • Sorry, too early submitted. Tags are creating non-directed graph. This is main difference I'm thinking about. – user16131 Feb 6 '11 at 21:44
  • 2
    Interfaces are good, but they don't add anything to objects, they are describing objects. Mixins, for example, would give specific abilities to class, behaviors, etc. – user16131 Feb 6 '11 at 21:46
  • @kolupaev: Edited the answer. Take a look at type classes. Do you know .NET'S extension methods? Tags describe too, as typeclasses do. Adding functionality once you got that generic description is just a matter of syntactic sugar. – Dario Feb 6 '11 at 21:50
  • @Kolupaev - Interfaces are virtually analogous with Tags, they add categorization via the API contract that they enforce. The main point being that all objects will not respond in the same way when the same method is used on them. – ocodo Feb 6 '11 at 21:52

I think the heart of your issue lies in the language's type system. In languages that use structural typing or duck typing, the type of the object is determined by the structure (or just part of the structure in duck typing) of the type instead of having to declare the type using inheritence. So all it takes to create an object of a certain type is to "tag" the object with a certain structure. This also avoids many of the issues with multiple inheritence.

Scala is a language with structural typing, and Ruby uses duck typing.

"When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck."


Roles in Perl6 come close. They specify a named (or "tagged") set of behaviors. Perl 5 has the incredible Moose, which implements the same concept. The are somewhat like java interfaces, but with implementation not just method definition. The role concept was based in part on smalltalk traits.


Two answers:

  • most dynamically typed language handle polymorphism separately from inheritance. not like your "tagging", but simply "if the object can do this, then it can be used here". If it doesn't, a run-time error is generated.

  • Google's Go language accomplishes a similar thing with interfaces. It's somewhat similar to the Java concept of Interfaces, but detached from inheritance: if an object definition has all the required methods, the compiler allows it to be used. In effect, interfaces are type 'specifications', that allow the compiler to strictly check at compile time if the substitution is acceptable without relying on a common ancestor.

  • 1
    Two answers should be two posts. But +1 anyway; I like the 2nd answer. – DarenW Mar 6 '11 at 0:10

modern OOP paradigm with inheritance is based on tree.

Check out C++, it has multiple inheritance. Of course, whether this counts depends on your definition of "modern" ;-)

Its successors, Java and C# disallowed multiple inheritance for very good reasons, but you still can implement multiple interfaces in these. IMO interfaces (especially marker interfaces) are much closer to the concept of tags than (abstract or concrete) classes.

  • Inheritance still gives oriented graph of objects, better then just tree, but I'm looking for a net of objects. – user16131 Feb 6 '11 at 21:31
  • I'd say C++ multiple inheritance gives the tree structure to OOP, simplistic languages like Java and C# have more of a list-based approach to inheritance. – gbjbaanb Aug 3 '13 at 12:37

For me aspected-oriented programming was always the closest thing to tags in OOP. Aspects are essentially tags that infer some behavior upon a method/class, and one method can multiple aspects. Unfortunately Heijlsberg has several times expressed a certain distate for AOP so it's doubtful if we'll ever see more support for it in the framework. There are however some pretty good thirdparty libraries if you want to experiment with it

  • AOP is built UPON some idea, merged with join points, it's not an basement paradigm itself. – user16131 Feb 6 '11 at 21:56

the bigest problem with multiple inherentence is the fact the language don't know wich method to call:

Class A {
  public method1 () {}
Class B {
  public method1 () {}
Class C extends A, B {
  public method2 () {}

Object o = new C();

Which method1() will be called? Will they both get called? In wich order? So only a few languages support multiple inheritence.

  • In a frame of my question, biggest problem is that class C to class A is not the same as class A to class C, this link is directed, so, they create a hierarchy. – user16131 Feb 6 '11 at 21:49
  • as opposed to C#-style inheritance where you cannot call method1 from a derived class without casting to an interface first. Is that progress? As it is, in C++ you'd get a compile warning if you tried to call method1 without disambiguating it by prefixing it with the base class (eg A::method1(), or dynamic_cast<A>(o).method1() ). Not much of a difference! – gbjbaanb Aug 3 '13 at 12:46

Ontologically, inheritance is represented by a directed acyclic graph of is-a relations between classes. Because the is-a relation is transitive (from its definition) the graph must be acyclic (or rather, if there is a cycle the only thing you can conclude is that everything in a cycle is actually the same thing). Many languages apply further restrictions (e.g., forcing a tree instead of a DAG) due to the experience with the complexity of C++'s inheritance, but that's not inherent whereas the restriction to DAGs is.

But there are other possible relations, provided the general transitivity requirement is dropped. This is why delegation is such an important software pattern; it's the basis for many relation implementations.


The problem you relate is an issue in certain development context (like game designing), and the closest solution people have found seems to be component-driven objects.

Roughly said, it lets you add features to an object by attaching more components (kind of like tags) to it. This question on Stack Overflow explores the issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy