Dynamische Programmierung unter .Net
Seite 5: Dynamische Softwareentwicklung
Dynamische Sprachen
Dynamische Softwareentwicklung
Für den Begriff „dynamische Programmiersprachen“ gibt es im Netz die unterschiedlichsten Definitionen. Die meisten Quellen sind sich einig, dass Ruby, Python oder Basic dazugehören. Auch der Begriff Script-Sprachen wird oft im selben Atemzug genannt. Was aber nun eine dynamische Programmiersprache von anderen genau unterscheidet, ist nicht exakt festzumachen. Die einzige Grundaussage, auf die sich alle einigen können, ist, dass dies Sprachen sind, die bestimmte Dinge erst zur Laufzeit tun, wie Variablen binden oder Ähnliches, was bei anderen schon beim Kompilieren passiert.
Um diese Sprachen etwas genauer eingrenzen zu können, hat Ed Johnson auf seiner Website drei Eigenschaften herausgearbeitet, die die meisten besitzen; manche aber auch wieder nicht:
- dynamische Typisierung,
- Ändern oder Erzeugen von Programmbestandteilen,
- interpretierend – kein Compiler.
Typisierung: Durch die Typisierung ordnet eine Programmiersprache ihre Bestandteile in bestimmte Gruppen ein. Variablen sind einem bestimmten Typ zugeordnet. Objekte gehören zu einer Klasse. Der Sinn dieses ganzen Aufwands liegt ganz klar in der Vermeidung von Fehlern. Dass ein Aufaddieren von Integerzahlen mit Zeichenkette nicht gut gehen kann, wird erkannt, bevor der Speicher überläuft.
Bei der Einordnung des Typsystems einer Programmiersprache gibt es grundsätzlich drei Kriterien:
- Stärke der Typisierung (stark – schwach),
- Dynamik der Typisierung (dynamisch – statisch),
- Explizität der Typisierung (explizit – implizit).
Eine Programmiersprache ist stark typisierend, wenn sie auf die Unterscheidung der Typen achtet und diese kontrolliert. Im klassischen C kann ein Programmierer mit einem Zeiger als Parameter jeden beliebigen Datentyp übergeben oder zur Laufzeiten mit Casting jeden Typ in einen anderen umdeklarieren. Ein klassischer C-Compiler prüft nicht, ob das sinnvoll ist, was früher häufig zu den Speicherüberläufen führte. C ist damit eine schwach typisierende Sprache, was eher den dynamischen Sprachen wie Python nachgesagt wird. Python hingegen prüft sehr stark, ob die Typen zur Laufzeit zusammenpassen. Ein entscheidendes Merkmal für ein dynamisches Typsystem ist, dass die Typen zur Laufzeit festgelegt werden können und nicht nur bei der Kompilierung, wie es bei statischen Systemen üblich ist.
Was eigentlich nichts mit einem dynamischen Typsystem zu tun hat, ist die Frage, ob eine explizite oder eine implizite Typdefinition möglich ist. Bei der expliziten Vorgehensweise muss der Programmierer, bevor er einer Variablen einen Wert zuweisen kann, diese erst deklarieren, bei der impliziten definiert die erste Zuweisung einer Variablen den Typ. Übrigens: Dieses Feature gibt es jetzt auch in den mit Visual Studio 2008 ausgelieferten Versionen von C# und VB.Net für lokale Variablen.
Programmänderung zur Laufzeit: Das sich ein Programm noch zur Laufzeit durch den Entwickler oder womöglich durch das Programm selbst ändert, klingt im ersten Moment etwas exotisch. Doch es gibt dafür einige sinnvolle Anwendungen. Kann erst das Laufzeitsystem feststellen, welche externe Schnittstelle eine bestimmte Klasse benötigt, ist es keine Magie, die Schnittstellen-Klasse erst dann zu erzeugen.
Ein ähnliches Thema sind SQL-Statements, die eine Programmroutine erst bei der Anwendung vervollständigt. In vielen Programmiersprachen kann dies der Entwickler nur mit Zeichenketten bewältigen, da das Statement nicht zur Laufzeit in Objekte und Methoden umgewandelt werden kann.
Interpreter: Das Gegensatzpaar Compiler vs. Interpreter gibt es in der Informatik immer seltener. Der klassische Compiler, der alles zur Laufzeit in festen Maschinencode übersetzt, ist eine aussterbende Spezies. Moderne Programmiersprachen, ob Java, C# oder Python, arbeiten mit Zwischencode, der zur Laufzeit von einem Just-in-time-Compiler übersetzt oder gleich von einer virtuellen Maschine – einem Interpreter – abgearbeitet wird.