2024-05-16 18:30:51 +02:00
|
|
|
Konzept für einen Vortrag
|
|
|
|
|
=========================
|
|
|
|
|
:author: Ichthyostega
|
|
|
|
|
:date: 15.5.2024
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Alt werden mit C++
|
|
|
|
|
------------------
|
|
|
|
|
|
2024-05-17 16:49:36 +02:00
|
|
|
Langlebige Software.
|
|
|
|
|
Software lebt solange sie änderbar ist.
|
|
|
|
|
OpenSource-Software muß von sich aus am Leben bleiben.
|
|
|
|
|
|
|
|
|
|
Projekt Lumiera als Beispiel für ein ambitioniertes Projekt, das auf Langlebigkeit abstellt.
|
|
|
|
|
|
|
|
|
|
Entscheidung für eine Plattform ist im Kern eine Entscheidung für ein Ökosystem.
|
|
|
|
|
Ein langlebiges Projekt muß auf Autonomie und Handlungsfähigkeit achten.
|
|
|
|
|
Daher scheiden die meisten zunächst offensichtlichen und beliebten Plattformen aus.
|
|
|
|
|
|
|
|
|
|
Für Lumiera hat man sich damals für C++ in einem Unix-Umfeld entschieden.
|
|
|
|
|
Realistische andere Optionen wären noch gewesen: D, Java, plain-C, Haskell.
|
|
|
|
|
Einmal getroffen, ist eine solche Entscheidung mehr oder weniger endgültig.
|
|
|
|
|
Denn jede der großen Programmiersprachen steht auch für eine bestimmte
|
|
|
|
|
Denkhaltung und Herangehensweise.
|
|
|
|
|
|
|
|
|
|
Der Charakter jeder Sprache, und die damit verbundenen Methoden entwickeln sich weiter.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Nachfolgend sei dies am Beispiel der Erfahrungen im Projekt Lumiera mit der Sprache C++
|
|
|
|
|
nachgezeichnet, exemplarisch anhand zentraler Entwicklungslinien.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Software bleibt nur änderbar, wenn sie mit den beschränkten menschlichen Fähigkeiten
|
|
|
|
|
im Einklang ist. Das gilt, sofern Software von Menschen und für Menschen gebaut wird.
|
|
|
|
|
Die wichtigste Beschränkung liegt dabei in der Fähigkeit, die Folgen von Änderungen
|
|
|
|
|
zu verstehen und zu beherrschen. Das wird ermöglicht durch den sachgemäßen Ansatz
|
|
|
|
|
von Abstraktionen.
|
|
|
|
|
|
|
|
|
|
Durch einen Interface-Kontrakt wird die Implementierung zum Detail, und damit lokal
|
|
|
|
|
änderbar. Sprachmittel: Vererbung. Tendentiell problematisch, aber gut verstanden
|
|
|
|
|
und weitgehend stabil. Tendenz: zunehmende Betonung von Modularität in Kontrakten,
|
|
|
|
|
realisiert als Mix-in
|
|
|
|
|
|
|
|
|
|
Schwachstelle von Kontrakten: man muß das Verhalten festlegen. Damit dringt man in
|
|
|
|
|
die Implementierung ein und braucht entsprechende Ausdrucksmittel. Der vorherrschende
|
|
|
|
|
Ansatz hierfür war in den letzten 20 Jahren die Trennung von Infrastruktur und Funktionalität.
|
|
|
|
|
Ein Stück Funktionalität wird zu einem abstrakten Element, das in einen Kontrakt eingebunden
|
|
|
|
|
werden kann.
|
|
|
|
|
|
|
|
|
|
Die Sprachmittel in C++ waren dafür wenig geeignet und problematisch: im Grunde haben wir
|
|
|
|
|
bis heute nur Funktions-Pointer. Jedoch hat C++ durch seine Klassen und das Typsystem eine
|
|
|
|
|
ausgeprägte Stärke im Bauen neuer Abstraktionen. Die Boost-Libraries haben daraus ein neues
|
|
|
|
|
Sprachmittel geschaffen: Funktions-Objekte.
|
|
|
|
|
|
|
|
|
|
In der Praxis war der Weg dorthin mühsam und erforderte viele work-arounds. Das führt dazu,
|
|
|
|
|
daß im bestehenden Code eine Menge von Hilfsmitteln entsteht, die aufeinander aufbauen und
|
|
|
|
|
weithin im Einsatz sind. Und dann kam C++11 mit einem neuen Sprachmittel: den Lambda-Ausdrücken.
|
|
|
|
|
Diese stehen gleichberechtigt neben den Funktionsobjekten.
|
|
|
|
|
Unterschiede Funktions-Objekt vs Lambda.
|
|
|
|
|
|
|
|
|
|
Die Entkopplung von Infrastruktur und Funktionalität führt dazu, daß zunehmend auch die
|
|
|
|
|
Operationen von den Daten entkoppelt werden müssen. Ein Funktions-Objekt, das gut per Kontrakt
|
|
|
|
|
in eine Infrastruktur eingebunden ist, könnte viele weitere Anwendungen abdecken, wenn man es
|
|
|
|
|
von den konkreten Argument-Daten abstrahieren könnte. So entsteht die Forderung nach Funktionen
|
|
|
|
|
auf generischen Argumenten.
|
|
|
|
|
|
|
|
|
|
Auch hierfür waren die vorhandenen Sprachmittel unzulänglich, und ziemlich clevere Tricks kamen
|
|
|
|
|
flächendeckend zum Einsatz: vor allem die partielle Spezialisierung von Templates.
|
|
|
|
|
Draus entsteht in einer größeren Code-Basis eine interne Binding-Schicht, die erhebliche
|
|
|
|
|
Probleme bei der Wartung aufwirft.
|
|
|
|
|
|
|
|
|
|
Währenddessen entwickelte sich die Sprache weiter. Mithilfe der RValue-References wurde das
|
|
|
|
|
transparente Durchreichen von Argumenten möglich. Die hierfür notwendigen semantischen Anpassungen
|
|
|
|
|
sind subtil und tückisch. Eine schrittweise Umstellung einer großen Codebasis ist ein langlaufender
|
|
|
|
|
Vorgang und eine organisatorische Herausforderung.
|
|
|
|
|
|
|
|
|
|
Oft muß man aber Argumente nicht nur durchreichen, sondern eine generische Funktion muß
|
|
|
|
|
Eigenschaften ihrer Argumente verstehen und sich daran anpassen können. In den meisten älteren
|
|
|
|
|
Programmiersprachen scheitert an dieser Forderung die gesamte Weiterentwicklung in Richtung einer
|
|
|
|
|
Funktions-Abstraktion. Zum Glück (oder leider) galt das nicht für C++, denn während der Standardisierung
|
|
|
|
|
der Sprache sind einige Design-Unfälle passiert, deren anfangs gar nicht intendiertes Verhalten in
|
|
|
|
|
den Compilern dazu verwendet werden konnte, diese »Schallmauer« zu durchbrechen. Gemeint ist die
|
|
|
|
|
Template-Metaprogamierung, eine Art »schwarze Magie«, mit der man eine funktionale Hilfs-Sprache
|
|
|
|
|
während dem Compilier-Prozess ausführen lassen kann.
|
|
|
|
|
|
|
|
|
|
Warum läßt man sich auf schwarze Magie ein? Antwort: weil man dadurch mächtiger wird.
|
|
|
|
|
Die Sprachmittel werden ausdrucksstärker. Mit wenigen Zeilen Code kann man eine komplexe
|
|
|
|
|
Funktionalität zuverlässig und sicher realisieren. Dadurch gewinnt man Zeit, über die eigentlichen
|
|
|
|
|
Anforderungen nachzudenken. Man geht damit aber technische Schulden ein: der Umgang mit der
|
|
|
|
|
Codebasis erfordert vertiefte Kenntnisse, und einen mathematisch-geprägten Denkstil.
|
|
|
|
|
|
|
|
|
|
Trotzdem war diese Entwicklung derart enorm erfolgreich, daß das C++ - Komittee ihr
|
|
|
|
|
gefolgt ist, und die Aufgabe angenommen hat, die historisch gewachsene schwarze Magie in
|
|
|
|
|
klar definierte und sauber verwendbare Sprachmittel inkrementell weiter zu entwickeln.
|
|
|
|
|
|
|
|
|
|
- Varidadics
|
|
|
|
|
- Concepts
|
|
|
|
|
|
|
|
|
|
Wenn man diese Aufgabe ernst nimmt, darf man sich nicht damit begnügen, einen pragmatischen Gebrauch
|
|
|
|
|
zu codifizieren und syntaktisch nett zu verpacken. Vielmehr sind neue Sprachmittel gefordert, die
|
|
|
|
|
sich zwar in den Stil der Sprache nahtlos einfügen, und auch das gleiche leisten wie die pragmatisch
|
|
|
|
|
gewachsene Lösung, aber dennoch auf einer neuen Basis stehen, klar definiert und leichter korrekt
|
|
|
|
|
verwendbar sind. Das ist eine sehr anspruchsvolle Aufgabe; das Ergebnis ist erstaunlich, hat aber
|
|
|
|
|
auch sehr lange gedauert und ist in einigen Teilaspekten immer noch unfertig.
|
|
|
|
|
|
|
|
|
|
Das bedeutet: man muß lange Zeit mit einer Mischung aus magischen Lösungen und der neuen
|
|
|
|
|
Standard-Lösung leben. Beide koexistieren, sind aber untereinander nicht kompatibel, obgleich
|
|
|
|
|
sie beide den gleichen Zweck erfüllen. Das erzeugt eine schwierige Situation in einer großen
|
|
|
|
|
Codebasis: zusammenhängende Systeme ziehen sich über weite Strecken durch den Code, und
|
|
|
|
|
stützen sich jeweils auf eine Menge von Hilfsmitteln ab, die untereinander nicht austauschbar
|
|
|
|
|
sind.
|
|
|
|
|
|
|
|
|
|
Beispiele
|
|
|
|
|
- Loki-Typlisten vs. Variadic Arguments
|
|
|
|
|
- Type-Traits vs. Concepts
|
|
|
|
|
|
2024-05-16 18:30:51 +02:00
|
|
|
|