Keep calm and curry on

Funktionales Programmieren
mit Beispielen in Haskell und Java,
License: CC-BY-SA-4.0

Martin Heuschober

2017-06-28

Intro

Überblick

Tiobe - Programmiersprachen
Tiobe - Programmiersprachen
Tiobe - Haskell
Tiobe - Haskell

Timeline

Timeline - Haskell Timeline - Java

History of Programming languages

Syntax & Features

  • Whitespace sensitive
  • Funktionsaufrufe ohne ()
  • Typ-Signatur (optional) getrennt von Definition
  • Funktionen sind “first level citizens”
  • Starkes Typsystem + Typinferenz
  • Objektorientiert + Vererbung -NullPointer
  • Riesiges Ökosystem/Libraries Entwickler
  • IDEs
  • bisschen Funktional (seit Java8)

Funktionales Programmieren

Was ist funktional?

Funktional jetzt aber wirklich

Eine Programmiersprache darf sich (meiner Meinung nach) funktional nennen wenn:

  • Funktionen als Parameter bzw. Rückgabewerte von anderen Funktionen auftauchen können
  • Funktionen in “Variablen” gesteckt werden können
  • jede Funktion einen Rückgabewert hat.

  • Bonuspunkte gibt es für partielle Funktionsaufrufe, i.e. wenn eine Funktion mit mehreren Parametern mit nur einem Parameter aufrufbar ist, und eine Funktion mit um einen Parameter weniger zurückgibt.

Was ist eine Funktion

Java8

Aufgabe: (Stackoverflow) Mache aus einer Liste: [5,4,2] => "+-----+----+--+"

Mache aus einer Liste: [5,4,2] => "| + + |"

Partielle Funktionsaufrufe

Higher order functions

map

  • macht aus einer Liste eine neue Liste

Aber was bringt uns das?

  • Parallelisation for “free”
  • equational reasoning
  • (stream) fusion

fold/reduce

filter

all/any

Typsystem

Info

  • Hindley-Milner
  • stark, statisch

Mein Problem mit schwachen Typsystemen

Aus der Dokumentation von node.js (fast wortgetreu) fs.openSync(path, flags[, mode])

  • path <string> | <Buffer> | <URL>
  • flags <string> | <number>
  • mode <integer>

Synchronous version of fs.open(). Returns an integer representing the file descriptor.

Offene Fragen

  • Welche Flags gibt es?
  • Was ist das ‘+’?
  • Welche numerischen Flags gibt es?
  • Sind das jetzt auch <integer> oder auch Kommazahlen?
  • Aber ok das ist ja nur die Dokumentation - gute Programmierer kümmern sich ja gern darum, dass ihre Doku brandaktuell und vollständig ist

Typsysteme sind ja da den Programmierern helfen keine Fehler zu machen

fs.truncate(<integer>, <integer>, <Function>)

Ok das kann ja nicht passieren wenn man die Doku ordentlich liest

machen ja auch alle - und kopieren nicht einfach Code von Stackoverflow

Wozu Typsysteme also?

  1. Soll unterstützen.
  2. Soll so viel Info wie möglich beinalten.
  3. Soll so wenig einschränken wie möglich.
  4. Soll weitgehend “automatisch” passieren.

Jeder Fehler der zur Compile-time erkannt wird, landet nie bei einem Kunden.

Dinge die das Haskell Typsystem gut macht

Und andere Systeme nicht können:

IO eingrenzen

Sum types

Pattern matching

Typinferez

[] und (:) sind Listenkonstruktoren (leere Liste und cons-Operator) => 2tes Argument von map muss eine Liste sein.

ebenso das Ergebnis

f wird in Zeile 2 auf das erste Element der Argument-Liste angewandt => damit muss f eine Funktion sein

f wird in Zeile 2 auf das erste Element der Argument-Liste angewandt => damit muss f der Wertebereich von f a sein und der Zielbereich b

Und man sich klauen kann

Generics verwenden und Arrays vermeiden

Haskell ist pure

  • NonNullable/@Nullable verwenden
  • IO minimieren
  • mutable State minimieren - z.B. List.append(x) verändert eine Liste und ist daher eine schlechte Idee . . .
  • Abstraktionen wie Funktor, Applicative, Monad, Monoid etc.

Fundamental theorem of software engineering

“We can solve any problem by introducing an extra level of indirection.”

Butler Lampson

Functor

What?

Ziel: Einen Container-Datentyp elementweise verändern, aber die Struktur des Containers beibehalten. Warum: Fast jeder Container hat diese Eigenschaft.

Haskell

Java

Haskell

Java