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