Universitetet i Linköping Institutionen för datavetenskap Anders Haraldsson 2

Relevanta dokument
Dagens föreläsning Programmering i Lisp Fö 5

Dagens föreläsning Programmering i Lisp Fö 7. Sammanfattning funktionell programmering Exempel på funktionella programspråk

Två fall: q Tom sekvens: () q Sekvens av element: (a b c) ; (sum-rec '(2 4 6)) = 12. q Första elementet uppfyller vissa villkor: (2 a b c)

Tentamen i. TDDC67 Funktionell programmering och Lisp

Rekursiva algoritmer sortering sökning mönstermatchning

TDDC74 Programmering, abstraktion och modellering DUGGA 2

Dagens föreläsning Programmering i Lisp. - Bindning av variabler (avs 14.6) fria variabler statisk/lexikalisk och dynamisk bindning

Universitetet i Linköping Institutionen för datavetenskap Anders Haraldsson

LABORATION 1. Inledande Lisp - rekursion

Dagens föreläsning. Diverse Common Lisp. Konstanter, parametrar, globala variabler

Imperativ programmering. Imperativ programmering konstruktioner i Lisp. Datastrukturer (kap ) arraystruktur poststruktur

TDDC74 Programmering, abstraktion och modellering. Tentamen

Komma igång med Allegro Common Lisp

TDDC74 Programmering: Abstraktion och modellering Tentamen, lördag 27 augusti 2016, kl 8 12

n Detta för att kunna koncentrera oss på n Tal: number? n Symboler: symbol? n Strängar: string? n Tecken: char? n Boolskt: boolean?

TDDC74 Programmering, abstraktion och modellering. Tentamen

Uppgift 6A - Frekvenstabell

TDDC74 Programmering, abstraktion och modellering. Tentamen

Uppgift 4A - Definition av enkla funktioner

TDDC74 Lab 02 Listor, sammansatta strukturer

allt.cl Page 1 of 17 Date: torsdag 7 december 2006

TDDC74 Lab 04 Muterbara strukturer, omgivningar

Tillämpad Programmering (ID1218) :00-13:00

TDDC74 Programmering, abstraktion och modellering DUGGA 2

Signalflödesmodellen. Två (gamla) exempel: Kvadratera alla jämna löv.

Idag: Par och listor. Scheme. DA2001 (Föreläsning 6) Datalogi 1 Hösten / 29

Idag: Par och listor. Symboler. Symboler används för att uttrycka icke-numeriska data såsom namn, adress, bilregisternummer, boktitel, osv.

TDDC74 Programmering, abstraktion och modellering. Tentamen

TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 14-18

Abstrakta datatyper. Dagens föreläsning. Abstract data types (ADT)

Dagens föreläsning. TDDC67 Funktionell programmering och Lisp Fö 8 och 9

Funktionell programmering DD1361

TDDC74 Programmering: Abstraktion och modellering Tentamen, onsdag 9 juni 2016, kl 14 18

Dagens föreläsning. - Vad skall vi kunna inför den skriftliga examinationen? - Vad skall vi ta med oss till andra kurser.

Universitetet i Linköping Institutionen för datavetenskap Anders Haraldsson

TDDC74 Programmering: Abstraktion och modellering Tentamen, lördag 29 augusti 2015, kl 8 12

TDDC74 Programmering, abstraktion och modellering DUGGA 1

TENTAMEN I PROGRAMSPRÅK -- DVG C kl. 08:15-13:15

TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 14-18

TDDC74 Programmering: Abstraktion och modellering Tenta, kl 14 18, 11 juni 2014

Våra enkla funktioner eller procedurer

Hur man programmerar. TDDC66 Datorsystem och programmering Föreläsning 3. Peter Dalenius Institutionen för datavetenskap

Programkonstruktion och datastrukturer. Moment 9 Om högre ordningens funktioner. PKD 2010/11 moment 9 Sida 1 Uppdaterad

TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 08-12

Tentamen i. TDDA 69 Data och programstrukturer

Imperativ och Funktionell Programmering i Python #TDDD73. Fredrik Heintz,

Linjärt minne. Sammanhängande minne är ej flexibelt. Effektivt

TDDC74 PROGRAMMERING: ABSTRAKTION OCH MODELLERING VT 2017

Dagens föreläsning. Modeller för programmeringsspråk. - Olika modeller programspråk Interpretator - kompilator. - Syntax - semantik.

Programmering II (ID1019) :00-17:00

Programmering II (ID1019)

TDDC74 Programmering: Abstraktion och modellering Tentamen, onsdag 19 oktober 2016, kl 14 18

Instruktioner - Datortentamen TDDD73 Funktionell och imperativ programmering i Python TDDE24 Funktionell och imperativ programmering del 2

Dataabstraktion. TDDD73 Funktionell och impterativ programmering i Python Föreläsning 12. Peter Dalenius Institutionen för datavetenskap

Datalogi, grundkurs 1 Övningsuppgifter i Scheme. Serafim Dahl, Carina Edlund, m.fl.

Universitetet i Linköping Institutionen för datavetenskap Anders Haraldsson

Instruktioner - Datortentamen TDDE24 och TDDD73 Funktionell och imperativ programmering (i Python)

TDDC74 - Lektionsmaterial C

Inlämningsuppgiften. Föreläsning 9 Innehåll. Träd. Datastrukturer i kursen

Idag: Dataabstraktion

TDDC74 Programmering: Abstraktion och modellering Dugga 2, , kl 14-16

729G74 IT och programmering, grundkurs. Tema 3. Föreläsning 2 Jody Foo,

FÖRELÄSNING 1 PERSONAL TDDC74 PROGRAMMERING: ABSTRAKTION OCH MODELLERING VT 2017 SYFTE EXAMINATION ORGANISATION

Föreläsning 9 Exempel. Intervallhalveringsmetoden. Intervallhalveringsmetoden... Intervallhalveringsmetoden...

Föreläsning Datastrukturer (DAT037)

Föreläsning 9 Exempel

Programmering II (ID1019) :00-12:00

Datalogi, grundkurs 1

TDDC74 Programmering: Abstraktion och modellering Datordugga 2 - exempel

SCB :-0. Uno Holmer, Chalmers, höger 2 Ex. Induktiv definition av lista. // Basfall

Föreläsning 9 Innehåll

Datastrukturer och algoritmer

Instruktioner - Datortentamen TDDD73 Funktionell och imperativ programmering i Python

TDDC74 Programmering: Abstraktion och modellering Dugga 1, exempeldugga

Funktionell programmering

Datastrukturer i kursen. Föreläsning 8 Innehåll. Träd rekursiv definition. Träd

Inom datalogin brukar man använda träd för att beskriva vissa typer av problem. Om man begränsar sig till träd där varje nod förgrenar sig högst två

Procedurer och villkor. Rekursiva procedurer. Exempel: n-fakultet

Procedurer och villkor

Datastrukturer, algoritmer och programkonstruktion (DVA104, VT 2015) Föreläsning 6

TDDC74 Programmering: Abstraktion och modellering Dugga 1, kl 14-16

Föreläsning 2 Programmeringsteknik och C DD1316. Mikael Djurfeldt

TDDC74 Programmering: Abstraktion och modellering Dugga 2, Tid: kl 08-10, Datum:

Sökning i ordnad lista. Sökning och sortering. Sökning med vaktpost i oordnad lista

Datatyper och kontrollstrukturer. Skansholm: Kapitel 2) De åtta primitiva typerna. Typ Innehåll Defaultvärde Storlek

Innehåll. Föreläsning 12. Binärt sökträd. Binära sökträd. Flervägs sökträd. Balanserade binära sökträd. Sökträd Sökning. Sökning och Sökträd

TENTAMEN I DATASTRUKTURER OCH ALGORITMER DVG B kl. 14:00-19:00

TDDC74 Programmering: Abstraktion och modellering Datortenta

TDP002 - Imperativ programmering

Programkonstruktion och Datastrukturer

Föreläsning 6: Introduktion av listor

FÖRELÄSNING 2, TDDC74, VT2018 BEGREPP PROBLEMLÖSNING MED HJÄLP AV FALLANALYS PROBLEMLÖSNING MED HJÄLP AV REKURSION

Instruktioner - Datortentamen TDDD73 Funktionell och imperativ programmering i Python

Föreläsningsanteckningar, Introduktion till datavetenskap HT S4 Datastrukturer. Tobias Wrigstad

Översikt. Varför lära sig detta? Motivering Syntax och semantik Imperativa språkets byggstenar och Python. PL-boken Kap 1 (repetition):

Instruktioner - Datortentamen TDDD73 Funktionell och imperativ programmering i Python

Deklarationer/definitioner/specifikationer

Ett generellt träd är. Antingen det tomma trädet, eller en rekursiv struktur: rot /. \ /... \ t1... tn

Uppgifter till tenta i 729G04 Programmering och diskret matematik. 17 december 2015, kl 14:00-18:00

Datastrukturer. Föreläsning 5. Maps 1

Transkript:

Anders Haraldsson 1 Anders Haraldsson 2 Dagens föreläsning Programmering i Lisp Fö 5 - Funktioner - lambda-uttryck (avs 7.1) - funcall och function (avs 7.2) - Högre ordningens funktioner (avs 7.) - Iteratorer - Egenskaper hos funktioner / operatorer - Sammanfattning av rekursiva strukturer Funktion - Lambda-uttryck Vid definitionen (defun square (x) (* x x)) definieras funktionen: (lambda (x) (* x x)) namn på denna funktion är: square Ett uttryck (form) i LISP är: (funktion argument... argument) funktion beskrivs av ett namn eller ett lambda-uttryck. Exempel som lambda-uttryck: ((lambda (x) (* x x)) 10) => 100 Anders Haraldsson Anders Haraldsson 4 Första ordningens dataobjekt En funktion i Lisp (och i de funktionella programspråken) är första ordningens dataobjekt i språket, dvs det är även data på samma sätt som andra datatyper (heltal, symboler, listor etc). Vi kan skriva funktioner som i sin tur tar funktioner som argument, returnerar en funktion som argument. Dessa funktioner brukar kallas högre ordningens funktioner. Vi kan via lambda-uttryck skapa godtyckliga funktioner under exekvering. Detta kräver tillgång till Lisp-interpretatorn (eval, apply/funcall). Vi kan ha dataobjekt med funktioner, t ex en associationslista med funktioner. ( (1. funktionen first ) (2. funktionen second ) (. funktionen third )... (20. funktionen som tar ut 20:e elementet på en lista)) Exempel: Skriv en funktion som summerar Σf(i), dvs f(1) + f(2) + f() i=1 Det som är okänt är vilken funktion som skall användas. Formella parametern f i summa-funktionen binds till den funktion, som skall användas för summeringen. (defun sum (f) (+ (funcall f 1) (funcall f 2) (funcall f ))) Funcall är en funktion som är en del av Lisp-interpretatorn, som tar ett godtyckligt antal argument (som beräknas i vanlig ordning). Första argumentets värde skall vara en funktion, och övriga arguments värden blir argumenten till denna funktion. Σsin(i) i=1 (sum (function sin)) Σi 2 + (sum (function i=1 (lambda (i) (+ (* i i) ))))

Anders Haraldsson 5 Anders Haraldsson 6 Function och # (function sin) (function (lambda (x) (* x x)) Har i stort samma funktion som quote, dvs skyddar sitt argument från vidare beräkning. I många fall skulle quote kunna användas, men det är praxis och i vissa fall nödvändigt att använda function. Ett förkortat skrivsätt för function är # # sin -> (function sin) # (lambda (x) (* x x)) -> (function (lambda (x) (* x x))) Jämför kalle -> (quote kalle) (lisa karin) -> (quote (lisa karin)) Detta är sk read-macron som direkt vid inmatning gör översättningen. Exempel på en funktion som returnerar en annan funktion: (defun choose-function (i) ((= i 1) (function 1+)) ((= i 2) (function (lambda (n) (+ n 2)))) (t (function (lambda (n) (+ n 10)))))) (funcall (choose-function 2) 5) => 7 (setq my-fn (choose-function )) (funcall my-fn 2) => 12 (my-fn 2) =>? Mer om detta att skapa funktioner beskrivs i kapitel 18 Lexical closure, där function beskrivs Anders Haraldsson 7 Anders Haraldsson 8 Repetition och iteratorer Vi har använt rekursion för att göra om något repetitivt (många olika mallar). Den andra möjligheten vi nu inför är med högre ordningens funktioner. Gör något med varje element på en lista. Gör något med varje löv i ett binärt träd. Gör något med varje nyckeln i en associationslista. Gör något med namnet i varje post i en databas. Många språk börjar införa denna typ av konstruktion. Där kallas de ofta iteratorer. Det är en generell funktion, som man kan styra genom, i Lisp-fallet ge funktioner som argument som anger vad som skall göras. Det vi hitills inte infört är den explicita repetitionssatsen, t ex for, while, loop Mallar som högre ordningens funktioner: Skriv en funktion som ökar varje element på en lista med 5. (defun öka-5 (l) (+ 5 (first l)) (öka-5 (rest l))) ))) (öka-5 (1 10 50)) => (6 15 55) Skriv en funktion som skapar en ny lista av alla förstaelementen på en lista av dellistor. (defun första-element (l) (first (first l)) (första-element (rest l))) ))) (första-element ((one ett) (two två) (three tre))) => (one two three)

Anders Haraldsson 9 Anders Haraldsson 10 Vi tänker oss en mall för genomgång av elementen i en lista och som resultat erhålla en ny lista där en funktion har applicerats på varje element (defun fn-mall (l) ( operation (first l)) (fn-mall (rest l))))))) Vi visar här hur en högre ordningens funktion mapcar kan definieras: (defun my-mapcar (fn l) (funcall fn (first l)) (my-mapcar fn (rest l))) ))) fn = operation eller "funktion Map-funktioner Common Lisp innehåller ett flertal sådana funktioner. Flera börjar på map, och kallas map-funktioner. (mapcar #'square '(1 2 4)) => (1 2 2 2 2 4 2 ) = (1 4 9 16) (mapcar #'(lambda (n) (+ n 10)) '(1 2 4)) => ( 1+10 2+10 +10 4+10 ) = (11 12 1 14) (mapcar #'(lambda (n) (if (< n 0) (- n) n)) '(1-2 -4)) => (1 2 4) Anders Haraldsson 11 Anders Haraldsson 12 Vi kan nu definiera de tidigare definierade funktionerna med mapcar. (defun öka-5 (l) (mapcar # (lambda (n) (+ n 5)) l)) (defun första-element (l) (mapcar # first l)) Map-funktioner i Common Lisp (mapcar # first ((a b c) (x y z))) => (a x) Kan användas med flera argument: (mapcar # (lambda (x y z) (+ x y z)) (1 2 ) (10 20 0) (100 200 00)) => (111 222 ) Vi använder en generell komponent (mapcar), som specialiceras för ett givet ändamål. Funktion utförs för sin sidoeffekts skulle, inget intressant värde returneras: (mapc # print (anna kalle stina)) anna kalle stina

Anders Haraldsson 1 Anders Haraldsson 14 Applicerar en funktion på successiva svansar: (maplist # length (a b c d)) => (4 2 1) Finns den rekursiva processlösningsmallen som en högre ordningens funktion? Ja, funktionen reduce kan användas för listor. Villkorsfunktioner: gäller för alla?, gäller för någon?,... (some # numberp (a 1 b c)) => t (every # numberp (1 2 4)) => t (notany # numberp (a b c d)) => t (notevery # numberp (a b c 1 d)) => t Vissa vanliga funktioner finns i if och if-notvarianter: (member-if # numberp (a b 1 c d)) => t (remove-if # numberp (a b 1 c d)) => (a b c d) (remove-if-not # numberp (a b 1 c d)) => (1) (reduce fn lista :initial-value init :from-end t) om lista är (e 1 e 2 e.. e n-1 e n ) motsvaras detta av en högerassociativ reducering av listan med fn som operator. (fn e 1 (fn e 2 (fn e... (fn e n init)..))) Med (reduce fn lista :initial-value init) erhålls en vänsterassociativ reducering (fn (fn... (fn (fn e 1 e 2 ) e ).. e n-1 ) e n ) Anders Haraldsson 15 Anders Haraldsson 16 Hur beräknas? 1-2 - - 4 (((1-2) - ) - 4) =? (1 - (2 - ( - 4))) =? 4 2 (2 ) 4 =? ( 4 ) 2 =? (expt (expt 2 ) 4) = 4096 (expt 2 (expt 4)) = 2417851692292584941252 (expt 2 4) ger fel (måste vara två argument) Rekursiva processlösningsmallen: Vi beräknar: 1 + 2 + + 4 (((1 + 2) + ) + 4) (1 + (2 + ( + 4))) Högerassociativ (defun addera-h (l) 0 (+ (first l) (addera-h (rest l))))) (addera-h (1 2 4)) -> (+ 1 (+ 2 (+ (+ 4 0))) ; (1 + (2 + ( + 4))) (defun addera-h (l) (reduce # + l :initial-value 0 :from-end t)) Vänsterassociativ (defun addera-v (l) (if (endp (rest l)) (first l) (+ (addera-v (butlast l)) (first (last l))))) (defun addera-v (l) (reduce # + l :initial-value 0 :from-end nil)) (addera-v (1 2 4)) -> (+ (+ (+ 1 2) ) 4) ; (((1 + 2) + ) + 4)

Anders Haraldsson 17 Anders Haraldsson 18 Viktiga egenskaper hos operatorer eller funktioner kommutativ operator x op y y op x Operatorer: + * snitt union +4 är samma som 4+ union av mängder: {a b c} U {a c d e} = {a b c d e} är samma som {a c d e} U {a b c} = {a b c d e} associativ operator (x op y) op z x op (y op z) Kan därför oftast skrivas x op y op z (1 + 2) + är samma som 1 + (2 + ), som är 1+2+ högerassociativ operator x op y op z tolkas som (x op (y op z)) vänsterassociativ operator x op y op z tolkas som ((x op y) op z) Vilka krav har vi på operatorn/funktionen om vi kan använda samma vid rekursiv och iterativ processlösning. Rekursiv processlösning (defun f (l) värde (operator/funktion (first l) (f (rest l))))) Iterativ processlösning (defun f (l) (f-iter l värde )) (defun f-iter (l res) res (f-iter (rest l) (operator/funktion (first l) res)))) operatorn/funktionen skall vara kommutativ och associativ Anders Haraldsson 19 Anders Haraldsson 20 Rekursiv processlösning (defun sum (l) 0 (+ (first l) (f (rest l))))) (sum (1 2 4)) -> (+ 1 (+ 2 (+ (+ 4 0)))) 1 + 2 + + 4 Iterativ processlösning (defun sum (l) (f-iter l 0)) (defun f-iter (l res) res (f-iter (rest l) (+ (first l) res)))) (sum (1 2 4)) -> (+ 4 (+ (+ 2 (+ 1 0)))) Går det med -? Koll av egenskaper för funktionerna append och union Rekursiv processlösning (defun sätt-ihop (l) ; l är en lista med listor () (append (first l) (sätt-ihop (rest l))))) (sätt-ihop ((1 2) ( 4) (5))) -> (append (1 2) (append ( 4) (append (5) ()))) => (1 2 4 5) Iterativ processlösning (defun sätt-ihop (l) (sätt-ihop-iter l ())) (defun sätt-ihop-iter (l res) res (sätt-ihop-iter (rest l) (append (first l) res)))) (sätt-ihop ((1 2) ( 4) (5))) -> (append (5) (append ( 4) (append (1 2) ()))) => (5 4 1 2) Med union så blir det samma resultat, som mängd. Ordningen mellan elementen i en mängd har ingen betydelse.

Anders Haraldsson 21 Anders Haraldsson 22 Koll av egenskaper för funktionerna append och union append är ej kommutativ (append x y) är ej lika med (append y x) append är associativ (append x (append y z)) lika med (append (append x y) z) därför kan vi tillåta append ta godyckligt antal argument och inte behöva veta i vilken ordning de sätts samman. (append (1 2) ( 4) (5)) => (1 2 4 5) union är kommutativ och associativ (union x y) är lika med (union y x) Sammanfattning av rekursiva modeller. Vi har två diskretmatematiska begrepp sekvens, elementen följer efter varandra s 1 s 2 s... s 4 exempel: en sekvens med element i en lista (lisa kalle svea tore) en följd med tecken för att bilda ett ord kalle en följde med ord för att bilda en mening idag är det vacker väder binärt träd, elementen delas upp i två hälfter + * / 2 4-8 2 exempel: en lista sedd som punkterade par ett aritmetiskt uttryck, där en nod innehåller en operator Anders Haraldsson 2 Anders Haraldsson 24 Bearbetning av elementen i dessa två strukturer följer olika rekursiva mallar: Om vi definierar en funktion f som skall bearbeta en sekvens så har vi fallen: 1) vad skall vi göra för tomma sekvensen? 2) vad skall vi göra för operation på första elementet och det värde vi får då vi utför f på resten av sekvensen Om ett element i sekvensen i sin tur innehåller en sekvens får vi en mall med tre fall. Om vi definierar en funktion f som skall bearbeta ett binärt träd så har vi fallen: 1) vad skall vi göra för lövet? 2) vad skall vi göra för operation på det värde vi får från att utföra f på vänster delträd och det värde vi får från att utföra f på höger delträd Detta är generella algoritmer och används på många olika slags datasstrukturer. I denna kurs använder vi den först på vanliga Lisp-listor. Vi kan se listan som en representation av antingen en sekvens eller ett binärt träd. Sedan använder vi binära träd för att kunna representera och bearbeta formeluttryck. Vi iillustrerar listorna grafiskt med cons-celler och pekare. Listan sedd som en sekvens (utvidgat till att elementen kan vara en sekvens). Listor i listor. Dubbelrekursion. mall: (defun fn (l) ((endp l) init-värde ) ((atom (first l)) ( operation 1 (first l) (fn (rest l)))) (t ( operation 2 (fn (first l)) (fn (rest l)))) )) Listan sedd som binärt träd. I Lisp punkterade par. b a a c b nil d mall: (defun fn (bt) (if (atom bt) bearbetning lövet ( operation (fn (car bt)) (fn (cdr bt))))) c nil d (a (b c) d) (a. ((b. (c. nil)). (d. nil))

Anders Haraldsson 25 - Vi har lärt oss skriva algoritmer som bearbetar sekvenser och binär träd-strukturer. - Vi har identifierat olika typer av mallar eller mönster. - Vi kan traversera en sådan struktur, dvs gå igenom den element för element. Vi kan nu identifiera olika typer av algoritmmönster: sökning efter givet element (finns-bokstav? i Övn 118, forwardfind i Uppg 2B) mappning, transformera varje elements värde till ett nytt och skapa en struktur av samma slag. (positiva i Uppg 1A, högre ordningens funktion mapcar) filtrering, skapa en ny struktur med alla elementen som uppfyller ett villkor (ta-bort-vokaler i Uppg 119, filtrera i Uppg 1A, filter Övn 21) reduktion (ackumulering), t ex summera alla talen i en sekvens (räkna i Uppg 1A, högre ordningens funktion reduce) back-tracking, sök först bestäm sedan (efter-sista i Uppg 205, backfind i Uppg 2C) generering, från ett värde skapa nästa (generate-list i Uppg 2E)