K09.1 Dynamische Programmiersprachen thorsten möller -­‐ informa=k.unibas.ch/lehre/fs14/cs109/09-­‐dyn&dsls.pdf 23. Mai 2014 2 Dynamische Programmiersprachen n
n
Der Begriff Dynamischen Programmiersprache ist nicht präzise bzw. formal definiert. Typischerweise versteht man darunter Sprachen ... n
... bei denen zur Laufzeit Tä=gkeiten ausgeführt werden, die bei „sta=schen Sprachen“* zur Compilezeit ausgeführt werden, z.B.: n
n
n
n
n
n
Dynamische Typüberprüfung Dynamische Bes=mmung des Typs anhand struktureller EigenschaWen Modifika=on von Programmen zur Laufzeit ... die Interpre=ert ausgeführt werden (Skriptsprachen) ... die automa=sche Speicherverwaltung anbieten Mo=va=on: n
n
Produk=vität bei der Programmierung erhöhen und/oder Erlernbarkeit der Programmiersprache vereinfachen * Auch dieser Begriff ist nicht präzise definiert. thorsten möller -­‐ informa=k.unibas.ch/lehre/fs14/cs109/09-­‐dyn&dsls.pdf 23. Mai 2014 1 3 Dynamische Typüberprüfung n
Typüberprüfung erfolgt zur Laufzeit (im Gegensatz zur sta=schen Typprüfung zur Compilezeit). n
n
(i) Vertreter: Groovy, JavaScript, Lisp, Lua, Perl, PHP, Ruby, Python, ... Charakteris=sche EigenschaW: 1. Werte/Objekte haben Typ n
Ergo: Typinforma=on muss zusätzlich mit dem Wert/Objekt geführt werden 2. Variablen haben keinen Typ n
Ergo: Variable kann während ihrer Lebenszeit Werte beliebigen Typs annehmen à Es können weniger bis gar keine Garan=en zur Typkompa=bilität zur Laufzeit gegeben werden. thorsten möller -­‐ informa=k.unibas.ch/lehre/fs14/cs109/09-­‐dyn&dsls.pdf 23. Mai 2014 4 Dynamische Typüberprüfung n
(ii) Nachteile: n
n
Typüberprüfung zur Laufzeit hat gewissen Aufwand (Overhead). Laufzeieehler durch Typinkompa=bilitäten. n
n
AuWretens-­‐ und Ursacheort im Quelltext u.U. weit voneinander eneernt Erhöhter Testaufwand; volle Abdeckung aller möglichen Ausführungen aber oW nicht mit sinnvollem Aufwand machbar. thorsten möller -­‐ informa=k.unibas.ch/lehre/fs14/cs109/09-­‐dyn&dsls.pdf 23. Mai 2014 2 5 Duck Typing
n
(i) Idee: Ein Objekt ist kompa=bel zu einem Typ T wenn es zur Laufzeit die Methoden (und Ajribute) von T besitzt. n
n
Analog: zwei Objekte sind typkompa=bel wenn sie zur Laufzeit gleiche Methoden (und Ajribute) besitzen. Ergo: Objekt muss im Grunde genommen überhaupt keinen sta=schen Typ besitzen. Der Typ wird dynamisch (zur Laufzeit) anhand seiner Struktur, nämlich der vorhandenen Methoden (und Ajribute), bes=mmt. Name geht zurück auf ein Gedicht von J.W. RILEY: „When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.“ thorsten möller -­‐ informa=k.unibas.ch/lehre/fs14/cs109/09-­‐dyn&dsls.pdf 23. Mai 2014 6 Duck Typing
(ii) Beispiel (Python): class Vogel: def __init__(self, name): self.name = name def __str__(self): return self.__class__.__name__ + ' ' + self.name class Ente(Vogel): def quak(self): print str(self)+': quak' class Frosch: def quak(self): print str(self)+': quak' tiere = [Vogel('Gustav'), Ente('Donald'), Frosch('Kermit')] for t in tiere: try: t.quak() except AttributeError: print 'Kann nicht quaken:', t Ausgabe: Kann nicht quaken: Vogel Gustav Ente Donald: quak Frosch Kermit: quak 23. Mai 2014 thorsten möller -­‐ informa=k.unibas.ch/lehre/fs14/cs109/09-­‐dyn&dsls.pdf 3 7 Duck Typing – Gegenüberstellung (iii) n
n
Duck Typing ist dynamische Form des Structural Typing. Bei letzterem wird Typkompa=bilität i. Allg. sta=sch zur Compilezeit bes=mmt. Die Typsysteme der bisher in der Vorlesung behandelten Sprachen (C++, Java, Haskell) sind nomina=v: n Typkompa=bilität bzw. -­‐äquivalenz bes=mmt durch explizite Typdeklara=onen und/oder Typnamen. // explizite Deklaration äquivalenter // Typen durch Typaliase in C++ // unterschiedliche Typen in C++ // mit identischer Struktur typedef unsigned char BYTE; struct Foo { int id; char name[80]; -­‐-­‐ explizite Deklaration äquivalenter -­‐-­‐ Typen durch Typsynonyme in Haskell type String = [Char]; }; struct Bar { int id; char name[80]; }; thorsten möller -­‐ informa=k.unibas.ch/lehre/fs14/cs109/09-­‐dyn&dsls.pdf 23. Mai 2014 8 Mixins n
n
(i) Idee: Ein Mixin deklariert und definiert eine Menge von Methoden die man (zur Laufzeit) beliebig vielen Klassen hinzufügt – „beimischt“. Direkt unterstützt u.a. in: Go, Ruby, Scala Beispiel (Ruby): # Mixin das Logging-­‐Methoden bereitstellt # Verwendung module Logging class Foo def logInfo # Methode für Info-­‐Ausgabe include Logging # Implementierung ... # ... end end def logErr # Methode für Fehler-­‐Ausgabe class Bar # Implementierung ... include Logging end # ... end end thorsten möller -­‐ informa=k.unibas.ch/lehre/fs14/cs109/09-­‐dyn&dsls.pdf 23. Mai 2014 4 9 Mixins n
n
(ii) Keine Form der Spezialisierung (Vererbung) sondern ein Mijel um Funk=onalität (dynamisch) einer Klasse hinzuzufügen. Mo=va=on: don‘t repeat yourself (dry) Vergleichbar mit: n
Mehrfachvererbung: Klasse kann (alle) Methoden über ein oder mehrere Mixins erhalten. n
n
Unterschied: eliminiert Probleme des mehrfachen erbens von Methoden (A sub B,C sub D; siehe auch virtuelle Mehrfachvererbung in C++) Java Interface n
n
Konzept in der objektorien=erten Programmierung: n
n
Unterschied: Methoden sind implemen=ert. Manche Sprachen ermöglichen das „beimischen“ von Methoden in eine Klasse zur Laufzeit, wobei Mixins selbst zur Compilezeit definiert sind. Dies entspricht einem late binding. thorsten möller -­‐ informa=k.unibas.ch/lehre/fs14/cs109/09-­‐dyn&dsls.pdf 23. Mai 2014 10 Metaprogrammierung – eval n
Mit Lisp wurde erstmalig die Möglichkeit eingeführt ein in ein Programm als Daten eingebejetes Programmfragment p (welches in derselben Sprache geschrieben ist) auszuwerten und das Ergebnis zurückzuliefern (Ausdruck) bzw. auszuführen (Anweisung(en)). n
Auswertung/Ausführung von p entweder zur: n
n
n
n
n
Sta=sche Metaprogrammierung z.B.: C/C++ Makros und C++ Templates Dynamische Metaprogrammierung Benö=gt eine Evaluierungsfunk=on: eval(p)
n
n
Compilezeit:
Laufzeit: p liegt in Form von Daten für eval vor. Auswertung zur Laufzeit meist interpre=ert; kompilierte Auswertung benö=gt Zugriff auf den Compiler durch das ausführbare Programm. Auswertung zur Laufzeit verfügbar u.a. in Lua, Perl, Python, Ruby. Syntax bzgl. eval variiert zwischen den Programmiersprachen; z.B. implizite Kennzeichnung durch Präfix # bei C/C++ Makros. thorsten möller -­‐ informa=k.unibas.ch/lehre/fs14/cs109/09-­‐dyn&dsls.pdf 23. Mai 2014 5 11 eval -­‐ Beispiele Java Script: Perl: // Auswertung eines Ausdrucks x = 3; alert(eval('x + 3')); // Ausführung von Anweisungen x = 3; eval('x += 3; alert(x);'); // Auswertung eines Ausdrucks $x = 3; print eval('$x + 3'), "\n"; // Ausführung von Anweisungen $x = 3; eval('$x += 3; print "$x\n";'); Python (interak=ver Modus >>>): >>> # Auswertung eines Ausdrucks >>> x = 3 >>> eval('x + 3') 6 >>> x = 3 >>> y = 4 >>> exec "x += 3; y += 4" >>> x 6 >>> y 8 thorsten möller -­‐ informa=k.unibas.ch/lehre/fs14/cs109/09-­‐dyn&dsls.pdf 23. Mai 2014 12 eval und Quines n
eval lässt sich verwenden um sogenannte Quines zu implemen=eren: n
n
Eine Quine ist eine Spezialform von Metaprogrammen. Defini=on: Ein Quine ist ein Programm dass keine Eingaben hat und bei Ausführung exakt seinen eigenen Quelltext ausgibt. Beispiel (Ruby): eval s=%q(puts"eval s=%q(#{s})") Ausprobierbar ohne dass man eine Ruby-­‐Laufzeitumgebung Installieren muss auf hjp://codepad.org/ thorsten möller -­‐ informa=k.unibas.ch/lehre/fs14/cs109/09-­‐dyn&dsls.pdf 23. Mai 2014 6 13 Metaprogrammierung – Dynamische Programmodifika=on n
Ebenfalls mit Lisp wurde erstmalig die Möglichkeit eingeführt dass ein Programm sich selbst zur Laufzeit modifiziert. n
Programm benutzt sich selbst als Daten. Durch Modifika=on dieser Daten kann es sich selbst modifizieren. Demzufolge erfolgt keine Unterscheidung mehr zwischen Programm und Daten. thorsten möller -­‐ informa=k.unibas.ch/lehre/fs14/cs109/09-­‐dyn&dsls.pdf 23. Mai 2014 14 Dyn. Programmänderung – Beispiel n
Hinzufügen einer neuen Methode zu einer Klasse und Ausführung dieser (Ruby): class Foo # initiale Definition der Klasse ... end # füge neue Methode 'hello' zur Klasse 'Foo' hinzu Foo.class_eval("def hello; return 'hello'; end”) # erzeuge neue Instanz und führe 'hello' aus Foo.new.hello n
Ähnlich kann man mit remove_method in Ruby eine Methode mC einer Klasse C zur Laufzeit eneernen. Beachte: hat mC jedoch mSup
einer Superklasse Sup überschrieben, dann kann danach immer noch mSup auf Instanzen C von aufgerufen werden (da ererbt). thorsten möller -­‐ informa=k.unibas.ch/lehre/fs14/cs109/09-­‐dyn&dsls.pdf 23. Mai 2014 7 K09.2 Domänenspezifische Programmiersprachen thorsten möller -­‐ informa=k.unibas.ch/lehre/fs14/cs109/09-­‐dyn&dsls.pdf 23. Mai 2014 16 Unterscheidung n
Alle bisher betrachteten Sprachen zählen zu den „general purpose“ Sprachen: sie sind universell, d.h. für jegliche Programmieraufgaben (mehr oder weniger gut) benutzbar. n
n
Programmiersprachen sind nicht per se gut oder schlecht; sie sind nur mehr oder weniger gut geeignet für einen bes=mmten Zweck. Eine domänenspezifische Sprache (DSL) ist für einen bes=mmten Problembereich entworfen. n
n
Ziel: durch Domänenexperten ohne Zusatzwissen nutzbar: „weniger technisch“. Beispiele für Nicht-­‐Ziele – als bewusste Designentscheidung: n
n
Turing-­‐Vollständigkeit Ausführbarkeit – Modellierungssprachen wie z.B. UML thorsten möller -­‐ informa=k.unibas.ch/lehre/fs14/cs109/09-­‐dyn&dsls.pdf 23. Mai 2014 8 17 Typen von DSLs (i) Man unterscheidet zwischen zwei Typen von DSLs: 1. Interne DSL: n
n
n
Definiert mijels einer Wirtsprogrammiersprache (host language) DSL („Programm“) ist eingebejet in ein Wirtsprogramm Freiheitsgrade bzgl. der DSL daher durch Wirtssprache beschränkt Beispiele interner DSLs: n Gradle: Build-­‐Sprache, auf Basis von Groovy definiert n Rake: Build-­‐Sprache, auf Basis von Ruby definiert thorsten möller -­‐ informa=k.unibas.ch/lehre/fs14/cs109/09-­‐dyn&dsls.pdf 23. Mai 2014 18 Typen von DSLs (ii) 2. Externe DSL: n
Nicht mijels einer bestehenden Programmiersprache definiert n
n
n
Defini=on der Syntax als formale Gramma=k meist mit entsprechenden Tools Freiheitsgrade „nur“ durch Editoren und Gesetze bzw. Grenzen der maschinellen Verarbeitung beschränkt (Berechenbarkeit, Ausführbarkeit, Komplexität). Bisher hoher Aufwand für Entwicklung externer DSLs. Neue Frameworks zur Entwicklung/Spezifika=on erleichtern dies erheblich, z.B.:
Xtext [hjp://www.eclipse.org/Xtext] n
n
Erweiterte Backus-­‐Naur-­‐Form (EBNF) zur Beschreibung der Gramma=k Parser, Compiler und Texteditor werden automa=sch erzeugt thorsten möller -­‐ informa=k.unibas.ch/lehre/fs14/cs109/09-­‐dyn&dsls.pdf 23. Mai 2014 9 19 Beispiele externer DSLs n
n
n
Csound: SoWware-­‐Synthesizer zur Klang-­‐/Musikerzeugung LaTeX: Textsatz PROMOS: Modellierung von (finanzmathema=schen) Produkten, z.B. Versicherungsprodukte n
n
n
n
n
Struktur, Varianten, Kostenmodell, Regeln R: sta=s=sches Rechnen und Erzeugung sta=s=scher Grafiken SQL: Anfragesprache für rela=onale Datenbanken Verilog, VHDL: Hardwarebeschreibungssprachen ... und viele, viele mehr thorsten möller -­‐ informa=k.unibas.ch/lehre/fs14/cs109/09-­‐dyn&dsls.pdf 23. Mai 2014 20 Zu guter Letzt: ein Ausblick Wo geht die Entwicklung von Programmiersprachen hin? Werden wir neue Paradigmen sehen? Was sind aktuelle Trends? Trends: n Mul=-­‐Paradigmen-­‐Sprachen n
n
n
Impera=v, objektorien=ert, funk=onal, generisch (, logikorien=ert) Beispiele: D, F#, Scala, Oz Polygloj-­‐Programmierung n
Verwendung und enge Kopplung mehrerer Programmiersprachen Mijel-­‐ bzw. langfris=g: n Modulare Sprachen* n
n
Standardisierte Module für grundlegende Belange Selbstdefinierte Module (Erweiterungen) für domänenspezifische Belange * Sind eine logische Konsequenz dessen was auch in natürlichen Sprachen passiert: sie verändern sich da jeder sie verändern kann. thorsten möller -­‐ informa=k.unibas.ch/lehre/fs14/cs109/09-­‐dyn&dsls.pdf 23. Mai 2014 10 21 Weiterführende Vorlesungen n
Einführung in die Künstliche Intelligenz n
n
n
Verbindungen zu Prolog bzw. logikorien=erter Programmierung bzw. zur kombinatorischen Problemlösung SoWware Engineering High Performance Compu=ng thorsten möller -­‐ informa=k.unibas.ch/lehre/fs14/cs109/09-­‐dyn&dsls.pdf 23. Mai 2014 11