2024-05-23 20:23:35 +02:00
|
|
|
Antrag für einen Vortrag auf der FrOSCon 24
|
|
|
|
|
===========================================
|
2024-05-23 18:36:42 +02:00
|
|
|
:author: Ichthyostega
|
2024-05-23 20:23:35 +02:00
|
|
|
:date: 23.5.2024
|
2024-05-23 18:36:42 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
Alt werden mit C++
|
|
|
|
|
------------------
|
|
|
|
|
|
2024-05-23 20:23:35 +02:00
|
|
|
Kurzfassung
|
|
|
|
|
~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Für eine langlebige Codebasis ist der Charakter und die weitere Entwicklung der einmal gewählten
|
|
|
|
|
Programmiersprache bedeutsam. Dies wird verdeutlicht anhand von Beispielen und Erfahrungen im Projekt
|
|
|
|
|
Lumiera mit der Sprache C++. Diese Sprache bietet Abstraktionsmittel, die sehr hilfreich sein können,
|
|
|
|
|
in einer großen und komplexen Codebasis die Flexibilität und Änderbarkeit zu erhalten. Allerdings tritt
|
|
|
|
|
die schrittweise Evolution dieser Sprachmittel in Wechselwirkung mit der Entwicklung der Codebasis und
|
|
|
|
|
erzeugt Wartungsprobleme. Dies wird beleuchtet am Beispiel von Lambdas und Funktoren, der Einführung
|
|
|
|
|
von RValue-Referenzen, sowie der Entwicklung von Generics und Concepts.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Langfassung
|
|
|
|
|
~~~~~~~~~~~
|
2024-05-23 18:36:42 +02:00
|
|
|
|
|
|
|
|
Software lebt solange sie änderbar ist.
|
|
|
|
|
Für langlebige Software ist der Charakter der Programmiersprache bedeutsam. Der Charakter jeder Sprache,
|
|
|
|
|
und die damit verbundenen Methoden entwickeln sich weiter. Daraus entsteht eine Wechselwirkung mit einer
|
|
|
|
|
bestehenden Codebasis, die sich ebenfalls weiterentwickelt.
|
|
|
|
|
|
|
|
|
|
Exemplarisch sei dies am Beispiel der Erfahrungen im Projekt Lumiera mit der Sprache C++ nachgezeichnet.
|
|
|
|
|
In diesem OpenSource-Projekt wird Software für professionellen Film/Videoschnitt entwickelt.
|
|
|
|
|
|
2024-05-23 20:23:35 +02:00
|
|
|
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.
|
2024-05-23 18:36:42 +02:00
|
|
|
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.
|
|
|
|
|
|
|
|
|
|
Software bleibt nur änderbar, wenn sie mit den beschränkten menschlichen Fähigkeiten
|
|
|
|
|
im Einklang steht. 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
|
2024-05-23 20:23:35 +02:00
|
|
|
änderbar. Für einen Kontrakt muß aber auch das Verhalten festgelegt werden. Damit dringt
|
|
|
|
|
die Abstraktion in die Implementierung ein, und erfordert entsprechende Ausdrucksmittel.
|
|
|
|
|
Der vorherrschende Lösungsansatz 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
|
|
|
|
|
anderweitig geregelten Kontrakt eingebunden werden kann. Einmal etabliert, könnte ein solches
|
|
|
|
|
Schema oft an weiteren Stellen angewendet werden, sofern man auch noch von den konkreten
|
|
|
|
|
Funktionsargumenten abstrahieren könnte. So entsteht die Forderung nach Funktionen
|
2024-05-23 18:36:42 +02:00
|
|
|
auf generischen Argumenten.
|
|
|
|
|
|
2024-05-23 20:23:35 +02:00
|
|
|
In der Praxis war der Weg dorthin mühsam und erforderte viele Workarounds. Die Sprachmittel in C++
|
|
|
|
|
waren dafür anfangs wenig geeignet und problematisch: im Grunde gab es nur die schon in C nutzbaren
|
|
|
|
|
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. Mit C++11 wurden diese auch Teil der Sprachdefinition; zugleich jedoch wurden
|
|
|
|
|
auch Lambda-Ausdrücke als neues Sprachmittel eingeführt. Beide Sprachmittel stehen nun gleichberechtigt
|
|
|
|
|
nebeneinander und ermöglichen völlig neue Anwendungsmuster. Und die Sprache entwickelte sich 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.
|
2024-05-23 18:36:42 +02:00
|
|
|
|
|
|
|
|
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 in der Praxis derart erfolgreich, daß das C++ - Komittee ihr
|
|
|
|
|
gefolgt ist, und die Aufgabe übernommen hat, die historisch gewachsene schwarze Magie in
|
|
|
|
|
klar definierte und sauber verwendbare Sprachmittel inkrementell weiter zu entwickeln.
|
|
|
|
|
|
2024-05-23 20:23:35 +02:00
|
|
|
- Varidadische Ausdrücke
|
2024-05-23 18:36:42 +02:00
|
|
|
- Concepts
|
|
|
|
|
|
2024-05-23 20:23:35 +02:00
|
|
|
Wenn man diese Aufgabe ernst nimmt, kann man sich nicht damit begnügen, einen pragmatischen Gebrauch
|
2024-05-23 18:36:42 +02:00
|
|
|
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 historisch
|
|
|
|
|
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
|
2024-05-23 20:23:35 +02:00
|
|
|
auch sehr viel Zeit in Anspruch genommen und ist in manchen Teilaspekten immer noch unfertig.
|
2024-05-23 18:36:42 +02:00
|
|
|
|
2024-05-23 20:23:35 +02:00
|
|
|
Diese schrittweise Weiterentwicklung der Sprache führt dazu, daß im bestehenden Code eine Menge von Hilfsmitteln
|
|
|
|
|
entsteht, die aufeinander aufbauen und weithin im Einsatz sind. Jedoch sind die Lösungen aus verschiedenen
|
|
|
|
|
Entwicklungsstadien untereinander oft nicht kompatibel, da sich die gesamte Herangehensweise geändert hat.
|
|
|
|
|
In einer größeren Code-Basis entstehen so komplexe interne Binding-Schichten, die erhebliche Probleme
|
|
|
|
|
bei der Wartung aufwerfen können: zusammenhängende Systeme ziehen sich über weite Strecken durch den Code,
|
|
|
|
|
und stützen sich jeweils auf Hilfsmittel ab, die untereinander nicht austauschbar sind.
|
2024-05-23 18:36:42 +02:00
|
|
|
|
2024-05-23 20:23:35 +02:00
|
|
|
Beispiele hierfür sind:
|
2024-05-23 18:36:42 +02:00
|
|
|
- Loki-Typlisten vs. Variadic Arguments
|
|
|
|
|
- Type-Traits vs. Concepts
|
|
|
|
|
|
|
|
|
|
Da die jeweiligen Alternativen den gleichen Zweck auf unterschiedlichem Weg erreichen, kann eine
|
2024-05-23 20:23:35 +02:00
|
|
|
Umstellung herausfordernd sein und läuft auf eine großflächige Überarbeitung etablierter Infrastrukturen
|
2024-05-23 18:36:42 +02:00
|
|
|
hinaus. Daraus erwächst aber auch die Chance, in der Codebasis weithin etablierte Lösungen
|
|
|
|
|
zu hinterfragen und weiterzuentwickeln.
|
|
|
|
|
|