Funktionale Programmierung

Werbung
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
Herunterladen