Moderne Funksjonell Programmering i Lisp

Like dokumenter
INF2810: Funksjonell Programmering. Strømmer og utsatt evaluering

INF2810: Funksjonell Programmering. Mer om verditilordning og muterbare data.

INF2810: Funksjonell Programmering. Mer om verditilordning og muterbare data.

INF2810: Funksjonell Programmering. Mer om verditilordning. Tabeller. Og strømmer.

INF2810: Funksjonell Programmering. Mer om verditilordning. Tabeller. Og strømmer.

INF2810: Funksjonell Programmering. Køer, tabeller, og (litt om) parallelitet

INF2810: Funksjonell Programmering. Strømmer og utsatt evaluering

INF2810: Funksjonell Programmering. Køer, tabeller, og (litt om) parallelitet

INF2810: Funksjonell Programmering. Kommentarer til prøveeksamen

INF2810: Funksjonell Programmering. Eksamensforberedelser

INF2810: Funksjonell Programmering. Mengder og lokal tilstand

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme, del 2

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme, del 2

INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering. Lister og høyereordens prosedyrer

INF2810: Funksjonell Programmering. Utsatt evaluering og strømmer

INF2810: Funksjonell Programmering. Utsatt evaluering og strømmer

INF2810: Funksjonell Programmering. Lokale variabler. Og trær.

INF2810: Funksjonell Programmering. Lokale variabler. Og trær.

INF2810: Funksjonell Programmering. Trær og mengder

INF2810: Funksjonell Programmering. Utsatt evaluering og strømmer

INF2810: Funksjonell Programmering. Utsatt evaluering og strømmer

Rekursjon og lister. Stephan Oepen & Erik Velldal. 1. februar, Universitetet i Oslo

INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering. Muterbare data

INF2810: Funksjonell Programmering. Lister og høyereordens prosedyrer

INF2810: Funksjonell Programmering. Trær og mengder

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme, del 2

INF2810: Funksjonell Programmering. Strømmer

INF2810: Funksjonell Programmering. Strømmer

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser

INF2810: Funksjonell Programmering. Dataabstraksjon og Trerekursjon

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser

Høyere-ordens prosedyrer

INF2810: Funksjonell Programmering. Tilstand og verditilordning

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser

INF2810: Funksjonell Programmering. Tilstand og verditilordning

INF2810: Funksjonell Programmering. Trær og mengder

INF2810: Funksjonell Programmering. Mer om strømmer

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme

INF2810: Funksjonell Programmering. Mer om strømmer

INF2810: Funksjonell programmering: Introduksjon

(define (naer-nok-kuberot? y x) (< (abs (- (kube y) x)) 0.001)) (define (naermere-kuberot y x) (/ (+ (* y 2) (/ x (kvadrat y))) 3))

LISP PVV-kurs 25. oktober 2012

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme

INF2810: Funksjonell Programmering. En metasirkulær evaluator

INF2810: Funksjonell Programmering. En metasirkulær evaluator

Det finnes ingenting. som kan gjøres med interface. men som ikke kan gjøres uten

INF2810: Funksjonell Programmering. En metasirkulær evaluator, del 2

INF2810: Funksjonell Programmering. En metasirkulær evaluator, del 2

Innlevering 2b i INF2810, vår 2017

INF2810: Funksjonell Programmering. Tilstand og verditilordning

INF2810: Funksjonell Programmering. Tilstand og verditilordning

UNIVERSITETET I OSLO

Vi skal se på lambda-uttrykk. Følgende er definerte og vil bli brukt gjennom oppgaven

Liste som abstrakt konsept/datatype

Lisp 3: Spesielle former, variabler, imperativ programmering

Hva er en liste? Hvert element har en forgjenger, unntatt første element i listen. Hvert element har en etterfølger, unntatt siste element i listen

UNIVERSITETET I OSLO

INF2810: Funksjonell Programmering. Introduksjon

INF2810: Funksjonell Programmering. Muterbare data

INF2810: Funksjonell programmering: Introduksjon

IN1010 våren januar. Objektorientering i Java

INF2810: Funksjonell Programmering. Introduksjon

INF2810: Funksjonell Programmering. Lister og høyereordens prosedyrer

Hva er en liste? Hvert element har en forgjenger, unntatt første element i listen. Hvert element har en etterfølger, unntatt siste element i listen

INF2810: Funksjonell Programmering. Muterbare data

AlgDat 12. Forelesning 2. Gunnar Misund

INF1010 våren januar. Objektorientering i Java

Array&ArrayList Lagring Liste Klasseparametre Arrayliste Testing Lenkelister

INF2810: Funksjonell programmering: Mer om Scheme. Rekursjon og iterasjon.

Gjennomgåelse av eksamensoppgaven i HUMIT2710 fra våren 2004

INF2220: Forelesning 1. Praktisk informasjon Analyse av algoritmer (kapittel 2) (Binær)trær (kapittel )

Introduksjon til programmering og programmeringsspråk. Henrik Lieng Høgskolen i Oslo og Akershus

UNIVERSITETET I OSLO

INF Seminaroppgaver til uke 3

Array&ArrayList Lagring Liste Klasseparametre Arrayliste Testing Lenkelister Videre

Lisp 2: Lister og funksjoner

Sideeekter og makroer i Lisp

NITH PG4200 Algoritmer og datastrukturer Løsningsforslag Eksamen 4.juni 2013

Løsningsforslag Test 2

Side 1. Oppgave 1. Prosedyrer 1.1. Prosedyrene f og g skal begge returnere prosedyrer. a. Skriv f slik at ((f a) b) returnerer summen av a og b.

Generiske mekanismer i statisk typede programmeringsspråk

INF1010 våren Grensesnitt

1- og 2-veis Innkapsling Java Stabel Kø Prio-kø Iterator. Enveis- og toveislister Innkapsling («boxing») (Big Java 6.8.5)

Variable Man kan bruke variable i ML. ML (kap 5 og 6) Nye datatyper INF3110/4110 INF3110/4110 INF3110/4110 INF3110/4110. Variable i ML.

Hva er en kø? En lineær datastruktur der vi til enhver tid kun har tilgang til elementet som ble lagt inn først

Introduksjon til programmering og programmeringsspråk

OPPGAVE 1 OBLIGATORISKE OPPGAVER (OBLIG 1) (1) Uten å selv implementere og kjøre koden under, hva skriver koden ut til konsollen?

INF Algoritmer og datastrukturer

INF2810: Funksjonell Programmering. Eksamensforberedelser

Hvorfor sortering og søking? Søking og sortering. Binære søketrær. Ordnet innsetting forbereder for mer effektiv søking og sortering INF1010 INF1010

Logaritmiske sorteringsalgoritmer

INF2810: Funksjonell Programmering. Introduksjon

Transkript:

Moderne Funksjonell Programmering i Lisp Lars Tveito 11. mai, 2017 Institutt for Informatikk, University of Oslo

Introduksjon

Abstract Vi skal utforske programmeringsspråket Clojure, en moderne Lisp-dialekt. Språket ønsker å oppnå bekymringsfri håndtering av samtidighet (eng: concurrency), et svært sentralt problem i moderne programvareutvikling. Clojure favoriserer ikke-muterbar data og rene funksjoner. Vi skal se hvordan Clojure utvider tradisjonelle Lisp-dialekter med ikke-muterbare implementasjoner av lister, vektorer og hashmaps som samles under begrepet persistente datastrukturer. Videre skal vi se hvordan Clojure utnytter tre referansetyper med ulik semantikk for samtidighet sammen med persistente datastrukturer for å oppnå gode og pragmatiske løsninger for samtidighet. Til slutt skal vi se at Clojure er et språk for hipstere med kule briller og GitHub-logo som dekker det halvspiste eplet. Clojurescript er Clojure som kompileres til Javascript og kan dermed brukes til utvikling av web-apps, samt bygge native mobilapplikasjoner for Android og ios! Dette er ikke pensum for INF2810. Det er allikevel fryktelig interessant. 1

Litt om Clojure Clojure dukket for 10 år siden og lansert i 2009 Dette er ganske nytt i programmeringsspråksammenheng 1

Litt om Clojure Clojure dukket for 10 år siden og lansert i 2009 Dette er ganske nytt i programmeringsspråksammenheng Clojure er bygget på Java Alt fra Java kan kalles på 1

Litt om Clojure Clojure dukket for 10 år siden og lansert i 2009 Dette er ganske nytt i programmeringsspråksammenheng Clojure er bygget på Java Alt fra Java kan kalles på Clojure er (i likhet med Scheme) dynamisk typet 1

Litt om Clojure Clojure dukket for 10 år siden og lansert i 2009 Dette er ganske nytt i programmeringsspråksammenheng Clojure er bygget på Java Alt fra Java kan kalles på Clojure er (i likhet med Scheme) dynamisk typet Clojure favoriserer rene funksjoner på ikke-muterbar data 1

Litt om Clojure Clojure dukket for 10 år siden og lansert i 2009 Dette er ganske nytt i programmeringsspråksammenheng Clojure er bygget på Java Alt fra Java kan kalles på Clojure er (i likhet med Scheme) dynamisk typet Clojure favoriserer rene funksjoner på ikke-muterbar data Clojure forsøker å løse problemer mht. samtidighet (eng: concurrency) 1

Litt om Clojure Clojure dukket for 10 år siden og lansert i 2009 Dette er ganske nytt i programmeringsspråksammenheng Clojure er bygget på Java Alt fra Java kan kalles på Clojure er (i likhet med Scheme) dynamisk typet Clojure favoriserer rene funksjoner på ikke-muterbar data Clojure forsøker å løse problemer mht. samtidighet (eng: concurrency) Clojure er laget av Rich Hickey en gud blant mennesker 1

Litt om Clojure Clojure dukket for 10 år siden og lansert i 2009 Dette er ganske nytt i programmeringsspråksammenheng Clojure er bygget på Java Alt fra Java kan kalles på Clojure er (i likhet med Scheme) dynamisk typet Clojure favoriserer rene funksjoner på ikke-muterbar data Clojure forsøker å løse problemer mht. samtidighet (eng: concurrency) Clojure er laget av Rich Hickey en gud blant mennesker 1

Men først, litt kode fra oblig1a 2

Men først, litt kode fra oblig1a Oppgave 3 (a) (defn add1 [n] (+ n 1)) Oppgave 3 (b) (defn plus [n m] (if (zero? m) n (add1 (plus n (sub1 m))))) (defn sub1 [n] (- n 1)) Oppgave 3 (c) (defn plus [n m] (if (zero? m) n (recur (add1 n) (sub1 m)))) 2

Men først, litt kode fra oblig1a (forts.) Oppgave 3 (e) (defn fib ([n] (fib 1 0 n)) ([a b count] (if (zero? count) b (recur (+' a b) a (dec count))))) 3

Men først, litt kode fra oblig1a (forts.) Oppgave 3 (e) i Clojure-stil (defn fib [n] (let [fib-step (fn [[a b]] [b (+' a b)]) fibs (iterate fib-step [1 1])] (first (nth fibs n)))) 4

Men først, litt kode fra oblig1a (forts.) Oppgave 3 (e) i Clojure-stil (defn fib [n] (let [fib-step (fn [[a b]] [b (+' a b)]) fibs (iterate fib-step [1 1])] (first (nth fibs n)))) Enda mer Clojure-stil (defn fib [n] ( (fn [[a b]] [b (+' a b)]) (iterate [1 1]) (nth n) first)) 4

Persistente datastrukturer

Persistente Datastrukturer En datastruktur er persistent hvis den ikke ødelegger gamle versioner av seg selv 5

Persistente Datastrukturer En datastruktur er persistent hvis den ikke ødelegger gamle versioner av seg selv Scheme sine lister er persistente fordi et kall på (cons x xs) ikke påvirker xs 5

Persistente Datastrukturer En datastruktur er persistent hvis den ikke ødelegger gamle versioner av seg selv Scheme sine lister er persistente fordi et kall på (cons x xs) ikke påvirker xs (men ikke hvis du bruker set-car! eller set-cdr!!) 5

Persistente Datastrukturer En datastruktur er persistent hvis den ikke ødelegger gamle versioner av seg selv Scheme sine lister er persistente fordi et kall på (cons x xs) ikke påvirker xs (men ikke hvis du bruker set-car! eller set-cdr!!) Clojure har ikke-muterbare og persistente implementasjoner av 5

Persistente Datastrukturer En datastruktur er persistent hvis den ikke ødelegger gamle versioner av seg selv Scheme sine lister er persistente fordi et kall på (cons x xs) ikke påvirker xs (men ikke hvis du bruker set-car! eller set-cdr!!) Clojure har ikke-muterbare og persistente implementasjoner av Lister (1 2 3) 5

Persistente Datastrukturer En datastruktur er persistent hvis den ikke ødelegger gamle versioner av seg selv Scheme sine lister er persistente fordi et kall på (cons x xs) ikke påvirker xs (men ikke hvis du bruker set-car! eller set-cdr!!) Clojure har ikke-muterbare og persistente implementasjoner av Lister Vektorer (1 2 3) [1 2 3] 5

Persistente Datastrukturer En datastruktur er persistent hvis den ikke ødelegger gamle versioner av seg selv Scheme sine lister er persistente fordi et kall på (cons x xs) ikke påvirker xs (men ikke hvis du bruker set-car! eller set-cdr!!) Clojure har ikke-muterbare og persistente implementasjoner av Lister Vektorer Mengder (1 2 3) [1 2 3] #{1 2 3} 5

Persistente Datastrukturer En datastruktur er persistent hvis den ikke ødelegger gamle versioner av seg selv Scheme sine lister er persistente fordi et kall på (cons x xs) ikke påvirker xs (men ikke hvis du bruker set-car! eller set-cdr!!) Clojure har ikke-muterbare og persistente implementasjoner av Lister (1 2 3) Vektorer [1 2 3] Mengder #{1 2 3} Hashmaps {:a 1, :b 2, :c 3} 5

Persistente Datastrukturer (forts.) Alle datastrukturer i Clojure støtter 1 De implementerer ISeq interfacet, som kan minne om Itrable fra Java. 6

Persistente Datastrukturer (forts.) Alle datastrukturer i Clojure støtter conj en mer generell cons 1 De implementerer ISeq interfacet, som kan minne om Itrable fra Java. 6

Persistente Datastrukturer (forts.) Alle datastrukturer i Clojure støtter conj en mer generell cons (conj '(1 2 3) 4) => (4 1 2 3) 1 De implementerer ISeq interfacet, som kan minne om Itrable fra Java. 6

Persistente Datastrukturer (forts.) Alle datastrukturer i Clojure støtter conj en mer generell cons (conj '(1 2 3) 4) => (4 1 2 3) (conj [1 2 3] 4) => [1 2 3 4] 1 De implementerer ISeq interfacet, som kan minne om Itrable fra Java. 6

Persistente Datastrukturer (forts.) Alle datastrukturer i Clojure støtter conj en mer generell cons (conj '(1 2 3) 4) => (4 1 2 3) (conj [1 2 3] 4) => [1 2 3 4] (conj #{1 2 3} 4) => #{1 4 3 2} 1 De implementerer ISeq interfacet, som kan minne om Itrable fra Java. 6

Persistente Datastrukturer (forts.) Alle datastrukturer i Clojure støtter conj en mer generell cons (conj '(1 2 3) 4) => (4 1 2 3) (conj [1 2 3] 4) => [1 2 3 4] (conj #{1 2 3} 4) => #{1 4 3 2} (conj {:a 1 :b 2 :c 3} [:d 4]) => {:a 1, :b 2, :c 3, :d 4} 1 De implementerer ISeq interfacet, som kan minne om Itrable fra Java. 6

Persistente Datastrukturer (forts.) Alle datastrukturer i Clojure støtter conj en mer generell cons (conj '(1 2 3) 4) => (4 1 2 3) (conj [1 2 3] 4) => [1 2 3 4] (conj #{1 2 3} 4) => #{1 4 3 2} (conj {:a 1 :b 2 :c 3} [:d 4]) => {:a 1, :b 2, :c 3, :d 4} count hvor mange ting er i samlingen? 1 De implementerer ISeq interfacet, som kan minne om Itrable fra Java. 6

Persistente Datastrukturer (forts.) Alle datastrukturer i Clojure støtter conj en mer generell cons (conj '(1 2 3) 4) => (4 1 2 3) (conj [1 2 3] 4) => [1 2 3 4] (conj #{1 2 3} 4) => #{1 4 3 2} (conj {:a 1 :b 2 :c 3} [:d 4]) => {:a 1, :b 2, :c 3, :d 4} count hvor mange ting er i samlingen? De kan brukes som sekvenser 1 1 De implementerer ISeq interfacet, som kan minne om Itrable fra Java. 6

Persistente Datastrukturer (forts.) Alle datastrukturer i Clojure støtter conj en mer generell cons (conj '(1 2 3) 4) => (4 1 2 3) (conj [1 2 3] 4) => [1 2 3 4] (conj #{1 2 3} 4) => #{1 4 3 2} (conj {:a 1 :b 2 :c 3} [:d 4]) => {:a 1, :b 2, :c 3, :d 4} count hvor mange ting er i samlingen? De kan brukes som sekvenser 1 map, filter, reduce og mange flere 1 De implementerer ISeq interfacet, som kan minne om Itrable fra Java. 6

Persistente Datastrukturer (forts.) Alle datastrukturer i Clojure støtter conj en mer generell cons (conj '(1 2 3) 4) => (4 1 2 3) (conj [1 2 3] 4) => [1 2 3 4] (conj #{1 2 3} 4) => #{1 4 3 2} (conj {:a 1 :b 2 :c 3} [:d 4]) => {:a 1, :b 2, :c 3, :d 4} count hvor mange ting er i samlingen? De kan brukes som sekvenser 1 map, filter, reduce og mange flere For hashmaps får vi en liste på formen ([:a 1] [:b 2] ) 1 De implementerer ISeq interfacet, som kan minne om Itrable fra Java. 6

Persistente Datastrukturer (forts.) Persistente datastrukturer baserer seg på strukturell deling 2 xs d b g a c f h 2 By The original uploader was VineetKumar at English Wikipedia - Transferred from en.wikipedia to Commons by sevela.p., CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=3594619 7

Persistente Datastrukturer (forts.) Persistente datastrukturer baserer seg på strukturell deling 2 xs xs ys d b d g d g b g a c f f h a c f h e 2 By The original uploader was VineetKumar at English Wikipedia - Transferred from en.wikipedia to Commons by sevela.p., CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=3594619 7

Persistente Datastrukturer (forts.) Lister O(1) for endring i begynnelsen (conj '(1 2 3) 4) O(n) for oppslag (nth '(1 2 3 4) 2) Egner seg når man skal traversere hele 8

Persistente Datastrukturer (forts.) Lister O(1) for endring i begynnelsen (conj '(1 2 3) 4) O(n) for oppslag (nth '(1 2 3 4) 2) Egner seg når man skal traversere hele Vektorer O(1) for innsetting på slutten (conj [1 2 3] 4) O(1) for oppslag ([1 2 3 4] 2) O(1) for (ikke destruktiv) endring (assoc [1 2 3 3] 3 4) Egner seg når man bryr seg om posisjon trenger raskt oppslag 8

Persistente Datastrukturer (forts.) Mengder O(1) for innsetting (conj #{1 2 3} 4) O(1) for sjekk av medlemskap (#{1 2 3} 3) Egner seg når du bryr deg om noe er i mengden eller ikke 9

Persistente Datastrukturer (forts.) Mengder O(1) for innsetting (conj #{1 2 3} 4) O(1) for sjekk av medlemskap (#{1 2 3} 3) Egner seg når du bryr deg om noe er i mengden eller ikke Hashmaps O(1) for innsetting (assoc {:a 1} :b 2) O(1) for oppslag ({:a 1, :b 2} :b) O(1) for (ikke destruktiv) endring (dissoc {:a 1 :b 2} :b) Egner seg når du trenger en assosiativ datastruktur 9

INF1010 Oblig i Clojure

Legg til Sortert (ns inf1010-oblig4.core (:require [clojure.core.reducers :as r])) (defn split [xs x] (split-with (comp neg? #(compare % x)) xs)) (defn add-sorted [xs x] (let [[smaller larger] (split xs x)] (reduce into [] [smaller [x] larger]))) 10

Fletting (defn merge-sorted ([] []) ([xs ys] (merge-sorted xs ys [])) ([xs ys res] (let [x (first xs) y (first ys)] (cond (empty? xs) (into res ys) (empty? ys) (into res xs) (neg? (compare x y)) (recur (rest xs) ys (conj res x)) :else (recur xs (rest ys) (conj res y)))))) 11

Sortering Sekvensiell sortering (defn single-threaded-sort [xs] (reduce add-sorted [] xs)) 12

Sortering Sekvensiell sortering (defn single-threaded-sort [xs] (reduce add-sorted [] xs)) Parallellisert sortering (defn threaded-sort [xs n] (let [chunk-size ( xs count (quot n) inc)] (r/fold chunk-size merge-sorted add-sorted xs))) 12

Tilstandsendring i Clojure

Verdier, Identitet og Tilstand En verdi er noe som ikke endrer seg 13

Verdier, Identitet og Tilstand En verdi er noe som ikke endrer seg Tallet 2 og 11. mai er verdier, men et Java-objekt er ikke det 13

Verdier, Identitet og Tilstand En verdi er noe som ikke endrer seg Tallet 2 og 11. mai er verdier, men et Java-objekt er ikke det Clojure skiller mellom identitet og tilstand 13

Verdier, Identitet og Tilstand En verdi er noe som ikke endrer seg Tallet 2 og 11. mai er verdier, men et Java-objekt er ikke det Clojure skiller mellom identitet og tilstand En identitet er en stabil logisk enhet som har en serie av verdier over tid 13

Verdier, Identitet og Tilstand En verdi er noe som ikke endrer seg Tallet 2 og 11. mai er verdier, men et Java-objekt er ikke det Clojure skiller mellom identitet og tilstand En identitet er en stabil logisk enhet som har en serie av verdier over tid En tilstand er en verdi ved et gitt tidspunkt 13

Referansetyper Trådlokale variabler kan endres med set!, tilsvarende Scheme 14

Referansetyper Trådlokale variabler kan endres med set!, tilsvarende Scheme Lite idiomatisk og sjeldent brukt 14

Referansetyper Trådlokale variabler kan endres med set!, tilsvarende Scheme Lite idiomatisk og sjeldent brukt Vi har tre forskjellige referansetyper, som har andledes semantikk mht. concurrency 14

Referansetyper Trådlokale variabler kan endres med set!, tilsvarende Scheme Lite idiomatisk og sjeldent brukt Vi har tre forskjellige referansetyper, som har andledes semantikk mht. concurrency Refs synkron og koordinert tilstandsendring 14

Referansetyper Trådlokale variabler kan endres med set!, tilsvarende Scheme Lite idiomatisk og sjeldent brukt Vi har tre forskjellige referansetyper, som har andledes semantikk mht. concurrency Refs synkron og koordinert tilstandsendring Atoms synkron og ukoordinert tilstandsendring 14

Referansetyper Trådlokale variabler kan endres med set!, tilsvarende Scheme Lite idiomatisk og sjeldent brukt Vi har tre forskjellige referansetyper, som har andledes semantikk mht. concurrency Refs synkron og koordinert tilstandsendring Atoms synkron og ukoordinert tilstandsendring Agents asynkron og ukoordinert tilstandsendring 14