Funktionale Programmierung Organisatorisches • Halbmodul im Masterstudiengang • Termin: Donnerstags, 12:30 Uhr, HS 5G • Ab etwa Mitte November zusätzlich • • • Donnerstags, 8:30 Uhr, HS 5G Es gibt keine Teilnahmepflicht und keine Abgabe der Übungsaufgaben Nächste Woche (23.10): VL um 8:30 Ich werde Sie per Mail (via LSF) informieren, wenn sich etwas ändert Projekt • Falls es gewünscht wird, kann ich eine Projektaufgabe stellen • Das Projekt-Ergebnis hätte einen Anteil an der Note Sprache • Clojure • Ein auf funktionale Programmierung ausgerichtetes Lisp, das auf der JVM läuft • Evtl. einen kleinen Happen Haskell oder Elixir Prüfung Klausur Termin nach Vereinbarung + Raumverfügbarkeit Evaluation 2013 Was ist funktionale Programmierung? Wikipedia [...] functional programming is a programming paradigm [...] that treats computation as the evaluation of mathematical functions and avoids state and mutable data. Functional programming emphasizes functions that produce results that depend only on their inputs and not on the program state - i.e. pure mathematical functions [...] Eliminating side effects [...] can make it much easier to understand and predict the behavior of a program, which is one of the key motivations for the development of functional programming. Kurzfassung • • • • • • Programmierparadigma mathematische Funktionen vermeidet Zustand vermeidet veränderbare "Objekte" Keine Nebeneffekte / vermeidet Nebeneffekte Einfacher zu verstehen und vorherzusagen Erik Meijer • Functional Programming is a style of programming in which expressions are more important than using statements • Komplexe Ausdrücke werden durch Komposition weniger komplexer Ausdrücke erzeugt Warum? • • • Welchen Wert hat x? x = 1 x += ++x + ++x" Perl? Groovy? JS? Php? Ruby? Python? Welchen Wert hat x nach x = 1 x = x + (x+1)+(x+1) Clojure? • Clojure ist unsere Arbeitssprache • Die Konzepte, die wir studieren sind aber breiter gefasst • Man kann in vielen Sprachen funktional programmieren • Sie sollen hier infiziert werden! Funktionale Sprachen im historischen Überblick Geschichte • 1936 Turing "On computational numbers with an Application to the Entscheidungsproblem" • Einführung der Turing Maschine um berechenbare Funktionen zu formalisieren ! 1936 - Alan Turing invents every programming language that will ever be but is shanghaied by British Intelligence to be 007 before he can patent them. A Brief, Incomplete, and Mostly Wrong History of Programming Languages http://james-iry.blogspot.de/2009/05/brief-incomplete-and-mostly-wrong.html Geschichte • 1936 A. Church "An unsolvable problem of elementary number theory" • In dem Paper wird der nicht typisierte Lambda Kalkül eingeführt als formaler Kalkül für berechenbare Funktionen Untypisierter 𝝺 Kalkül • Grammatik: T ≔ V | T T | 𝝺V.T • V:Variablen • T: Term • Erweiterungen • Konstanten • Zahlen • mathematische Standardfunktionen Der 𝝺 Kalkül • 𝝺 V.T : Definiert eine Funktion, die den Parameter V • • hat und als Ergebnis T liefert (üblicherweise beinhaltet T die Variable V) T1 T2 : Funktionsanwendung von T1 auf T2. Beispiel (mit Erweiterung): Definition der Quadratfunktion: 𝝺x.x*x • • Anwendung: 𝝺x.x*x 4 ! 1936 - Alonzo Church also invents every language that will ever be but does it better. His lambda calculus is ignored because it is insufficiently C-like. This criticism occurs in spite of the fact that C has not yet been invented. A Brief, Incomplete, and Mostly Wrong History of Programming Languages http://james-iry.blogspot.de/2009/05/brief-incomplete-and-mostly-wrong.html Geschichte • Satz: Turing Maschinen und untypisierter 𝝺 Kalkül sind gleich mächtig • Beweisidee: Implementiere eine TM im 𝝺 Kalkül • • Implementiere einen Auswerter für den 𝝺 Kalkül auf einer TM Geschichte • 1958: McCarthy "Recursive Functions of Symbolic Expressions and their Computation by Machine, Part 1" • Das Paper beschreibt ein ProgrammierSystem (List Processing) um den untypisierten 𝝺 Kalkül leichter benutzbar zu machen ! 1958 - John McCarthy and Paul Graham invent LISP. Due to high costs caused by a post-war depletion of the strategic parentheses reserve LISP never becomes popular. In spite of its lack of popularity, LISP remains an influential language in "key algorithmic techniques such as recursion and condescension" A Brief, Incomplete, and Mostly Wrong History of Programming Languages http://james-iry.blogspot.de/2009/05/brief-incomplete-and-mostly-wrong.html Geschichte • 1964: Kenneth Iverson: APL • Grosser Einfluss auf Matlab und Mathematica • • Hat ein eigenes Keyboard 'if you need more than one line of APL you do not fully understand your problem' Geschichte • 1972/74: Girard und Reynolds entdecken unabhängig voneinander System F • System F ist ein parametrischer polymorpher 𝝺 Kalkül. • Es gibt nicht nur Variablen für Funktionen sondern auch für Typen • Eine Erweiterung von System F wird seit 2008 für Haskell benutzt Geschichte • Satz: Typinferenz ohne explizite Typannotationen für System F ist unentscheidbar • Beweis: siehe J.B. Wells, 1998 "Typability and Type Checking in System F are equivalent and undecidable" Geschichte • • 1972: A. Colmerauer - Prolog • Man kann in Prolog funktional programmieren Einordnung als funktionale Sprache wird Prolog nicht gerecht ! 1972 - Alain Colmerauer designs the logic language Prolog. His goal is to create a language with the intelligence of a two year old. He proves he has reached his goal by showing a Prolog session that says "No." to every query. A Brief, Incomplete, and Mostly Wrong History of Programming Languages http://james-iry.blogspot.de/2009/05/brief-incomplete-and-mostly-wrong.html Geschichte • 1973: Charles 'Chuck' Moore Forth • Imperative, stack basierte Sprache • Postfix Notation: 10 2 + dup * • Forth ist nicht funktional, hatte aber Einfluss auf spätere funktionale (konkatenative) Sprachen Stack basierte Sprachen • Stack basierter Ansatz ist in VMs verbreitet • JVM • CPython VM, PyPy • Warum sind VMs stack basiert? ! Geschichte • • 1974: Sussman/Steele - Scheme • Scheme ist minimalistisch und "funktionaler" als Lisp Scheme wird als Lisp Dialekt für die Lehre entwickelt Geschichte • • • • • • • • Zwischen 1975 und 1980 publizieren Steele und Sussman eine Reihe von Artikeln, die oft als λ Papers bezeichnet werden ! Scheme: An Interpreter for Extended Lambda Calculus 1975 Lambda: The Ultimate Imperative 1976 Lambda: The Ultimate Declarative 1976 Lambda: The Ultimate GOTO 1977 The Art of the Interpreter 1978 Rabbit: A Compiler for Scheme 1978 Lambda: The Ultimate Opcode 1979 http://lambda-the-ultimate.org/ ! 1970 - Guy Steele and Gerald Sussman create Scheme. Their work leads to a series of "Lambda the Ultimate" papers culminating in "Lambda the Ultimate Kitchen Utensil." This paper becomes the basis for a long running, but ultimately unsuccessful run of late night infomercials. Lambdas are relegated to relative obscurity until Java makes them popular by not having them. A Brief, Incomplete, and Mostly Wrong History of Programming Languages http://james-iry.blogspot.de/2009/05/brief-incomplete-and-mostly-wrong.html Geschichte • 1976: R. Millner "A theory of type polymorphism in programming" • Neuartiger Inferenzalgorithmus (Hindley-Millner Type Inference) • ML markiert den Anfang der statisch typisierten funktionalen Sprachen ! 1973 - Robin Milner creates ML, a language based on the M&M type theory. ML begets SML which has a formally specified semantics. When asked for a formal semantics of the formal semantics Milner's head explodes. Other well known languages in the ML family include OCaml, F#, and Visual Basic. A Brief, Incomplete, and Mostly Wrong History of Programming Languages http://james-iry.blogspot.de/2009/05/brief-incomplete-and-mostly-wrong.html Geschichte • • • 1984: Lisp und ML werden standardisiert Common Lisp Standard ML Geschichte • • 1984: Beginn der Arbeit an Coq • Implementierung einer funktionalen Programmiersprache mit Dependent Typsystem • Als "Nebeneffekt" generiert Coq Programme Coq ist ein mathematisches Beweissystem / Theorembeweiser Geschichte • • 1986: J. Armstrong entwickelt Erlang • Erlang ist gedacht für hochgradig nebenläufige Systeme • Der zweite Fokus ist Fehlertoleranz Der erste Erlang Prototyp wurde in Prolog implementiert (das merkt man) Joe Armstrong über OO “The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them.You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.” (Joe Armstrong) Geschichte • • 1994: Apple - Dylan • • Eine Mischung aus Lisp und Smalltalk Hybrid aus funktionaler und objektorientierter Sprache Dylan ist praktisch tot, hatte aber starken Einfluss auf Ruby Geschichte • • 1995: Z. Somogyi - Mercury • • Statisch typisiert Mercury mischt logische und funktionale Programmierung Rein logisch (im Gegensatz zu Prolog) Geschichte • • 1995: M. Hanus - Curry • Curry ist ein Hybrid aus funktionaler und logischer Sprache Die zweite nach Haskell Curry benannte Sprache Geschichte • • • 1995: OCaml Sprache aus der ML Familie OO Features Geschichte • • • 1995: Gosling - Java Keine funktionale Sprache JVM Geschichte • • • • • • 1998: Haskell 98 Standard Haskell ist die wichtigste funktionale Sprache in der Forschung Statisch typisiert Lazy Evaluation Pure! "Learning Haskell to improve one's Java skills is like working on sushi knife technique to better amputate one's way out of a beartrap." (@bos31337) ! 1990 - A committee formed by Simon Peyton-Jones, Paul Hudak, Philip Wadler, Ashton Kutcher, and People for the Ethical Treatment of Animals creates Haskell, a pure, non-strict, functional language. Haskell gets some resistance due to the complexity of using monads to control side effects. Wadler tries to appease critics by explaining that "a monad is a monoid in the category of endofunctors, what's the problem?" A Brief, Incomplete, and Mostly Wrong History of Programming Languages http://james-iry.blogspot.de/2009/05/brief-incomplete-and-mostly-wrong.html Geschichte • • Ebenfalls 1998: Scheme R5RS Standard für Scheme Geschichte • • 1999: T. Coquand - Agda • • Dependent Typsystem Agda ist ein Beweisassistent und eine funktionale Programmiersprache I'm going to write a long rant on how the Agda and Coq communities thinks the Haskell community is a bunch of anything-goes hippies. (@jamesiry) Geschichte • • • 2001: M. von Thun - Joy • Konkatenative Sprache: Joy ist eine funktionale Sprache Idee: Jede Berechnung ist eine Funktion von Stack nach Stack Programm Konkatenation == Funktionale Komposition Geschichte • • • 2003: Slava Pestov - Factor Erste Implementierung: JFactor (JVM) Es gibt eine Clojure DSL - Factjor (2013, Bloom) Geschichte • • 2003: M. Odersky - Scala • • Scala ist im Moment sehr populär Scala ist ein funktionaleobjektorientierte Hybridsprache Interessant für Java Programmierer ist der Umgang mit Generics Geschichte Liskov'sches Substitutionsprinzip: Sei P eine beweisbare Eigenschaft von Objekten des Typs S. Dann soll P auch für Objekte des Typs T wahr sein, wobei T ein Untertyp von S ist. • • • • Immer wenn irgendwo S steht, kann man gedanklich T dafür einsetzen Bsp. S = Obst, T = Apfel public void essen(Obst x) { ... }" Apfel a = new Apfel(); essen(a);" Geschichte Frage: Wenn T ein Subtyp von S ist, was gilt für List<T> und List<S> ? A. List<T> ist Subtyp von List<S> ? B. List<S> ist Subtyp von List<T> ? C. Es gibt keine Vererbungsbeziehung zwischen List<S> und List<T>? D. Kann ich jemanden anrufen? ! 2003 - A drunken Martin Odersky sees a Reese's Peanut Butter Cup ad featuring somebody's peanut butter getting on somebody else's chocolate and has an idea. He creates Scala, a language that unifies constructs from both object oriented and functional languages. This pisses off both groups and each promptly declares jihad. ! A Brief, Incomplete, and Mostly Wrong History of Programming Languages http://james-iry.blogspot.de/2009/05/brief-incomplete-and-mostly-wrong.html Geschichte • • • 2005: Microsoft - F# • Ursprünglich ein Forschungsprojekt, aber seit 2010 offiziell in Visual Studio unterstützt • Das F# Typsystem unterstützt Einheiten, der Typchecker kann Fehler in physikalischen Einheiten finden F# ist ein Abkömmling der ML Familie Sehr nahe an OCaml (viele OCaml Programme können direkt mit F# kompiliert werden) Geschichte • • 3<m> + 3<s> gibt einen Typfehler 3<m> + 1 <cm> ergibt 301 <cm> Geschichte • • • • 2005: M. Tarver - Qi Ziel war ein modernes Lisp für die Lehre zu entwickeln um zu verhindern, das Lisp stirbt Qi basiert auf Common Lisp Qi ist gescheitert, hat aber einige Eigenschaften, die es bemerkenswert machen Es verwendet den Sequenten Kalkül für das Typsystem Es hat Prolog und YACC als Subsprachen eingebettet • • Geschichte • • 2009: R. Hickey - Clojure • • Clojure ist ein Erfolg geworden Ziel war ein modernes Lisp zu für die JVM zu implementieren Alles Weitere im Rest des Semesters! Geschichte • • • 2011: M. Tarver - Shen • Es ist für verschieden Lisps (u.a. Clojure) portiert worden Nachfolger / Fork von Qi Sehr ähnlich zu Qi, aber nicht mehr so stark an Common Lisp gebunden Geschichte • • • • • • 2011: Elixir Läuft auf der Erlang BEAM-VM modernisiertes Erlang Syntax erinnert an Ruby Meta-Programmierung Polymorphismus wurde von Clojure adaptiert Clojure: Getting started Installation • Bitte nicht per Paketmanager Clojure installieren • Stattdessen sollte man leiningen benutzen Leinigen Leiningen • • Build System für Clojure • • http://leiningen.org/ Maven kompatibel (benutzt Clojars Repository und Maven Central) Installation: https://raw.github.com/technomancy/ leiningen/stable/bin/lein runterladen, im Pfad unterbringen und ausführbar machen Leiningen Basics • lein new <Projektname> • lein repl • lein test • lein uberjar Leiningen konfigurieren • Leiningen legt im user home einen Ordner .lein an • In diesem Ordner kann man in einer Datei profiles.clj zusätzliche leiningen Plugins eintragen {:user {:plugins [[lein-catnip "0.5.1"]]}} IDE / Editor? • • • • • • • • Emacs + Paredit vim (Es gibt paredit, soll aber nicht so toll sein) Counterclockwise (Eclipse) Cursive (IntelliJ) Lighttable Nightcode Catnip Notepad, Sublime Text, Textmate, ...