Neue Sprachen braucht die Welt (Teil 4)
Kommentare

Dynamische Programmierung
Auch bei der dynamischen Programmierung handelt es sich aus Sicht von .NET um ein Spezialgebiet, das mit den „alten“ Sprachen bisher kaum angetastet wurde. Ähnlich der funktionalen

Dynamische Programmierung

Auch bei der dynamischen Programmierung handelt es sich aus Sicht von .NET um ein Spezialgebiet, das mit den „alten“ Sprachen bisher kaum angetastet wurde. Ähnlich der funktionalen Programmierung ist es auch hier schwer, fokussierte Beispiele zu zeigen, und viele dynamische Sprachen interpretieren „Dynamik“ unterschiedlich. (Iron)Python ist eine Sprache mit dynamischer Typisierung, in der alle Typen erst zur Laufzeit festgestellt werden. Die anderen beschriebenen Sprachen sind alle (weitgehend) statisch typisiert. In F# ist das nicht immer offensichtlich, da die Typherleitung des Compilers so mächtig ist, dass Typen nur selten explizit angegeben werden müssen – trotzdem werden sie immer hergeleitet, wenn der Compiler das ausführbare Programm erzeugt, so dass auch F# eine statisch typisierte Sprache ist. Visual Basic hat als einzige Sprache in diesem Vergleich ein Feature, das an dynamische Programmierung erinnert. Es unterstützt late binding (späte Bindung), wie in diesem Beispiel:

Dim lateBoundDog As Object

lateBoundDog = New Dog()

lateBoundDog.Sleep()

lateBoundDog.Bark()

Sobald der Typ der Variablen als Object angegeben wird, geht Visual Basic von der Verwendung von late binding aus. Der Compiler prüft nicht, ob die Methoden Sleep und Bark tatsächlich verfügbar sind, stattdessen werden diese zur Laufzeit gesucht und hoffentlich gefunden. In dem Beispiel ist die Methode Bark nicht verfügbar und es wird eine Exception ausgelöst.

Wer sich bindet …

Traditionelle (auf der .NET-Plattform) Anwendungen für diese Techniken sind die Automatisierung mittels COM oder der Zugriff auf Webservices. Dabei wird das COM-Interface IDispatch für die Namensauflösung eingesetzt, so dass auf dieser Basis der Mechanismus auch erweiterbar ist – natürlich nur, sofern COM-Komponenten geschrieben werden. In Python ist late binding der „normale“ Weg, da die Sprache Namensauflösung generell zur Laufzeit durchführt (der Fachbegriff lautet dynamic dispatch). Es ist sehr einfach, dynamisch nachschlagbare Elemente selbst zu Klassen hinzuzufügen, und auf dieser Basis werden oft APIs entwickelt, die sich in statischen Sprachen nicht erzeugen ließen. Auf der Basis von IronPython hat die Firma Resolver Systems das Programm Resolver One entwickelt, bei dem es sich um eine Spreadsheet-Anwendung handelt. Ein Spreadsheet hat natürlich Zellen, und eine Methode des Zugriffs darauf ist das aus Excel bekannte System, Spalten mit Buchstaben und Zeilen mit Zahlen zu nummerieren. Wie würde in einer statischen Sprache also der Code zum Zugriff auf die Zelle A1 aussehen? Hier einige denkbare Varianten:

Cells[0, 0] = new Cell( ... )

Cells["A1"] = "..."

Cells[Columns.A][1] = ...

In Python ist dies hingegen durch die Anwendung von dynamic dispatch viel einfacher:

Cells.A1 = ...

Natürlich gibt es nicht wirklich ein Element namens A1 in dem Objekt Cells – dann müsste es ja unendlich viele andere solche Elemente geben. Stattdessen wird der Mechanismus erweitert, um den direkten Zugriff auf alle Zellen mit solcher Syntax zu ermöglichen. Listing 7 zeigt eine IronPython-Klasse, die dynamisch auf bestimmte Elementnamen reagieren kann. Das Beispiel ist auf das Notwendigste reduziert, zeigt aber, wie unbekannte Elementnamen ausgewertet und ungültige Namen zurückgemeldet werden. Das Beispiel erzeugt die folgende Bildschirmausgabe:

Returning secret value for number 1

Setting secret value for number 3

Traceback (most recent call last):

File Program.py, line 52, in Initialize

AttributeError: 'instance' object has no attribute 'SomethingElse'

def GetSecretNumber(name):
  if name.startswith('Secret'):
    return int(name[6:])
  return None

class Dynamic:
  def __getattr__(self, name):
    number = GetSecretNumber(name)
    if number is None:
      raise AttributeError(name)
    return 'Returning secret value for number ' + 'number'
    
  def __setattr__(self, name, value):
    number = GetSecretNumber(name)
    if number is None:
      raise AttributeError(name)
    print 'Setting secret value <' + 'value' + '> for number ' + 'number'

dyn = Dynamic()
print dyn.Secret1
dyn.Secret3 = 42
print dyn.SomethingElse  

Listing 7

Dynamische Aussichten

In C# 4.0 wird es einige Spracherweiterungen geben, die ähnliche Techniken ermöglichen. Auf der einen Seite wird das Schlüsselwort dynamic eingeführt, das die Deklaration einer Variablen als dynamisch ermöglicht. Auf der anderen Seite gibt es das Interface IDynamicObject sowie die abstrakte Basisklasse DynamicObject. Mit diesen beiden Neuerungen wird es einfacher, auf bestehende dynamische Typen zuzugreifen sowie eigene zu erzeugen. Microsoft hat dabei weniger eine Entwicklung von C# in Richtung einer dynamischen Sprache im Sinn als vielmehr eine verbesserte Interaktion mit der DLR (dynamic language runtime), die als Basis der dynamischen Sprachen für .NET dient. Die Zeit wird zeigen, ob dies auch Neuerungen in APIs für die Verwendung in den statischen Sprachen nach sich ziehen wird. Heute gibt es bereits viele Librarys, die Reflection zu Zwecken einsetzen, die in Zukunft mithilfe der dynamischen Features umgesetzt werden können, so dass eine solche Entwicklung sicherlich in gewissen Bereichen anzunehmen ist.

Oliver Sturm lebt in Schottland, arbeitet für Developer Express und ist Microsoft MVP für C#. Sie können ihn per E-Mail erreichen und seinen Blog finden Sie auf sturmnet.org.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -