In meinen Recherchen zu den in der STL verwendeten Kategorien (z.B. im Zusammenhang mit iterator_category der iterator_traits<T>) bin ich auf Alexander A. Stepanov gestoßen. Kein Wunder, schließlich hat er die STL entwickelt (ca. 1993), nachdem C++ Templates konnte. Zuvor (1985) hatte er die generische Bibliothek für Ada entwickelt. Man kann sagen, dass Herr Stepanov sich ziemlich gut auskennt und sich zu vielem Gedanken gemacht hat. In der C++-Hierarchie kommt er gleich nach Bjarne Stroustrup.
Das An Interview with A. Stepanov ist nun sehr aufschlussreich. Ich habe noch nie einen Text gelesen, in dem ein hochrangiger Guru zwei große Konzept der Informatik innerhalb eines Absatzes ‘trashed’:
STL is not object oriented. I think that object orientedness is almost as much of a hoax as Artificial Intelligence. I have yet to see an interesting piece of code that comes from these OO people. In a sense, I am unfair to AI: I learned a lot of stuff from the MIT AI Lab crowd, they have done some really fundamental work: Bill Gosper’s Hakmem is one of the best things for a programmer to read. AI might not have had a serious foundation, but it produced Gosper and Stallman (Emacs), Moses (Macsyma) and Sussman (Scheme, together with Guy Steele). I find OOP technically unsound. It attempts to decompose the world in terms of interfaces that vary on a single type. To deal with the real problems you need multisorted algebras – families of interfaces that span multiple types. I find OOP philosophically unsound. It claims that everything is an object. Even if it is true it is not very interesting – saying that everything is an object is saying nothing at all. I find OOP methodologically wrong. It starts with classes. It is as if mathematicians would start with axioms. You do not start with axioms – you start with proofs. Only when you have found a bunch of related proofs, can you come up with axioms. You end with axioms. The same thing is true in programming: you have to start with interesting algorithms. Only when you understand them well, can you come up with an interface that will let them work.
Gemeint sind die Konzepte der objektorientierten Programmierung und der Bereich der Informatik, der Künstliche Intelligenz genannt wird.
Auf ObjectOrientationIsaHoax wird dieser Abschnitt des Interviews ‘diskutiert’. Aber…
Was ist eigentlich eine Kategorie?
Folgende Definition habe ich aus einem Script:
- Kategorie
- Menge von Typen, die gewisse Anforderungen erfüllen. Ein Typ ist ein Modell einer Kategorie.
- Kategorie ist Menge ihrer Modelle, z.B. alle Klassen, die ein bestimmtes Interface erfüllen.
Oh, ok. Wie jetzt? Von den zweien gefällt mir der erste Definitionsansatz noch am besten. Klingt so ein bisschen nach einer Schnittstellendefinition (als erfüllte Anforderung) ohne Vererbung. Oder? Anforderungen können aber vieles sein. Auch Laufzeitanforderungen. Man kann z.B. für eine Kategorie von Algorithmen verlangen, dass die in ihr enthaltenen Algorithmen eine Laufzeitkomplexität von O(n) haben.
Generell sind Kategorien eine Alternative zur Mehrfachvererbung (oder Vererbung allgemein). Ein Beispiel soll das verdeutlichen. Stellen wir uns vor, dass wir eine Angestelltenverwaltungssoftware o.ä. entwickeln. Vereinfacht gibt es Manager, Entwickler und Kundenbetreuer. Diese können Teilzeit oder Vollzeit arbeiten. Würde man dies durch Mehrfachvererbung realisieren, ergäbe sich ungefähr folgendes Bild.
Die Verwendung von Interfaces (z.B. in Java) würde das Problem nicht verringern. Aus den drei Klassen der Angestellten-Hierarchie und den zwei Klassen der Anstellungsverhältnis-Hierarchie ergeben sich sechs zu implementierende Klassen. Die Mehrfachvererbung bringt also das Problem der Typexplosion mit sich.
Desweiteren drückt der Polymorphismus, der aus der Vererbung und dem Überschreiben einer Methode in abgeleiteten Klassen herrührt, auf die Performanz des Softwaresystems. Schließlich muss zu jedem Laufzeitobjekt der tatsächliche Typ ermittelt werden, damit dann die richtige Methodenimplementierung aufgerufen werden kann. Auch dieser Aspekt führte zur Verwendung von Kategorien. Deshalb…
Was sind Kategorien?
Im Zusammenhang mit Kategorien stösst man in englischen Texten auch auf den Begriff multisorted algebra
. Leider weiss ich nicht sicher, was das ist, deshalb erwähne ich es hier, erkläre es aber nicht weiter. Den Begriff sollte man sich aber merken, klingt beeindruckend.
Zusammenfassend sind Kategorien eine Möglichkeit eine mehrdimensionale Vererbungshierarchie zu realisieren, ohne Vererbung (zumindest nicht notwendigerweise). Im obigen Beispiel gab’s zwei Dimensionen: Angestellter und Anstellungsverhältnis. Die Verwendung von Kategorien im Beispiel ergäbe beispielsweise Angestellte, die eine Variable besitzen, die angibt, ob Voll- oder Teilzeit gearbeitet wird.
Ich stelle mir eine Kategorie gerne als eine Menge von Typen vor, die Methoden eines oder mehrerer Interfaces implementieren, dies aber nicht explizit tun.
interface IExample{
public void method1(typ1 par1);
}
class Example{
public void method1(typ1 par1){
System.out.println("Hello, World.");
}
}
Im Beispiel realisiert die Example-Klasse zwar die im Interface IExample deklarierte Methode, gibt jedoch nicht explizit (mit implements IExample) an, dass es dies tut. D.h. als Anwender muss man wissen, dass Example die Methode zur Verfügung stellt und kann dann Example an Stellen verwenden, wo generell IExample verwendet werden kann.
Ähnliches gibt es bei EJB. Hier implementiert die Bean-Klasse das Remote-Interface auch nicht explizit. Hat zwar andere Gründe, die Funktionsweise ist aber dieselbe. Implizites Wissen, sozusagen.
Es ist schwierig sich hier in Java einen Vorteil vorzustellen. In C++ ist der Vorteil aber leicht einzusehen. In einer typparamtrisierten Klasse (einem Template) kann auf ein Objekt eines Typparameters zugegriffen werden, ohne dass man explizit weiss, um welchen Typ es sich handelt. Hier ist die Bezugnahmen auf eine Kategorie als eine Abstraktion von Typen also durchaus leicht umsetzbar. Als Stichwort sei hier noch latent typing genannt. Ein kurzes Beispiel:
template <class T>
void hallo(const T& partner){
partner.gruesse();
}
Das Beispiel ist entnommen aus Lehrbuch der Objektmodellierung von Heide Balzert. Man könnte sagen, dass der Typ T zu einer Kategorie gehört, die die Implementierung der Methode gruesse fordert.
In conclusio
Ein Synonym für Kategorie
ist übrigens Konzept
. Deshalb nochmal zur Wiederholung:
Generic Programming von David R. MusserEin Konzept ist eine Familie von Abstraktionen, die durch eine gemeinsame Menge von Anforderungen in Beziehung stehen.





Post a Comment