Funktionale Programmierung Th. Letschert TH Mittelhessen Gießen University of Applied Sciences Einführung – Programmierparadigmen – Was ist funktionale Programmierung Enthusiastischer (naiver) junger Dozent in seiner Einleitung zum Skript der Vorlesung „Funktionale Programmierung“, TU Darmstadt WS 1983 Write a paper promising salvation, make it a 'structured' something or a 'virtual' something, or 'abstract', 'distributed' or 'higher-order' or 'applicative' and you can almost be certain of having started a new cult. Seite 2 Erfahrener Großmeister der Informatik 1979 https://en.wikiquote.org/wiki/Edsger_W._Dijkstra Paradigmen der Programmierung Paradigma Ursprünglich: Beispiel das eine Art charakterisiert Allgemeiner Sprachgebrauch: Lehrmeinung, Gedankengebäude Karriere des Begriffs Startet mit Thomas Kuhn: The Structure of Scientific Revolutions (1962) deutsch: Die Struktur wissenschaftlicher Revolutionen, Suhrkamp Taschenbuch Wissenschaft, 13. Auflage 1996 These von Kuhn: Wissenschaftlicher Fortschritt ist nicht kontinuierlich Paradigma: Die akzeptierte Lehrmeinung bewegt sich meist in einem festen Rahmen, Paradigma genannt Von Zeit zu Zeit werden die Begrenzungen des herrschenden Paradigmas sichtbar Paradigmenwechsel: In eine Umbruch- und Kampf-Phase setzt sich dann ein neues Paradigma durch. Wissenschaftlicher Fortschritt kann damit (auch) als sozialer Prozess verstanden werden Seite 3 Paradigmen der Programmierung Paradigmen der Programmierung Ein Programmierparadigma ist ist eine Menge an kohärenten Konzepten und Prinzipien, die bei der Gestaltung einer software-technischen Lösung eingesetzt werden können. Paradigmen definieren Schemata zur Lösung von Problemen mit Hilfe von Computern: – Wie modelliert man Sachverhalte: Mit Listen, Abbildungen, Mengen, Relationen Mit Relationen Mit Klassen und Objekten Mit logischen Aussagen … – Wie formuliert man Berechnungen Mit Variablen, Zuweisungen, Bedingungen, Schleifen Mit Funktionen die Funktionen nutzen und selbst Funktionen erzeugen können Mit Regeln die logische Schlussfolgerungen erlauben Mit Regeln zur Manipulation von Termen ... Seite 4 Paradigmen der Programmierung Paradigmen der Programmierung Eine Programmiersprache unterstützt meist mehr als ein Programmierparadigma. Ein Programmierparadigma wird in der Regel von vielen Programmiersprachen unterstützt. Grundlegende Programmierparadigmen Imperativ Programme bestehen aus Anweisungen – eventuell zu Prozeduren zusammengefasst. Anweisungen manipulieren den Inhalt von Variablen. Objektorientiert Programme bestehen aus Objekten die gegenseitig ihre Methoden aufrufen. Objekte bestehen aus Variablen und Prozeduren. Sie können als Instanzen von Klassen erzeugt werden. Funktional Programme bestehen aus Ausdrücken mit einem Wert. Sie enthalten Funktionen die Werte in andere Werte transformieren. Logisch Programme bestehen aus logischen Charakterisierungen von gesuchten Lösungen. Relational Programme beschreiben die Manipulation von Relationen. Seite 5 Paradigmen der Programmierung Paradigmen der Programmierung Imperativ / Objektorientiert Funktional Logisch / Relational Ist bekannt. Besprechen wir in dieser Veranstaltung Programme beschreiben Beziehungen zwischen Dingen. def pythagoreischesTripel () = { x = choice(1,2,3,4,5,6,7,8,9) y = choice(1,2,3,4,5,6,7,8,9) z = choice(1,2,3,4,5,6,7,8,9) if x*x + y*y = z*z then return (x,y,z) else fail fi } append([],Y,Y). append(X,[],X). Ein relationales Programm:Bestimme drei Zahlen x, y, z derart, dass x2 + y2 = z2 Ein logisches Programm (-Stück) : AppendFunktion in Prolog append(X,Y,Z) :X = [H | T], Z = [H | U], append(T, Y, U). Eine ausgezeichnete Übersicht der unterschiedlichen Programmierparadigmen findet sich in: Peter Van Roy, Seif Haridi: Concepts, Techniques, and Models of Computer Programming MIT-Press 2004 Seite 6 Paradigmen der Programmierung Programmierparadigmen: Übersicht Quelle: http://www.info.ucl.ac.be/~pvr/paradigms.html Seite 7 Funktionale Programmierung – um was geht es Grundprinzipien der funktionalen Programmierung Funktionale Programmierung = Programmierung mit (mathematischen) Funktionen Zeit und zeitliche Reihenfolge spielen keine Rolle bei der Programmdefinition Programme werden nicht als Aktionen in der Zeit definiert Die Ausführung läuft natürlich in der Zeit ab, aber dieser Ablauf wird nicht vom Programmierer (ungeschickt, eventuell fehlerhaft) sondern vom System (korrekt und angepasst an die aktuelle Situation zur Ausführungszeit) festgelegt Die Definitionen von Funktionen ist das Ausdrucksmittel für Programmdefinitionen Funktionsaufrufe sind die einzige „Kontrollstruktur“. Rekursion spielt darum eine besondere Rolle Funktionen sind eine wichtige Art von Werten Funktionen sind darum als Argumente und Ergebnisse anderer Funktionen erlaubt. Seite 8 Funktionale Programmierung – um was geht es Konzepte der Funktionalen Programmierung In der funktionalen Programmierung wird eine Vielzahl von Konzepte mit unterschiedlicher Bedeutung verwendet: – Funktionen sind Werte. Es gibt Ausdrücke deren Wert eine Funktion ist (Closure) – Es gibt Ausdrücke deren Wert eine (mehr oder weniger) komplexe Datenstruktur ist – Induktive / algebraische Typen – Call-by-need / Call-by-name werden unterstützt – Funktionen höherer Ordnung (Map / Fold) stehen zur Verfügung – Es gilt referenzielle Transparenz – Es gibt (scheinbar) unendlich große Datensequenzen – Parallelverarbeitung muss nicht explizit formuliert werden – ... Seite 9 Funktionale Programmierung – um was geht es Programmierung mit beschränkten Mitteln Jede (ernsthafte) Programmiersprache bietet (auch) Funktionen Funktionale Programmierung ist darum immer – eine Programmierung mit beschränkten Mitteln – die wesentlich durch das definiert wird, was nicht geht. Worin besteht die Beschränkung: Es gibt nichts, das sich verändert, Zeit, Aktionen, Reihenfolgen von Aktionen etc. spielen keine Rolle Was spricht gegen die Beschränkung Zeit gibt es wirklich die Welt besteht aus Dingen, die sich verändern, der Mensch lebt in Raum und Zeit und hat für beides ein gutes Verständnis, das ihn als Programmierer einer nicht-funktionalen Sprache produktiv macht. Was spricht für die Beschränkung Ja, warum sollte mach sich mit weniger zufrieden geben? The functional programmer sounds rather like a mediæval monk, denying himself the pleasures of life in the hope that it will make him virtuous. John Hughes in „Why Functional Programming matters“ Seite 10 Funktionale Programmierung – um was geht es Programmierung mit beschränkten Mitteln Was spricht für die Beschränkung auf Funktionen Weniger geht schon: die Mathematik ist eine rein funktionale Sprache: kennt nur ewige Werte die sich nie verändern Trotzdem ist sie extrem erfolgreich als Mittel zur Beschreibung der Welt – unsere gesamte technische Zivilisation beruht auf diesem Erfolg. Also muss es nicht nur irgendwie gehen, sondern sogar gut gehen. Warum ist weniger aber gut? Seite 11 Funktionale Programmierung – um was geht es Programmierung mit beschränkten Mitteln Was spricht für die Beschränkung auf Funktionen: Zustandsänderungen / Variablen und Anweisungen .. sind böse: – Zustandsänderungen sind unübersichtlich Man sieht einer Funktion mit Seiteneffekten nicht sofort an, dass sie Seiteneffekte hat oder schreibt jeder die korrekten Post-Conditions in den Header – wer weiß überhaupt was das ist? Wie sehen Tests aus? … – Zustandsänderungen sind gefährlich Andere (vor allem nebenläufige) Aktionen können die Zustände „von aussen“ unbemerkt verändern .. sind oft nicht notwendig: – Das Programmieren mit Anweisungen und Variablen ist oft nur eine schlechte Angewohnheit. Viele Programme können viel klarer ohne Anweisungen und Variablen formuliert werden. .. können explizit gemacht werden: – Wenn tatsächlich mit Dingen gearbeitet werden muss, die sich verändern, dann können die Veränderungen in funktionaler Art zu modelliert werden. Seite 12 Funktionale Programmierung – um was geht es Explizite statt implizite Zustandsänderungen Zustandsänderungen können explizit gemacht werden Dinge ändern sich – die auf Mathematik basierende Physik leugnet das nicht! Sie macht es explizit: – Die Temperatur eines Körpers ist keine Variable mit wechselnden Werten, mal so und dann später anders. – Die Temperatur eines Körpers ist eine Funktion t : T → Real die Zeitwerte auf Temperaturwerte abbildet. Seite 13 Funktionale Programmierung – um was geht es Explizite statt implizite Zustandsänderungen Zustandsänderungen können explizit gemacht werden In der funktionalen Programmierung – sind Zustandsänderungen nicht verboten, – sie müssen explizit modelliert werden. Beispiel ein „funktionales“ C-Programm: #include <stdio.h> #include <stdlib.h> int count(void); count ist eine Funktion ohne Argument die einen int-Wert liefert int main(void) { printf("%d\n", count()); printf("%d\n", count()); } 0 -1 -2 Ausgeben wird dies: wechselnde int-Werte int count(void) { static int c = 0; return c--; } Der Protopyp von count ist also eine freche Lüge! Eine Funktion liefert bei gleicher Eingabe das gleiche Ergebnis. Also ist count keine Funktion void => int! denn count ist so implementiert! Seite 14 Funktionale Programmierung – um was geht es Explizite statt implizite Zustandsänderungen Beispiel ein „funktionales“ Scala-Programm: dieser Typ für count ist ebenfalls eine freche Lüge! object Counter { var c = 0 def count: Int = { val res = c; c = c-1 res } } object CounterApp extends App { import Counter.count println(count) println(count) } 0 -1 -2 denn ausgeben wird dies: wechselnde int-Werte Seite 15 Funktionale Programmierung – um was geht es Explizite statt implizite Zustandsänderungen Behelf: Post-Conditions object Counter { var c = 0 /** counts downwards from 0. * @return the value of c * @post c is decreased by one */ def count: Int = { val res = c; c = c-1 res } Zustandsänderungen können explizit gemacht werden } In der funktionalen Programmierung sind „heimliche“ Zustandsänderungen verboten. – Sie müssen klar erklärt werden. Das ist schon mal ein Ansatz in die Richtung. Seite 16 Funktionale Programmierung – um was geht es Explizite statt implizite Zustandsänderungen Korrekt: count hat zwei Werte – den Zählerwert und – einen neuen Zähler dieser Typ für count ist korrekt! object Counter { val start = 0 def count(c: Int) : (Int, Int) = (c+1, c) } object CounterApp extends App { import Counter._ Das Programm ist funktional. Dinge ändern sich, aber die Änderungen werden explizit modelliert. val c0 = start val (c1, v1) = count(c0) println(v1) val (c2, v2) = count(c1) println(v2) } c0,c1,c2, sind die (expliziten) Zählerzustände. Das ist wirklich rein funktional: der gleiche Bezeichner bezieht sich immer auf das Gleiche. Nie auf „etwas das sich ändert“. – Alles was sich ändert muss über unveränderliches modelliert werden. Seite 17 Funktionale Programmierung – um was geht es Explizite statt implizite Zustandsänderungen Explizite Zustände: Was soll daran gut sein? Man sieht die Zustände! object Counter { val start = 0 def count(c: Int) : (Int, Int) = (c+1, c) } object Counter { var c = 0 def count: Int = { val res = c; c = c-1 res } } object CounterApp extends App { import Counter.count println(count) println(count) } object CounterApp extends App { import Counter._ val c0 = start val (c1, v1) = count(c0) println(v1) val (c2, v2) = count(c1) println(v2) Fortschritt ? – Hmm ? Ja ! Später werden wir sehen, dass man das auch hübscher formulieren kann. Seite 18 } Bei der funktionalen Programmierung muss das Böse seine hässliche Fratze zeigen. Das Böse sind die zustandsabhängigen Berechnungen. Funktionale Programmierung – um was geht es Explizite statt implizite Zustandsänderungen Berechnungen mit wechselnden Zuständen sind sehr oft gar nicht notwendig! Sehr vieles kann rein funktional berechnet werden: Functional programming is programming with functions! Und, ja, das geht! Das geht sogar meistens elegant und klar. Zustände und deren Änderungen sind nicht so oft notwendig wie viele denken. Wenn Zustandsänderungen doch notwendig und da sind, dann erkennt man sie auch. Die Typen (Funktionsspezifikationen) lügen nicht mehr. Das ist referenzielle Transparenz. Seite 19 Funktionale Programmierung – um was geht es Wer braucht schon Zustände? Zustandsänderungen sind oft nicht notwendig: – Das Programmieren mit Anweisungen und Variablen ist oft nur eine schlechte Angewohnheit. Viele Programme können viel klarer ohne Anweisungen und Variablen formuliert werden. Seite 20 Funktionale Programmierung – um was geht es Wer braucht schon Zustände? Beispiel: Das FizzBuzz-Problem (https://en.wikipedia.org/wiki/Fizz_buzz): Erzeuge die Folge: 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz, 16, 17, Fizz, 19, Buzz, Fizz, 22, 23, Fizz, Buzz, 26, Fizz, 28, 29, FizzBuzz, 31, 32, Fizz, 34, Buzz, Fizz, ... for (var i = 1; i < ...; i++) { // For each iteration, // initialize an empty string var string = ''; // If `i` is divisible by 3 // with no remainder, append `Fizz` if (i % 3 === 0) { string += 'Fizz'; } Das Programmieren mit Anweisungen und Variablen ist oft nur eine schlechte Angewohnheit. // If `i` is divisible by 5 // with no remainder, append `Buzz` if (i % 5 === 0) { string += 'Buzz'; } // // // if } } If `string` is still empty, `i` is not divisible by 3 or 5, so use the number instead. (string === '') { string += i; Lösung aus Wikipedia. Nicht funktional: i ändert sich! Verhunzter Mist – aus schlechter Gewohnheit formuliert! console.log(string); Seite 21 Funktionale Programmierung – um was geht es Wer braucht schon Zustände? FizzBuzz funktional – Das FizzBuzz-Problem wird durch einen Ausdruck gelöst! – In dem Ausdruck dürfen / sollten Funktionen verwendet werden, die einfachere / Teil- Probleme lösen: fizzBuzz = … F … G ... – Welche funktionalen Gliederungen sind möglich: fizzBuzz wird aus einer Folge natürlicher Zahlen erzeugt: fizzBuzz = F(1, 2, 3, 4, 5, … ) indem auf jede Zahl eine Funktion angewendet wird. fizzBuzz = ( G(1), G(2), G(3), G(4), G(5), … ) fizzBuzz wird aus mehreren Folgen erzeugt: fizzBuzz = F( (1, 2, 3, 4, 5, …), („“, „“, „fizz“, „“, „“, „fizz“, …), („“, „“, „“, „“, „buzz“, „“, …)) …. Seite 22 Kern des WikipediaAlgorithmus' von oben, aber in Variablen und Anweisungen begraben. Funktionale Programmierung – um was geht es Wer braucht schon Zustände? FizzBuzz funktional – Der Wikipedia-Lösung ist eine Funktion / ein „funktionaler Algorithmus“, der nicht-funktional umgesetzt wurde, – Der „Grund-Algorithmus“ kann auch funktional implementiert werden – Bei der funktionalen Programmierung kommt es darauf an „in Funktionen zu denken“ und nicht vorzeitig in Zuständen und sich verändernden Variablen. object FizzBuzz extends App { def hasCharsOrElse(s: String, n: Int): String = if (s.length>0) s else n.toString() def fizzBuzz(n: Int) : String = (if (n%3 == 0) "fizz" else "") + (if (n%5 == 0) "buzz" else "") def G(n: Int) : String = hasCharsOrElse(fizzBuzz(n), n) for (i <- 1 to 30) println(G(i)) Wikipedia-Algorithmus ohne vorzeitige irrelevante und verwirrende Details einer Implementierung. – In „gebildeter Form“ also, nicht „prä-pubertäres Gehacke“. } Seite 23 Funktionale Programmierung – um was geht es Denken in Funktionen statt in Variablen und Anweisungen Funktionale Programmiersprachen unterstützen das Denken in Funktionen durch spezielle Ausdrucksmittel: – Unendliche Folgen: Konstruiere die Folge der Zahlen 1, 2, 3, 4, 5, … – Funktionsanwendung auf alle Elemente einer Kollektion: Map, wende eine Funktion auf jedes Element einer Folge an – ... object FizzBuzz extends App { def numsFrom(n: Int) : Stream[Int] = n #:: numsFrom(n+1) Erzeuge eine unendliche Folge def hasCharsOrElse(s: String, n: Int): String = if (s.length>0) s else n.toString() def fizzBuzz(n: Int) : String = (if (n%3 == 0) "fizz" else "") + (if (n%5 == 0) "buzz" else "") def G(n: Int) : String = hasCharsOrElse(fizzBuzz(n), n) val allNums = numsFrom(1) val fizzBuzzes = allNums map (G) map: Wende G auf jedes Element an. fizzBuzzes.take(30).foreach { println(_) } } Seite 24 Funktionale Programmierung – um was geht es Seiteneffekte braucht man nicht Funktionale Programmierung verzichtet so weit wie möglich auf Zustände – Ohne Zustand kann eine Funktion keinen Seiteneffekt haben (Seiteneffekt: das Liefern eines Wertes ist nicht der einzige Effekt einer Funktion) – Seiteneffekte man braucht nicht, es geht ohne. Beispiel: Insertion Sort Algorithmus: l l.length < 2 insert(x, sort(l')) l = x :: l' sort (l) = mit: insert(x, l) = List(x) x :: l e :: insert(x, l') l = List() l = e :: l' und x > e l = e :: l' sonst Notation e :: l ist die Liste l mit davor gesetztem e : a :: List(b, c) = List(a, b, c) Seite 25 Funktionale Programmierung – um was geht es Seiteneffekte will man nicht Beispiel: Insertion Sort, Implementierung in Java: – Seiteneffekte sind böse. Beispiel: public class InsertionSortApp { private static void insSort(List<Integer> l) { if (l.size() >= 2) { int first = l.get(0); insSort(l.subList(1, l.size())); insert(first, l); } } private static void insert(Integer x, List<Integer> l) { if (l.size() == 0 ) { l.add(x); } else { if (l.get(0) > x) { l.add(0,x); } else { insert(x, l.subList(1, l.size())); l.add(0, l.get(0)); } } } Seite 26 korrekt ? Funktionale Programmierung – um was geht es Seiteneffekte will man nicht und braucht man nicht Beispiel: Insertion Sort, Implementierung in Java: – Seiteneffekte sind böse. Beispiel: public class InsertionSortApp { } private static void insSort(List<Integer> l) { if (l.size() >= 2) { int first = l.get(0); insSort(l.subList(1, l.size())); insert(first, l); } } private static void insert(Integer x, List<Integer> l) { if (l.size() == 0 ) { l.add(x); } else { if (l.get(0) > x) { l.add(0,x); } else { insert(x, l.subList(1, l.size())); l.add(0, l.get(0)); } } } public static void main(String[] args) { List<Integer> lst = new LinkedList<>(); for (int i: new Integer[]{7,3,9,1}) lst.add(i); System.out.println(lst); insSort(lst); System.out.println(lst); } Seite 27 Nicht korrekt ! [7, 3, 9, 1] [7, 7, 3, 3, 3, 3, 3, 3, 7, 9, 9, 1, 1, 9] Funktionale Programmierung – um was geht es Keine Seiteneffekte ist gut Beispiel: Insertion Sort, korrekte, Seiteneffekt-freie (funktionale) Implementierung in Java – Seiteneffekt-frei (mit Mühen) und korrekt private static List<Integer> insSort(List<Integer> l) { if (l.size() < 2) { return l; } else { int first = l.get(0); List<Integer> sortedRest = insSort(l.subList(1, l.size())); return insert(first, sortedRest); } } private static List<Integer> insert(Integer x, List<Integer> l) { if (l.size() == 0 ) { List<Integer> ll = new LinkedList<>(); ll.add(x); return ll; } else { int first = l.get(0); if (first > x) { List<Integer> ll = new LinkedList<>(l); ll.add(0, first); return ll; } else { List<Integer> ll = insert(x, l.subList(1, l.size())); ll.add(0, l.get(0)); return ll; } } } Seite 28 Korrekt ! – aber umständlich, denn List ist eine veränderliche Datenstruktur die mit Sorgfalt und Mühen bedient werden muss. Funktionale Programmierung – um was geht es Keine Seiteneffekte ist gut Beispiel: Insertion Sort, funktionale Implementierung in Scala: – Seiteneffekt-frei (mühelos) und korrekt def insSort(l: List[Int]): List[Int] = if (l.length < 2) l else insert(l(0), insSort(l.slice(1, l.length))); def insert(x: Int, l: List[Int]): List[Int] = if (l.length == 0 ) List(x) else if (l(0) > x) x::l else l(0) :: insert(x, l.slice(1, l.length)) List ist in Scala (und jeder anständigen funktionalen Sprache) eine unveränderliche Kollektion, Seiteneffekte sind ausgeschlossen! Unveränderliche Kollektionen vermeiden versehentliche Seiteneffekt und sind darum ein zwingend notwendiges Mittel der funktionalen Programmierung. Seite 29 Funktionale Programmierung – Historie Funktionale Programmierung – Die ewige Untote Erfunden von McCarthy: Lisp ~ 1958 Wiederentdeckt als alte Idee mit neuer Zukunft ~ 1982 Siegeszug des japanischen 5-th Generation Project KI: Computer finden Lösungen selbständig Deklarative Sprachen: Man sagt was, nicht wie Funktional ist deklarativ! Tatsächlich: 1980er, Jahrzehnt des Triumphs der Objektorientierung (GUIs)! Wiederentdeckt als alte Idee mit neuer Zukunft ~ 2010 Siegeszug der Multicore-Rechner Fehleranfällige schwierige Synchronisation allgegenwärtig in Anwendungen – statt nur Systemsoftware Kein Problem mit der Synchronisation wenn sich die Daten nicht ändern – also wenn funktional programmiert wird. Seite 30 Funktionale Programmierung – Historie Einige funktionale Sprachen – Lisp (List Processing Language) Dynamisch typisiert, erste Programmiersprache mit Datenstrukturen (ab 1958) – Common Lisp Lisp-Variante, dynamisch typisiert, Seiteneffekte erlaubt (ab 1984) – Clojure Lisp-Variante, dynamisch typisiert, JVM-Sprache (ab 2007) – ML / Caml / OCaml statisch typisierte Sprachen, Seiteneffekte erlaubt (ab 1973) – F# statisch typisiert, Microsoft Sprache, Seiteneffekte erlaubt, basiert auf OCaml (ab 2002) – Haskell statisch typisiert, rein funktional (ab 1990) – Frege JVM-Implementierung von Haskell (ab 2013) – Erlang dynamisch typisierte streng funktionale Sprache (Telekom-Anwendungen) (ab 1993) – Scala statisch typisierte Multiparadigmen-Sprache mit funktionalen Elementen (ab 2003) Seite 31 Funktionale Programmierung – Warum Warum funktional Programmieren Allgemein – Erweiterung der Entwickler-Kompetenz eine weitere Problemlösungs-Strategie ein weiteres Softwaretechnisches Kozept eine weitere Klasse von Programmiersprachen weitere interessante / wichtige Programmkonstrukte – Erweiterung der Employablitity Kenntnis einer Technologie mit zunehmender Bedeutung – Es macht Spass Speziell – Robustere / fehlerfreiere Programme – Klarerer (leichter testbarer) Code – Kürzerer Code – Direktere Umsetzung von Lösungsideen Seite 32 Funktionale Programmierung – Was ist das Funktionale Programmiersprachen und funktionale Programmierung Funktionale Programmierung – Programmieren mit (reinen) Funktionen – In erster Linie ein software-technischer Ansatz: Wie gestaltet / strukturiert man Software Funktionale Programmiersprachen – Programmiersprachen mit Ausdrucksmitteln zur Unterstützung der funktionalen Programmierung Funktionen höherer Ordnung Unveränderliche Datenstrukturen … – Varianten funktionaler Sprachen rein funktionale Sprachen (z.B. Haskell) keine Unterstützung von zustandsändernden Aktionen nicht rein funktionale Sprachen (z.B. Lisp) wenig Unterstützung von zustandsändernden Aktionen Multi-Paradigma-Sprachen Ausdrucksmittel zur Unterstützung der funktionalen und anderer (der objektorientierten) Programmierung Seite 33 Funktionale Programmierung – Die Veranstaltung Thema der Veranstaltung Funktionale Programmierung – als software-technischer Ansatz – auch in Konkurrenz und / oder in Zusammenarbeit zu anderen Ansätzen (Objektorientierung) Funktionale Programmiersprachen – Wesentliche Ausdrucksmitteln zur Unterstützung der funktionalen Programmierung Funktionen höherer Ordnung Unveränderliche Datenstrukturen Statische Typisierung … Scala – Als Multi-Paradigma-Sprache mit Ausdrucksmitteln zur Unterstützung der funktionalen und der objektorientierten Programmierung – Funktionale Programmierung ist ein wichtiges Programmierparadigma, aber nicht das einzige. Es ist weder notwendig noch sinnvoll sich als fortgeschrittener Software-Entwickler auf ein Paradigma zu beschränken! "there is no single development, in either technology or management technique, which by itself promises even one order of magnitude improvement within a decade in productivity, in reliability, in simplicity." Fred Brooks – zitiert nach https://en.wikipedia.org/wiki/No_Silver_Bullet Seite 34 Funktionale Programmierung – Die Veranstaltung Literatur Dies ist ein Kurs zu funktionaler Programmierung in Scala. Die Teilnehmer sollten eine geeignete und ihnen passende Literatur zum Thema „Scala“ zur Hand haben. Rein sprachbezogene Dinge werden in den Folien nicht systematisch dargestellt. Empfehlenswert sind die vielfältigen Online-Quellen und beispielsweise – Odersky, Spoon, Venners: Programming in Scala artima, 2007 – M. C. Lewis: Introduction to the Art of Programming using Scala, CRC 2012 Die Veranstaltung verwendet einige Inhalte aus: – P. Chiusano, R. Bjarnason. Functional Programming in Scala, Manning 2015 – sowie in geringerem Umfang: P. Pepper, P. Hofstedt: Funktionale Programmierung, Springer 2006 B.C. Pierce: Types and Programming Languages, MIT-Press 2002 Der „Geist“ der dieser Veranstaltung zugrunde liegt, wird in einem Klassiker der funktionalen Programmierung sehr schön dargelegt: – John Hughes: Why functional Programming matters Chalmers Tekniska Högskola, Göteborg, 1984; online: http://www.cse.chalmers.se/~rjmh/Papers/whyfp.pdf Seite 35 Funktionale Programmierung – Die Veranstaltung Voraussetzungen In der Veranstaltung wird von einem erfolgreichen Grundstudium der Informatik ausgegangen. Insbesondere sollten die Kenntnisse aus folgenden Veranstaltungen in solider Form präsent sein: – Objektorientierte Programmierung – Programmierung interaktiver Systeme – Algorithmen und Datenstrukturen Grundkenntnisse in Scala sind nützlich, aber nicht zwingend notwendig. Eine gewisse Bereitschaft sich mit dieser Sprache zu beschäftigen, wird jedoch vorausgesetzt. Seite 36