Memoisering. I de følgende memoiseringeksemplene brukes tabeller, og vi tar derfor først en repetisjon av dette.

Størrelse: px
Begynne med side:

Download "Memoisering. I de følgende memoiseringeksemplene brukes tabeller, og vi tar derfor først en repetisjon av dette."

Transkript

1 Memoisering I de følgende memoiseringeksemplene brukes tabeller, og vi tar derfor først en repetisjon av dette. Vi definere en allmenn tabelltype ved en prosedyre med - tabellen som en lokal tilstandsvariabel, - lokale rutiner for å hente frem og legge inn data, samt - en meldingsbehandlingsprosedyre. (define (make-table) (let ((table (list *table-head*))) (define (lookup line-key col-key)...) (define (insert! line-key col-key value)...) (define (dispatch m) (cond ((eq? m 'lookup) lookup) ((eq? m 'insert!) insert!) (else (error "Unknown operation -- TABLE" m)))) dispatch)) 455

2 (define (lookup line-key col-key) (let ((line (assoc line-key (cdr table)))) (and line ; andre term evalueres bare hvis line #f. (let ((entry (assoc col-key (cdr line)))) (and entry (cdr entry)))))) ; andre term evalueres bare hvis entry #f. (define (insert! line-key col-key value) (let ((line (assoc line-key (cdr table)))) (if line (let ((entry (assoc col-key (cdr line)))) (if entry (set-cdr! entry value) (set-cdr! line ; fant ikke kolonnenøkkelen, (cons (cons col-key value) ; så vi legger inn en ny entry (cdr line))))) ; først på linjen (set-cdr! table ; fant ikke linjenøkkelen, (cons (list line-key ; en ny linje (cons col-key value)) ; med én enkelt entry (cdr table)))))))) ; først i tabellen 456

3 Ordet memoisere betegner det å høres ut som memorisere og minner om memorere, lagre resultatet av en regneoperasjon, slik at neste gang samme operasjon evt. skal utføres, så kan det allerede utregnede resultatet ganske enkelt hentes frem. Det må da dreie seg om - en bestemt type operasjoner, - og en tilsvarende prosedyre - som selv holder rede på de resultater som allerede foreligger. Exercise 3,27 (s. 272) i SICP dreier seg om memoisering av resultater fra beregning av fibonacci-tall, men vi tar en kort motiverende omvei der vi ser først på memoisering av resultater fra multiplikasjoner. Vi tenker oss et system for håndtering av valutatransaksjoner som - utfører en rekke divisjoner med et Liten vits i å gjøre dette hvis det er - begrenset utvalg av faktorer bestående av ulike valutakurser. en stor mengde mulige argumenter 457

4 For memoiseringen benytter vi en todimensjonal tabell. (define (memoize-div) (let ((table (make-table))) (lambda (x y) (let ((known-result ((table 'lookup) x y))) (or known-result ; enten fant vi det tidligere beregnede resultatet og returnerer det, (let ((result (/ x y))) ; eller så regner vi det ut nå, og ((table 'insert!) x y result); legger det inn i tabellen, result)))))) ; før vi returnerer det (define div (memoize-div)) (div 18 3) 6 (div 18 3) 6 Her ser vi ikke hva som foregår, men, om vi, for illustrasjonens skyld, bytter ut første term i or-uttrykket med (and known-result (cons 'memoized known-result)) og returverdien fra let-uttrykket med (cons 'computed known-result) får vi (div 18 3) (computed. 6) (div 18 3) (memoized. 6) NB! Dette er ikke det vi vil ha. Selv om memoisering innebærer tilstandsendring bak kulissene, fastholder vi det funksjonelle paradigmet og kravet om at samme argument skal gi samme resultat svekkes ikke. 458

5 Så til memoiseringen av fibonacci-tallene: Utgangspunktet er bokas opprinnelige rekursive, eksponensielt voksende, utgave av fibonacci-funksjonen. (define (fib n) (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2))))) De blå numrene angir kallrekkefølgen. 459

6 For å memoisere denne bruker vi en endimensjonal tabell med følgende (globale) prosedyrer: (define (make-table) (list '*table*)) (define (lookup key table) (let ((record (assoc key (cdr table)))) ; Verdien til record blir enten det vi evt. fant, eller #f. (and record (cdr record)))) ; (if record (cdr record) #f) (define (insert! key value table) (let ((record (assoc key (cdr table)))) (if record ; Fant vi en tidligere utregning av denne (set-cdr! record value) ; Erstatt tidligere med aktuell verdi * (set-cdr! table ; Ingen record her, så (cons (cons key value) ; sett inn ny med aktuell verdi (cdr table)))))) Vi er ikke interessert i noen returverdi fra insert! bare at tabelllen blir endret. * Denne hører med i den generelle tabellen, men er ikke relevant for dette eksempelet. Her kaller vi insert! bare for å sette inn nye verdier ikke for å endre ekstisterende. Set neste side. 460

7 En memoiseringsprosedyre for en hvilken som helst ett-arguments-prosedyre f kan skrives slik: (define (memoize f ) ; Det er resultatene av eventuelle kall på f som skal memoiseres. (let ((table (make-table))) ; Vi lager en omgivelse der både tabellen og f inngår. (lambda (x) (let ((result (lookup x table))) (or result ; Enten fant vi et tidligere utregnet resultat, og returnerer dette, * (let ((result (f x))) ; eller så må vi regne ut resultatet, og (insert! x result table) ; legge det i tabellen, result)))) ; før vi returnerer det. )) Et kall på memoize gir oss en prosedyre hvis lokale omgivelser inneholder funksjonen f og tabellen table. Det er denne prosedyren som returneres fra kallet på memoize i definisjonen av memo-fib på neste side. * Angående or-uttrykket over: (or a b) gir samme resultat som (if a a b). 461

8 Vi bruker memoize til å definere en prosedyre memo-fib, og som argument til memoize sender vi en variant av fibonacci-prosedyren der de rekursive kallene går via kall på memo-fib slik: (define memo-fib (let ((fib (lambda (n) ; fib = f i memoize (if (> n 2) n (+ (memo-fib (- n 1)) (memo-fib (- n 2))))) (memoize fib))) Merk at koden til prosedyreobjektet memo-fib ikke er fib, men derimot lambdauttrykket i memoize. De lokale omgivelsene til memo-fib er således memoize, der prosedyrevariabelen f bindes til fib ved kallet (memoize fib). Det rekursive kallet på memo-fib går dermed via kallet på f dvs fib i memoize. mens det rekursive kallet på fib går via kallet på memo-fib i fib. 462

9 463

10 Så gjenstår det bare å forklare hva som skjer når vi kaller memo-fib f.eks. slik: (memo-fib 5) Vi ser en gang til på rekursjonsmønstret for den opprinnelige versjonen: Det vi vil med memoiseringen er å utnytte det faktum at vi her har 15 rekursive kall med bare 6 ulike argumenter. Vi ser at kallkjeden går nedover langs venstregrenene fib(4), fib(3), fib(2), fib(1), og i og med høyre bladnode i nederst venstre subtre, fib(0) er alle de gjenværende kallene i treet alt uført. Merke at for hvert tidligere utført kall, kuttes hele subtreet. 464

11 Utsatt evaluering Skillet i Scheme mellom ordinære uttrykk og spesialformer angår bl.a. om, og evt. når, deler av sammensatte uttrykk evalueres. Regelen for applikativ evaluering sier at - alle deluttrykk i et sammensatt uttrykk må evalueres - før hele uttrykket kan evalueres (ved at første term anvendes på de øvrige), Men dette gjelder ikke for spesialformene, dvs. uttrykk som innledes med if, cond, and eller or. 465

12 Vi kan få til noe som ligner på spesialformer, ganske enkelt ved å pakke inn deluttrykk i spesialformen lambda uten argumenter. (define (pakket? exp) (procedure? exp)) Vi pakker ut et innpakket uttrykk ved å kalle det. (define (pakk-ut exp) (if (pakket? exp) (exp) ; pakk det ut, dvs. kall det. exp)) ; returnér det som det er Noen språk som Algol og Simula (som har bl.a. Algol som basis) har syntaks for såkalt navnoverføring av argumenter (call by name). Dette innebærer nettopp det vi snakker om her. Det uttrykket som (om nødvendig) må evalueres, for at et argument skal få sin verdi, kalles da en thunk. (pakk-ut (lambda () (+ 2 3))) 5 (pakk-ut (+ 2 3)) 5 (define pakket-sum (lambda () (+ 2 3))) pakket-sum #<procedure:pakket-sum> (pakket-sum) 5 (pakk-ut pakket-sum) 5 466

13 (define (test a b) (if (= (pakk-ut a) 0) 'a=zero (pakk-ut b))) (define a 2) (test a (/ 1 a)) ; ==> 1/2 (test (lambda () a) (lambda () (/ 1 a))) ; ==> 1/2 Nå kaller vi test og med et argumentet som garantert gir kjøreavbrudd, dersom det blir evaluert. (define a 0) (test a (/ 1 a)) ; ==> /: division by zero Men når vi pakker inn uttrykket, evaluerer selve pakken til en prosedyre, vi kommer inn i prosedyren, og siden a = 0, blir ikke uttrykket pakket ut (test (lambda () a) (lambda () (/ 1 a))) ; ==> a=zero 467

14 Vår utpakkingsprosedyre pakk-ut, skiller seg fra Schemes standardprosedyre for utpakking (som er den vi skal bruke etter hvert). For å kunne demonstrere test-prosedyren, har vi definert vår utpakkingsprosedyre slik at den aksepteres både uinpakkede og innpakkede argumenter, men som vi straks skal se: standardprosedyren for utpakking i Scheme aksepterer kun innpakkede argumenter. (Og dette er vel i og for seg rimelig. Det kunne ha virket forvirrende om f.eks. et argument av typen heltall skulle gi samme resultat som et argument av typen prosedyre.) 468

15 Vi kan ikke ha noen egen prosedyre for innpakking, ettersom "innpakkingen" da i seg selv ville ha forårsaket en evaluering, og dermed ødelagt hele poenget. Gitt en definisjon som (define (pakk-inn exp) (lambda () exp)) ville vi ved kallet (pakk-inn (+ 2 3)) først ha fått evaluert argumentet (+ 2 3) 5, slik at exp i kroppen til pakk-inn ble bundet til 5 og ikke til uttrykket (+ 2 3). 469

16 Men nå finnes det en spesialform for innpakking i Scheme, nemlig delay. Assossiert til denne er metaforparet løftegivning og -avtvinging. Vi sier at resultatet av en utsatt delayed evaluering, er et løfte om en fremtidig evaluering, og at dette løftet, om nødvendig, kan avtvinges. (define løfte (delay (+ 2 3))) løfte #<struct:promise> (promise? løfte) #t En annen utsett-fremtving-relasjon finner vi mellom quote og eval. (eval (quote (+ 2 3))) 5 (eval '(+ 2 3)) 5 Det er altså klare likheter mellom relasjonene quote eval, lambda kall og delay force, men det er også viktige forskjeller mellom dem. (force løfte) 5 (løfte) procedure application: expected procedure, given: #<struct:promise> (no arguments) Siste linje viser at delay, i motsetning til innpakking vha lambda, ikke returner en prosedyre. NB! dette gjelder Racket. Det finnes Scheme implementasjoner der et løfte ikke er en egen datatype men ganske enkelt er et lambda-objekt. 470

17 Primitiven force tar et løfte, laget av delay, som argument og avtvinger innfrielsenav dette om det da ikke alt var innfridd. Et løfte kan sees som et memoiserende prosedyreobjekt. Når uttrykket i løftet evalueres første gang, lagres resultatet i løftets omgivelser, slik at det gankske enkelt kan hentes frem ved eventuell senere bruk av force. Dette kan vi illustrere ved å legge et ekstra lag rundt uttrykket i form av en utskrift. Utskriften kommer bare ved evalueringen altså første gang løftet avtvinges. (define løfte (delay (begin (display 'yo) (+ 2 3)))) (force løfte) yo5 Her vises utskriften fra REPL. (force løfte) 5 Merk at display-setningen ikke bidrar til resultatet. Slike bieffekter (side effects) kan vi fremkalle i illustrasjonsøyemed, men i et program, ville vi aldri finne på å gjøre noe slikt i en sammenheng som denne. 471

18 En datatype der utsatt evaluering er helt essensielt, er en egen form for par der - car-delen alltid er umiddelbart tilgjengelig, mens - cdr-delen kun foreligger som et løfte om å produsere noe. Til dette formålet kan car virke som for vanlige par, mens vi trenger en cdr-selektor som tvinger cdr-delen til å innfri sitt løfte. (define (force-cdr pair) (force (cdr pair))) Det å utstyre et programmeringsspråk med mekanismer for utsatt evaluering, som call by name, se tekstboksen på s. 410, kan bl.a. begrunnes ut fra et ønske om å kunne sende potensielt tunge beregninger, som ikke nødvendigvis skal utføres, som argumenter til prosedyrer. Men det finnes også problemer for hvilke utsatt evaluering er inherent i løsningen, som f.eks. løsning av differensialligninger der vi må utsette evalueringen av integranden for overhodet å komme i gang. NB! Disse navnene er midlertidige. Vi skal etter hvert knytte denne typen par til strømmer, og der er navnene hhv. stream-car og stream-cdr. 472

19 Vi kan lage slike par etter to litt ulike prinsipper. Legg nøye merke til hva som er kall her: (define (gjenta) (cons 'jada (delay (gjenta)))) ; (1) gjenta ; ==> #<procedure:gjenta> (2) (gjenta) ; ==> (jada. #<struct:promise>) (3) (car (gjenta)) ; ==> jada (4) (car (force-cdr (gjenta))) ; ==> jada (5) (car (force-cdr (force-cdr (gjenta)))) ; ==> jada (6) I (4) ber vi om første element i det paret som ble generert av et kall på gjenta. I (5) ber vi om første element i det paret som ble generert av et gjentatt kall på gjenta. I (6) ber vi om første element i det paret som ble generert av andre gangs gjentatte kall på gjenta. 473

20 Se så på disse setningene. (define repetér (cons 'jada (delay repetér))) ; (7) repetér ; ==> (jada. #<struct:promise>) (8) (car repetér) ; ==> jada (9) (car (force-cdr repetér)) ; ==> jada (10) (car (force-cdr (force-cdr repetér))); ==> jada (11) Mens gjenta i (1) ble definert som en prosedyre som genererer et par, blir det tilsvarende objektet i (7) definert ganske enkelt som et par, men vel å merke, et par hvis cdr-del inneholder et løfte om gjentagelse. Vi kaller det siste en implisitt gjentaglse. Følgende, som er ekvivalent med (7), viser noe av det som foregår (define repetér (cons 'jada (12) (delay (cons 'jada (delay repetér))))) 474

21 I (9) ber vi ganske enkelt om første element i paret repetér. (car repetér) ; ==> jada (9) I (10) ber vi om første element i det paret som ble generert ved innfrielsen av løftet i andre del av paret repetér. (car (force-cdr repetér)) ; ==> jada (10) I (11) ber vi om første element i det paret som ble generert ved innfrielsen av løftet i andre del av innfrielsen av løftet i andre del av paret repetér. (car (force-cdr (force-cdr repetér))); ==> jada (11) Vi setter inn definisjonen av repetér i (10), etter at den utsatte evalueringen er utført: (car (cdr (cons 'jada (cons 'jada (delay repetér))))) (13) Tilsvarende kan vi, for å forstå hva som skjer i (11) gjøre enda en substitusjon. (car (cdr (cons 'jada (cons 'jada (cons 'jada (delay repetér)))))) (14) 475

22 Sammenlign (3) og (8) (gjenta) ; ==> (jada. #<struct:promise>) (3) repetér ; ==> (jada. #<struct:promise>) (8) Hvorfor trenger vi den eksplisitte formen når den ekslisitte og den implisitte formen her gir samme resultat? Poenget er at prosedyren i den eksplisitte formen gir mulighet for mer enn rene gjentagelser. Her er et eksempel der vi sender et argument til en gjentagelsesproduserende prosedyre og bruker dette i et regnestykke som gir en ny verdi til neste løfte. (define (heltall fra) (cons fra (delay (heltall (+ fra 1))))) ; (15) (car (heltall 1)) ; 1 (16) (car (force-cdr (heltall 1))) ; 2 (17) (car (force-cdr (force-cdr (heltall 1)))) ; 3 (18) 476

23 I neste eksempel ser vi på en liste av gjentatte gjentagelser. Vi kan samle opp et gitt antall gjentagelsene i en liste slik (define (gjenta->liste gjentagelse n) (if (= n 0) '() (cons (car gjentagelse) (gjenta->liste (force-cdr gjentagelse) (- n 1))))) (gjenta->liste (gjenta) 3) ; (jada jada jada) (gjenta->liste repetér 3) ; (jada jada jada) (gjenta->liste (heltall 1) 3) ; (1 2 3) Det er fullt mulig å definere en prosedyre som genererer et endelig antall gjentagelser. SICP inneholder en definisjon av en prosedyre som konverterer en strøm av gentagelser til en liste, uten å telle antall elementer. I stedet tester prosedyren for nil (vi skal straks se hva dette betyr). En slik prosedyre kan bare brukes på en endelig strøm. 477

24 Den indirekte (implisitte) formen er ikke særlig interessant alene, men den kan gi input til andre mer interessante gjentagelsesstrømmer. (define enere (cons 1 (delay enere))) (define toere (cons 2 (delay toere))) (define (tell n enheter) (cons n (delay (tell (+ n (car enheter)) (force-cdr enheter))))) (gjenta->liste (tell 1 enere) 10) ; ( ) (gjenta->liste (tell 1 toere) 10) ; ( ) (gjenta->liste (tell 2 toere) 10) ; ( ) Prosedyren tell synes å måtte gi en evig løkke, men pga. delay, produserer den bare ett nytt par for hver gang den blir kalt, og dette gjør den vha. første gjenværende ledd i strømmen enheter. 478

25 Egendefinerte spesialformer Det som mangler i vår implementasjon, er en konstruktor, men vi kan ikke definere noen prosedyre som tar som argument noe som (i første omgang) ikke skal evalueres. Det vi trenger er vår egen spesialform, og Scheme gir oss da også muligheten for å definere en slik. Vi kunne kalle vår egendefinerte spesialform cons-and-delay, men for å slippe å bytte navn i neste omgang kaller vi den cons-stream (som vi straks skal bruke til å lage strømmer). 479

26 En definisjon av en spesialform - innledes med ordet define-syntax, - fulgt av navnet på den formen vi skal definere, heretter kalt nøkkelordet. - Deretter følger reglene for transformasjon av vår spesialform til basisformer i Scheme. - Transformasjonsreglene inngår i en liste som - innledes med ordet syntax-rules - fulgt av en liste med eventuelle reserverte ord, - fulgt av en liste med én eller flere transformasjonsregler. En transformasjonsregel har formen (mønster utførelse). Mønsteret det evaluatoren skal gjenkjenne er - en liste med nøkkelordet, fulgt av - ingen, ett eller flere ord som er variabler i transformasjonsregelen. Utførelsen kan bektraktes som regelens kropp. Den består av - en eller flere Scheme-setninger der eventuelle variabler i mønsteret inngår. 480

27 Vi definerer formen hverken-eller (define-syntax hverken-eller ; Navnet på spesialformen (syntax-rules () ; Intet reservert ord ((hverken-eller test1 test2) ; Mønstret som skal gjenkjennes (not (or test1 test2))))) ; Malen (kroppen) som skal utføres (hverken-eller (= (+ 2 2) 4) (= (+ 2 2) 4)) ==> #f (hverken-eller (= (+ 2 2) 4) (= (+ 2 2) 5)) ==> #f (hverken-eller (= (+ 2 2) 3) (= (+ 2 2) 4)) ==> #f (hverken-eller (= (+ 2 2) 3) (= (+ 2 2) 5)) ==> #t begge er sanne det første er sant og det andre er usant det første er usant og det andre er sant begge er usanne I de to første uttrykkene evaluer den første termen til #t, og dermed er det ikke nødvendig å evaluere den andre. Vi legger inn en effekt og ser hva REPL gir (hverken-eller (display "hverken ") (display "eller ")) gir hverken #f (hverken-eller (not (display "hverken ")) (display "eller ")) gir hverken eller #f Returverdien fra display og andre effektprosedyrer er uspesifisert i R5RS, men den kan aldri være #f. 481

28 Følgende definisjon av en eksklusiv eller, gir ingen besparelse: (define-syntax enten-eller ; Navnet på spesialformen (syntax-rules () ; Intet reservert ord ((enten-eller test1 test2) ; Mønstret som skal gjenkjennes (or (and test1 (not test2)) ; Malen (kroppen) som skal utføres (and (not test1) test2))))) (enten-eller (= (+ 2 2) 4) 'månen-er-en-gul-ost) #f (enten-eller (= (+ 2 2) 3) 'månen-er-en-gul-ost) 'månen-er-en-gul-ost Uansett om første term evaluerer til #t eller #f, må den andre termen også evalueres, for å få sjekket om den evaluerer til det motsatte. 482

29 Mulig, men kanskje ikke særlig pent Ved å bruke et reservert ord så som eller kunne vi ha laget formene (hverken a eller b) og (enten a eller b). (define-syntax hverken ; Navnet på spesialformen (syntax-rules (eller) ; Reservert ord ((hverken test1 eller test2) ; Mønstret som skal gjenkjennes (not (or test1 test2))))) ; Malen (kroppen) som skal utføres (hverken #f eller #f) #t Her er eller en ren dekorasjon. Ordet dukker opp mellom to signifikante termer men er i og for seg uten betydning, og dermed får vi ikke noe S-uttrykk, der alle ledd evalueres og første ledd anvendes på de øvrige. 483

30 Definisjonen av cons-stream følger samme mønster. (define-syntax cons-stream ; Navnet på spesialformen (syntax-rules () ; Ingen andre reservert ord ((cons-stream obj stream) ; Mønstret som skal gjenkjennes (cons obj (delay stream))))) ; Malen (kroppen) som skal utføres Ved hjelp av cons-stream kan vi skrive om (1), (5) og (11) slik: (define (gjenta) (cons-stream 'jada (gjenta))) ; (1') (define repetér (cons-stream 'jada repetér)) ; (6') (define (tell fra) (cons-stream fra (tell (+ fra 1)))) ; (13') (define enere (cons-stream 1 enere)) Dette er strømmer, som har selektorene stream-car og stream-cdr. (define (stream-car obj) (car obj)) (define (stream-cdr obj) (force (cdr obj))) Med disse kan vi definere tellestrømmen slik: (define (tell n enheter) (cons-stream n (tell (+ n (stream-car enheter)) (stream-cdr enheter)))))) 484

31 Prosedyre for memoisering av prosedyrer Vi minner om syntaks-definisjonen av spesilaformen cons-stream over: (define-syntax cons-stream (syntax-rules () ((cons-stream obj stream) (cons obj (delay stream))))) Spesilaformen delay skal være definert i Scheme (i hht. R5RS), men om den ikke var det, kunne vi ha definert den selv slik: (define-syntax delay (syntax-rules () ((delay expression) (memo-proc ; se under (lambda () expression))))) 485

32 Prosedyren memo-proc (se under) tar som argument en argumentløs prosedyre, en"lambda-pakke", med et eller annet uttrykk som kropp og returnerer en prosedyre som tar ingen, ett eller flere argumenter, og som har to lokale variabler: - én for lagring av et eventuelt ferdig beregnet resultat fra det innpakkede uttrykket og - én for å holde rede på om uttrykket er evaluert eller ikke. Første gang det innpakkede uttrykket evalueres, lagres resultatet resultat-variabelen, før det returneres. Alle eventuelle etterfølgende ganger returneres det lagrede resultatet. Legg for øvrig merke til følgende: (define p (cons 1 (delay 2))) p ==> (1. #<promise:xxx>) (force (cdr p)) ==> 2 p ==> (1. #<promise:2>) Et avtvunget løftet er fortsatt et løfte. 486

33 Neste gang prosedyren kalles, returneres ganske enkelt det tildligere beregnede resulatet. (define (memo-proc lambda-wrapped-expression) (let ((already-run? #f) ; begge disse verdiene gjelder bare frem til første kall, (result #f)) ; bortsett fra at det faktiske resultatet kan være #f, og ; det er derfor vi trenger et eget flagg for om evalueringen alt er gjort (lambda () (if already-run? result Merk forskjellen mellom (begin (set! already-run? #t) (set! result (lambda-wrapped-expression))); utfør det innpakede uttrykket result))) - den argumentløse prosedyren som sendes til memo-proc, og - det uttrykket som er pakket inn i denne prosedyren. Det siste kan godt være et kall på en prosedyre som tar argumenter. 487

34 I SICP Exercise 3.52 og 3.53 dreier det seg om å se hva som foregår, når en strøm produseres, og det kan da være greit å kunne slå memoiseringen av og på. For å få til dette definerer vi vår egen utgave av delay sammen med en hjelpeprosedyre og en global variabel: (define *memoize* #t) (define (set-memoize! on/off)(set! *memoize* on/off)) (define-syntax delay (syntax-rules () ((delay expression) (if *memoize* (memo-proc (lambda () expression)) (lambda () expression))))) Som vi ser, er *memoize* et globalt flagg som bestemmer om delay skal memoisere eller ikke, og som vi kan heise og fire vha set-memoize! 488

35 NB! delay skaper et objekt av typen promise som er den eneste typen force aksepterer, så når vi definerer vår egen delay, må vi også definere vår egen force. (define (force expression) (expression)) ; utfør kallet Her er et eksempel på hvordan dette virker: (define (vis-og-returner noe) (display " ") (display noe) noe) (define (effekt-tall fra) (cons-stream (vis-og-returner fra) (effekt-tall (+ fra 1)))) (define noen-tall (effekt-tall 1)) 489

36 Følgende kall gir følgende effekter og returverdier (stream->list noen-tall 5) ( ) ; Fra REPL: ( ) (stream->list noen-tall 5) ( ) ; Fra REPL: ( ) Vi merker oss at vi bare får effekt første gang de tre løftene etter første element i noen-tall avkreves. Så slår vi av memoiseringen og ser hva som skjer. (set-memoize! #f) (define noen-tall (effekt-tall 1)) (stream->list noen-tall 5) ( ) ; Fra REPL: ( ) (stream->list noen-tall 5) ( ) ; Fra REPL: ( ) 490

37 Strømmer Mens en liste er en sekvens av et gitt antall objekter, er en strøm både en sekvens og en prosess., og mens en gitt liste til enhver tid har et gitt, endelig, antall elementer, har en strøm har til enhver tid enda ett element. Dette gjelder uendelige strømmer. Det går også an å lage endelige strømmer. Poenget med en strøm er at dens elementer produseres ettersom vi aksesserer dem. Altså, mens en liste foreligger i sin helhet med et endelig antall elementer, foreligger en strøm bare element for element, men med et i prinsippet uendelig antall elementer. Og når vi på fullt alvor kan snakke om strømmer i datamaskinprogrammer som uendelige størrelser, så er det nettopp fordi en strøm aldri realiseres i sin helhet. 491

38 Sekvensierte versus sammenpakkede prosesser Vi har tidligere sett hvordan vi kan løse sammensatte problemer ved hjelp av en sekvens av prosesser. F. eks. for å summere kvadratene av alle primtall i et gitt intervall, kan vi - generere sekvensen av alle tallene i intervallet, - filtrere ut ikke-primtallene fra denne sekvensen, - kvadrere de filtrerte tallene, og til slutt - summere de kvadrerte tallene. Dette gir greie og oversiktlige løsninger, men arbeidsmengden i en slik sekvens lett blir større enn om man hadde slått sammen flest mulig prosesser i en og samme iterasjon. Ikke minst ville man på den måten kunne unngå å generere en masse verdier som i siste instans allikevel ikke ville bli brukt. 492

39 Følgende eksempel illustrerer dette. Komprimert løsning: (define (sum-kvadrerte-primtall a b) (define (iter n sum) (cond ((> n b) sum) ((prime? n) (iter (+ n 1) (+ (kvadrat n) sum))) (else (iter (+ n 1) sum)))) (iter a 0)) Sekvens av sekvensielle prosesser: (define (sum-kvadrerte-primtall a b) (accumulate + 0 (map kvadrat (filter prime? (enumerer a b))))) Et, for visse formål, vesentlig aspekt ved den siste er at den i langt større grad enn den første likner en rent fysisk signalstrøm. 493

40 Mens den komprimerte løsningen klarer seg med telleren og summen (siden iter er halerekursiv, får vi ingen rekursjonsstack), må liste-til-liste-løsningen generere hele heltallssekvensen, før den kan begynne å lete etter heltall. Deretter produserer filtreringsprosedyren en ny sekvens og mappingprosedryen enda en, før akkumulatoren kan beregne summen. Ved hjelp av strømmer kan vi slå to fluer i en smekk, idet vi beholder sekvensen av atskilte prosesser, samtidig som vi ikke utfører flere beregninger enn det vi ville ha gjort med en hvilken som helst kompakt løsning. 494

41 Utsatt evaluering og memoisering Det magiske løsen her er utsatt evaluering og memoisering. Vi tenker oss at vi skal plukke ut ett og ett - primtallet fra listen av heltallene fra 10 til Slik lister er operasjonalisert i Scheme, måtte alle listens elementer genereres, før vi kunne gå videre i prosessen, uansett hvor mange eller få primtall vi ønsket. Her plukker vi ut det andre primtallet 10 (altså 13). (car (cdr (filter prime? (enumerate )))) I læreboken startes det på 1 000, men vi starter før, for å kunne kjenne igjen primtallene. 495

42 Fra strømmen av heltall fra 10 til kan jeg imidlertid plukke ut det andre primtallet, uten at det genereres mer enn fire tall. Ved hjelp av konstruktoren cons-stream og selektoren stream-car og stream-cdr kan vi definere ekvivalenter til alle de typiske listeoperasjonene som seleksjon mapping, filtrering, akkumulering, etc, slik at strømmer og lister, fra en funksjonell betraktning, er ekvivalente. (stream-car (stream-cdr (stream-filter prime? (stream-enumerate )))) Dette er helt parallelt til det liste-baserte uttrykket over. 496

43 Vi minner om at - første gjenværende elementet i en strøm alltid er tilgjengelig vha. stream-car, mens det - for andre gjenværende elementet bare foreligger et løfte som vi må avtvinge, for å få tak i elementet. Med dette for øye kan vi se hva som foregår bak kulissene under evalueringen av uttrykket over. - Kallet (stream-cdr (stream-filter...)), tvinger stream-filter til å produsere sitt andre tall, men før dette kan skje, må stream-filter ha fått tilstrekkelig mange tall fra stream-enumerate. - For å kunne produsere sitt andre tall, må stream-filter - først hente (ikke tvinge) første tall fra stream-enumerate og - deretter tvinge stream-enumerate til å produsere sitt andre tall. 497

44 Dette gir hhv. tallene 10 og 11, hvorav stream-filter vraker det første og aksepterer det andre som det dermed kan levere fra seg som sitt første tall. - Nå er stream-filter klar til å produsere sitt andre tall, som det får ved først å avtvinge stream-enumerate dens neste tall, 12, som, vrakes, og deretter 13, som aksepteres, slik at stream-filter kan levere det fra seg som sitt andre tall. - Dermed mottar stream-cdr resten av strømmen fra og med andre primtall mellom 10 og fra stream-filter og levere det første av disse, 13, til stream-car. 498

Memoisering. I de følgende memoiseringeksemplene brukes tabeller, og vi tar derfor først en repetisjon av dette.

Memoisering. I de følgende memoiseringeksemplene brukes tabeller, og vi tar derfor først en repetisjon av dette. Memoisering I de følgende memoiseringeksemplene brukes tabeller, og vi tar derfor først en repetisjon av dette. Vi definere en allmenn tabelltype ved en prosedyre med - tabellen som en lokal tilstandsvariabel,

Detaljer

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 En Scheme-evaluator i Scheme, del 2 Erik Velldal Universitetet i Oslo 7. mai 2015 Tema Forrige uke SICP 4.1. Structure and interpretation

Detaljer

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

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme, del 2 INF2810: Funksjonell Programmering En Scheme-evaluator i Scheme, del 2 Erik Velldal Universitetet i Oslo 4. mai 2017 Tema 2 Forrige uke SICP 4.1. Structure and interpretation of computer programs Metacircular

Detaljer

Memoisering, utsatt evaluering og strømmer

Memoisering, utsatt evaluering og strømmer Memoisering, utsatt evaluering og strømmer Først litt repetisjon: Utsatt evaluering Gitt (define (p x) (if test (x) something-else)) la E være et Scheme-uttrykk, og la L = (lambda () E). Da vil, ved kallet

Detaljer

Memoisering, utsatt evaluering og strømmer

Memoisering, utsatt evaluering og strømmer Memoisering, utsatt evaluering og strømmer Først litt repetisjon: Utsatt evaluering Gitt (define (p x) (if test (x) something-else)) la E være et Scheme-uttrykk, og la L = (lambda () E). Da vil, ved kallet

Detaljer

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

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme, del 2 INF2810: Funksjonell Programmering En Scheme-evaluator i Scheme, del 2 Erik Velldal Universitetet i Oslo 4. mai 2017 Tema 2 Forrige uke SICP 4.1. Structure and interpretation of computer programs Metacircular

Detaljer

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

INF2810: Funksjonell Programmering. En metasirkulær evaluator, del 2 INF2810: Funksjonell Programmering En metasirkulær evaluator, del 2 Stephan Oepen & Erik Velldal Universitetet i Oslo 03. mai 2013 Tema 2 Forrige uke SICP 4.1. Structure and interpretation of computer

Detaljer

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

INF2810: Funksjonell Programmering. En metasirkulær evaluator, del 2 INF2810: Funksjonell Programmering En metasirkulær evaluator, del 2 Stephan Oepen & Erik Velldal Universitetet i Oslo 03. mai 2013 Tema 2 Forrige uke SICP 4.1. Structure and interpretation of computer

Detaljer

INF2810: Funksjonell Programmering. Strømmer og utsatt evaluering

INF2810: Funksjonell Programmering. Strømmer og utsatt evaluering INF2810: Funksjonell programmering INF2810: Funksjonell Programmering Strømmer og utsatt evaluering Erik Velldal Universitetet i Oslo 5. april 2016 Forrige forelesning Mer om (prosedyre)navn, bindinger,

Detaljer

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

Gjennomgåelse av eksamensoppgaven i HUMIT2710 fra våren 2004 Gjennomgåelse av eksamensoppgaven i HUMIT2710 fra våren 2004 Oppgave 1 For å komme nærmere kvadratroten til et tall fra en foreløpig tilnærming y, kan vi bruke formelen (y + /y)/2. Dette gir grunnlag for

Detaljer

INF2810: Funksjonell Programmering. Strømmer og utsatt evaluering

INF2810: Funksjonell Programmering. Strømmer og utsatt evaluering INF2810: Funksjonell Programmering Strømmer og utsatt evaluering Stephan Oepen Universitetet i Oslo 30. mars 2017 Forrige forelesning 2 Mer om (prosedyre)navn, bindinger, og verditilordning Nok en ny abstrakt

Detaljer

INF2810: Funksjonell Programmering. Mer om strømmer

INF2810: Funksjonell Programmering. Mer om strømmer INF2810: Funksjonell Programmering Mer om strømmer Stephan Oepen & Erik Velldal Universitetet i Oslo 19. april 2013 Tema 2 Forrige uke Repetisjon: parallelitet Noe helt nytt: strømmer Noe quizzaktivitet

Detaljer

INF2810: Funksjonell Programmering. Mer om strømmer

INF2810: Funksjonell Programmering. Mer om strømmer INF2810: Funksjonell Programmering Mer om strømmer Stephan Oepen & Erik Velldal Universitetet i Oslo 19. april 2013 Tema 2 Forrige uke Repetisjon: parallelitet Noe helt nytt: strømmer Noe quizzaktivitet

Detaljer

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

INF2810: Funksjonell Programmering. Mer om verditilordning og muterbare data. INF2810: Funksjonell Programmering Mer om verditilordning og muterbare data. Erik Velldal Universitetet i Oslo 16. mars 2017 De siste ukene: destruktive operasjoner 2 set! endrer verditilordningen til

Detaljer

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

INF2810: Funksjonell Programmering. Mer om verditilordning. Tabeller. Og strømmer. INF2810: Funksjonell programmering INF2810: Funksjonell Programmering Mer om verditilordning. Tabeller. Og strømmer. Erik Velldal Universitetet i Oslo 29. mars 2016 De siste ukene: destruktive operasjoner

Detaljer

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

INF2810: Funksjonell Programmering. Mer om verditilordning og muterbare data. INF2810: Funksjonell Programmering Mer om verditilordning og muterbare data. Erik Velldal Universitetet i Oslo 16. mars 2017 De siste ukene: destruktive operasjoner 2 set! endrer verditilordningen til

Detaljer

INF2810: Funksjonell Programmering. Kommentarer til prøveeksamen

INF2810: Funksjonell Programmering. Kommentarer til prøveeksamen INF2810: Funksjonell programmering INF2810: Funksjonell Programmering Kommentarer til prøveeksamen Erik Velldal Universitetet i Oslo 1: Grunnleggende (6 poeng)? (define foo '(a b))? (define bar foo)? (set!

Detaljer

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

(define (naer-nok-kuberot? y x) (< (abs (- (kube y) x)) 0.001)) (define (naermere-kuberot y x) (/ (+ (* y 2) (/ x (kvadrat y))) 3)) Oppgave 1 For å komme nærmere kuberoten (tredjeroten) til et tall x fra en foreløpig tilnærming y, kan vi bruke formelen (2y + x/y 2 )/3. Skriv prosedyrene (nær-nok-kuberot? y x), (nærmere-kuberot y x)

Detaljer

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

INF2810: Funksjonell Programmering. Mer om verditilordning. Tabeller. Og strømmer. INF2810: Funksjonell Programmering Mer om verditilordning. Tabeller. Og strømmer. Erik Velldal Universitetet i Oslo 29. mars 2016 De siste ukene: destruktive operasjoner 2 set! endrer verditilordningen

Detaljer

INF2810: Funksjonell Programmering. Utsatt evaluering og strømmer

INF2810: Funksjonell Programmering. Utsatt evaluering og strømmer INF2810: Funksjonell Programmering Utsatt evaluering og strømmer Erik Velldal Universitetet i Oslo 12. april 2016 Tema 2 Forrige gang Ny datastruktur, ny teknikk: Strømmer Utsatt evaluering Uendelige sekvenser

Detaljer

INF2810: Funksjonell Programmering. En metasirkulær evaluator

INF2810: Funksjonell Programmering. En metasirkulær evaluator INF2810: Funksjonell Programmering En metasirkulær evaluator Stephan Oepen & Erik Velldal Universitetet i Oslo 26. april 2013 Tema 2 Forrige uke Strømmer og utsatt evaluering Memoisering Kort om makroer

Detaljer

INF2810: Funksjonell Programmering. Utsatt evaluering og strømmer

INF2810: Funksjonell Programmering. Utsatt evaluering og strømmer INF2810: Funksjonell Programmering Utsatt evaluering og strømmer Stephan oepen Universitetet i Oslo 6. april 2017 Tema 2 Forrige gang Ny datastruktur, ny teknikk: Strømmer Utsatt evaluering I dag Uendelige

Detaljer

INF2810: Funksjonell Programmering. En metasirkulær evaluator

INF2810: Funksjonell Programmering. En metasirkulær evaluator INF2810: Funksjonell Programmering En metasirkulær evaluator Stephan Oepen & Erik Velldal Universitetet i Oslo 26. april 2013 Tema 2 Forrige uke Strømmer og utsatt evaluering Memoisering Kort om makroer

Detaljer

INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering INF2810: Funksjonell Programmering Høyereordens prosedyrer, lambda og lokale variabler Erik Velldal Universitetet i Oslo 9. februar 2017 Tema 2 Forrige uke Lister og listerekursjon quote Høyereordens prosedyrer

Detaljer

Eksamen i SLI230, vår 2003.

Eksamen i SLI230, vår 2003. Eksamen i SLI230, vår 2003. Oppgavesettet har 8 sider medregnet denne forsiden. Ingen hjelpemidler er tillatt. Vedlegg: To sider som inneholder en liste over primitiver fra scheme (og simply.scm) samt

Detaljer

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO UNIVERSITETET I OSLO Det matematisk-naturvitenskapelige fakultet Eksamen i: INF2810 Eksamensdag: Fredag 5. juni 2015 Tid for eksamen: 14:30 (4 timer) Oppgavesettet er på 4 sider (ikke medregnet denne siden)

Detaljer

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme INF2810: Funksjonell Programmering En Scheme-evaluator i Scheme Erik Velldal Universitetet i Oslo 19. april 2016 Tema 2 Forrige uke Strømmer og utsatt evaluering Kort om makroer I dag Kap. 4 Metasirkulær

Detaljer

INF2810: Funksjonell Programmering. Utsatt evaluering og strømmer

INF2810: Funksjonell Programmering. Utsatt evaluering og strømmer INF2810: Funksjonell programmering INF2810: Funksjonell Programmering Utsatt evaluering og strømmer Erik Velldal Universitetet i Oslo 12. april 2016 Tema Forrige gang Ny datastruktur, ny teknikk: Strømmer

Detaljer

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO UNIVERSITETET I OSLO Det matematisk-naturvitenskapelige fakultet Eksamen i: INF2810 Eksamensdag: 5. juni, 2014 Tid for eksamen: 14:30 (4 timer) Oppgavesettet er på 4 sider. Vedlegg: Ingen Tillatte hjelpemidler:

Detaljer

INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering INF2810: Funksjonell Programmering Høyereordens prosedyrer, lambda og lokale variabler Erik Velldal Universitetet i Oslo 9. februar 2017 Tema 2 Forrige uke Lister og listerekursjon quote Høyereordens prosedyrer

Detaljer

INF2810: Funksjonell Programmering. Utsatt evaluering og strømmer

INF2810: Funksjonell Programmering. Utsatt evaluering og strømmer INF2810: Funksjonell Programmering Utsatt evaluering og strømmer Stephan oepen Universitetet i Oslo 6. april 2017 Tema 2 Forrige gang Ny datastruktur, ny teknikk: Strømmer Utsatt evaluering I dag Uendelige

Detaljer

INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering INF2810: Funksjonell Programmering Høyereordens prosedyrer, lambda og lokale variabler Stephan Oepen Universitetet i Oslo 9. februar 2015 Tema 2 Forrige uke Lister og listerekursjon quote Høyereordens

Detaljer

INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering INF2810: Funksjonell Programmering Høyereordens prosedyrer, lambda og lokale variabler Stephan Oepen Universitetet i Oslo 9. februar 2015 Tema 2 Forrige uke Lister og listerekursjon quote Høyereordens

Detaljer

Høyere-ordens prosedyrer

Høyere-ordens prosedyrer INF2810: Funksjonell programmering Høyere-ordens prosedyrer Stephan Oepen & Erik Velldal Universitetet i Oslo 8. februar, 2013 Tema 2 Forrige uke Lister og listerekursjon Høyere-ordens prosedyrer Prosedyrer

Detaljer

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

Rekursjon og lister. Stephan Oepen & Erik Velldal. 1. februar, Universitetet i Oslo INF2810: Funksjonell programmering Rekursjon og lister Stephan Oepen & Erik Velldal Universitetet i Oslo 1. februar, 2013 Agenda 2 Forrige uke Scheme Substitusjonsmodellen Blokkstruktur Predikater Kondisjonale

Detaljer

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme INF2810: Funksjonell Programmering En Scheme-evaluator i Scheme Erik Velldal Universitetet i Oslo 27. april 2017 Tema 2 Forrige forelesning Strømmer og utsatt evaluering Kort om makroer I dag Kap. 4 Metasirkulær

Detaljer

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

INF2810: Funksjonell programmering: Mer om Scheme. Rekursjon og iterasjon. INF2810: Funksjonell programmering: Mer om Scheme. Rekursjon og iterasjon. Stephan Oepen & Erik Velldal Universitetet i Oslo 25. januar, 2013 På blokka 2 Forrige uke Introduksjon og oversikt Funksjonell

Detaljer

INF2810: Funksjonell Programmering. Dataabstraksjon og Trerekursjon

INF2810: Funksjonell Programmering. Dataabstraksjon og Trerekursjon INF2810: Funksjonell Programmering Dataabstraksjon og Trerekursjon Stephan Oepen & Erik Velldal Universitetet i Oslo 15. februar, 2013 Tema 2 Forrige uke Høyere-ordens prosedyrer: Prosedyrer som argumenter

Detaljer

Eksamen i HUMIT 2710, Funksjonell programmering, våren Ingen hjelpemidler er tillatt. <resten av forsiden> Side 1 av 7

Eksamen i HUMIT 2710, Funksjonell programmering, våren Ingen hjelpemidler er tillatt. <resten av forsiden> Side 1 av 7 Eksamen i HUMIT 2710, Funksjonell programmering, våren 2005 Ingen hjelpemidler er tillatt. Side 1 av 7 Oppgave 1 Rekursjon Fakultetsfunksjonen, her kalt Fak, kan defineres rekursivt

Detaljer

INF2810: Funksjonell Programmering. Lister og høyereordens prosedyrer

INF2810: Funksjonell Programmering. Lister og høyereordens prosedyrer INF2810: Funksjonell programmering INF2810: Funksjonell Programmering Lister og høyereordens prosedyrer Erik Velldal Universitetet i Oslo 5. februar 2015 Agenda Forrige uke Substitusjonsmodellen og evalueringsstrategier.

Detaljer

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

INF2810: Funksjonell Programmering. Lokale variabler. Og trær. INF2810: Funksjonell Programmering Lokale variabler. Og trær. Erik Velldal Universitetet i Oslo 11. september 2019 Tema forrige uke 2 Lister som datastruktur quote Rekursjon på lister Høyereordens prosedyrer

Detaljer

INF2810: Funksjonell Programmering. Lister og høyereordens prosedyrer

INF2810: Funksjonell Programmering. Lister og høyereordens prosedyrer INF2810: Funksjonell Programmering Lister og høyereordens prosedyrer Erik Velldal Universitetet i Oslo 2. februar 2017 Agenda 2 Forrige uke Substitusjonsmodellen og evalueringsstrategier. Blokkstruktur

Detaljer

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

INF2810: Funksjonell Programmering. Lokale variabler. Og trær. INF2810: Funksjonell Programmering Lokale variabler. Og trær. Erik Velldal Universitetet i Oslo 11. september 2019 Tema forrige uke 2 Lister som datastruktur quote Rekursjon på lister Høyereordens prosedyrer

Detaljer

Innlevering 2b i INF2810, vår 2017

Innlevering 2b i INF2810, vår 2017 Innlevering 2b i INF2810, vår 2017 Dette er del to av den andre obligatoriske oppgaven i INF2810. Man kan oppnå 10 poeng for oppgavene i 2b, og man må ha minst 12 poeng tilsammen for 2a + 2b for å få godkjent.

Detaljer

INF2810: Funksjonell Programmering. Eksamensforberedelser

INF2810: Funksjonell Programmering. Eksamensforberedelser INF2810: Funksjonell Programmering Eksamensforberedelser Stephan Oepen & Erik Velldal Universitetet i Oslo 24. mai 2013 I dag 2 Kort oppsummering Praktisk om eksamen Hvem vant konkurransen om flest oblig-poeng

Detaljer

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO Side 1 UNIVERSITETET I OSLO Det matematisk-naturvitenskapelige fakultet Eksamen i: INF2810 Eksamensdag: 7. juni Tid for eksamen: 14.30 Oppgavesettet er på 5 sider Vedlegg Relevante prosedyrer Tillatte

Detaljer

INF2810: Funksjonell Programmering. Tilstand og verditilordning

INF2810: Funksjonell Programmering. Tilstand og verditilordning INF2810: Funksjonell Programmering Tilstand og verditilordning Stephan Oepen Universitetet i Oslo 2. mars 2017 Forrige gang 2 I dag 3 Vi blar om til kapittel 3 i SICP. Tilstand og verditilordning. Destruktive

Detaljer

INF2810: Funksjonell Programmering. Strømmer

INF2810: Funksjonell Programmering. Strømmer INF2810: Funksjonell Programmering Strømmer Stephan Oepen & Erik Velldal Universitetet i Oslo 12. april 2013 Tema 2 Forrige uke Litt mer i dybden om køer Eksperiment: live-programmering Tabeller som hierarkiske

Detaljer

INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering INF2810: Funksjonell Programmering Omgivelsesmodeller og destruktive listeoperasjoner Stephan Oepen & Erik Velldal Universitetet i Oslo 15. mars 2013 Tema 2 Forrige uke Representasjon av mengder Sorterte

Detaljer

INF2810: Funksjonell Programmering. Strømmer

INF2810: Funksjonell Programmering. Strømmer INF2810: Funksjonell Programmering Strømmer Stephan Oepen & Erik Velldal Universitetet i Oslo 12. april 2013 Tema 2 Forrige uke Litt mer i dybden om køer Eksperiment: live-programmering Tabeller som hierarkiske

Detaljer

INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering INF2810: Funksjonell Programmering Omgivelsesmodeller og destruktive listeoperasjoner Stephan Oepen & Erik Velldal Universitetet i Oslo 15. mars 2013 Tema 2 Forrige uke Representasjon av mengder Sorterte

Detaljer

Par og Lister (først et par sider fra forrige uke) Par er byggestener for lister og trær og sammensatte datatyper.

Par og Lister (først et par sider fra forrige uke) Par er byggestener for lister og trær og sammensatte datatyper. Par og Lister (først et par sider fra forrige uke) Par er byggestener for lister og trær og sammensatte datatyper. Par kan representeres grafiske slik: Som vi ser kan vi bruke cons til å lage par hvis

Detaljer

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.

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. 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. (define (f a) (lambda (b) (add a b ))) b. Skriv g, uten å

Detaljer

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

INF2810: Funksjonell Programmering. Køer, tabeller, og (litt om) parallelitet INF2810: Funksjonell Programmering Køer, tabeller, og (litt om) parallelitet Stephan Oepen & Erik Velldal Universitetet i Oslo 5. april 2013 Tema 2 Siste gang Kort om underveisevaluering Destruktive listeoperasjoner

Detaljer

INF2810: Funksjonell Programmering. Tilstand og verditilordning

INF2810: Funksjonell Programmering. Tilstand og verditilordning INF2810: Funksjonell Programmering Tilstand og verditilordning Stephan Oepen Universitetet i Oslo 8. mars 2016 Forrige gang 2 I dag 3 Vi blar om til kapittel 3 i SICP. Tilstand og verditilordning. Destruktive

Detaljer

INF2810: Funksjonell Programmering. Tilstand og verditilordning

INF2810: Funksjonell Programmering. Tilstand og verditilordning INF2810: Funksjonell Programmering Tilstand og verditilordning Erik Velldal Universitetet i Oslo 1. mars 2018 Forrige gang 2 Kode som trær 3 Ved evaluering oversettes kildekoden i et språk først til et

Detaljer

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO Side 1 UNIVERSITETET I OSLO Det matematisk-naturvitenskapelige fakultet Eksamen i: INF2810 Eksamensdag: 6. juni Tid for eksamen: 14.30 Oppgavesettet er på 4 sider pluss vedlegg Tillatte hjelpemiddel: Ingen

Detaljer

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

INF2810: Funksjonell Programmering. Køer, tabeller, og (litt om) parallelitet INF2810: Funksjonell Programmering Køer, tabeller, og (litt om) parallelitet Stephan Oepen & Erik Velldal Universitetet i Oslo 5. april 2013 Tema 2 Siste gang Kort om underveisevaluering Destruktive listeoperasjoner

Detaljer

Appendiks A Kontinuasjoner

Appendiks A Kontinuasjoner Appendiks A Kontinuasjoner Fra R5RS: "Whenever a Scheme expression is evaluated there is a continuation wanting the result of the expression." Eller med andre ord: En kontinuasjon i et program under utførelse

Detaljer

Innlevering 2a i INF2810, vår 2017

Innlevering 2a i INF2810, vår 2017 Innlevering 2a i INF2810, vår 2017 Hovedtematikken denne gang er Huffman-koding, som ble dekket i 6. forelesning (23. februar) og i seksjon 2.3.4 i SICP. Det er viktig å ha lest denne seksjonen før dere

Detaljer

INF2810: Funksjonell Programmering. Tilstand og verditilordning

INF2810: Funksjonell Programmering. Tilstand og verditilordning INF2810: Funksjonell programmering INF2810: Funksjonell Programmering Tilstand og verditilordning Erik Velldal Universitetet i Oslo 26. februar 2015 Forrige gang 2 I dag Vi blar om til kapittel 3 i SICP.

Detaljer

INF2810: Funksjonell Programmering. Mengder og lokal tilstand

INF2810: Funksjonell Programmering. Mengder og lokal tilstand INF2810: Funksjonell Programmering Mengder og lokal tilstand Stephan Oepen & Erik Velldal Universitetet i Oslo Kvinnedagen, 2013 Forrige gang 2 Dagens dont 3 Del 1 Litt mer om hierarkisk data. Representasjon

Detaljer

INF2810: Funksjonell Programmering. Trær og mengder

INF2810: Funksjonell Programmering. Trær og mengder INF2810: Funksjonell programmering INF2810: Funksjonell Programmering Trær og mengder Erik Velldal Universitetet i Oslo 19. februar 2015 Tema Forrige uke Høyereordens prosedyrer lambda, let og lokale variabler

Detaljer

INF2810: Funksjonell Programmering. Trær og mengder

INF2810: Funksjonell Programmering. Trær og mengder INF2810: Funksjonell Programmering Trær og mengder Stephan Oepen Universitetet i Oslo 16. februar 2017 Tema 2 Forrige uke Høyereordens prosedyrer lambda, let og lokale variabler Dataabstraksjon I dag Lister

Detaljer

LISP PVV-kurs 25. oktober 2012

LISP PVV-kurs 25. oktober 2012 LISP PVV-kurs 25. oktober 2012 Hva er Lisp? Grunnleggende konsepter Variabler (Pause) Lister Løkker Funksjoner Oversikt over kurset Først: Få tak i en implementasjon av Common Lisp Mange implementasjoner

Detaljer

INF2810: Funksjonell Programmering. Trær og mengder

INF2810: Funksjonell Programmering. Trær og mengder INF2810: Funksjonell Programmering Trær og mengder Stephan Oepen Universitetet i Oslo 16. februar 2016 Tema 2 Forrige uke Høyereordens prosedyrer lambda, let og lokale variabler Dataabstraksjon I dag Lister

Detaljer

INF2810: Funksjonell Programmering. Muterbare data

INF2810: Funksjonell Programmering. Muterbare data INF2810: Funksjonell Programmering Muterbare data Stephan Oepen Universitetet i Oslo 15. mars 2016 Agenda Forrige uke Prosedyrebasert objektorientering Lokale tilstandsvariabler Innkapsling + set! Eksempel:

Detaljer

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

Vi skal se på lambda-uttrykk. Følgende er definerte og vil bli brukt gjennom oppgaven SLI 230 - side 2 av 8 EKSAMENSOPPGAVE - SLI 230 - VÅR 2000 Nedenfor følger eksamensoppgaver i SLI 230. Først om oppgavene Bakerst følger to sider med hjelp slik det er avtalt - liste over primitiver fra

Detaljer

Kap. 4 del I Top Down Parsering INF5110 v2006. Stein Krogdahl Ifi, UiO

Kap. 4 del I Top Down Parsering INF5110 v2006. Stein Krogdahl Ifi, UiO Kap. 4 del I Top Down Parsering INF5110 v2006 Stein Krogdahl Ifi, UiO 1 Innhold First og Follow-mengder Boka ser på én parseringsmetode først, uten å se på First/Follow-mengder. Vi tar teorien først To

Detaljer

INF2810: Funksjonell programmering: Introduksjon

INF2810: Funksjonell programmering: Introduksjon INF2810: Funksjonell programmering: Introduksjon Stephan Oepen & Erik Velldal Universitetet i Oslo 18. januar, 2013 Tema for i dag 2 Introduksjon Praktiske detaljer Pensum Obliger Lærebok Hva skal vi lære?

Detaljer

Det er ikke tillatt med andre hjelpemidler enn de to sidene som er vedlagt oppgavesettet. Følgende funksjoner er definert og brukes i oppgaven:

Det er ikke tillatt med andre hjelpemidler enn de to sidene som er vedlagt oppgavesettet. Følgende funksjoner er definert og brukes i oppgaven: Eksamen SLI 230 Bakerst ligger to sider med oversikt over standardprosedyrer og spesialformer i Scheme, samt oversikt over prosedyrer fra Simply Scheme og en enkel oversikt over konvertering mellom datatyper

Detaljer

Anatomien til en kompilator - I

Anatomien til en kompilator - I Anatomien til en kompilator - I program Symboltabell tekst tokens syntaks-tre beriket syntaks-tre Finne struktur i programmet OK i henhold til grammatikk? Preprocessor Makroer Betinget kompilering Filer

Detaljer

Anatomien til en kompilator - I

Anatomien til en kompilator - I Anatomien til en kompilator - I 5/22/2006 1 Framgangsmåte for automatisk å lage en scanner Beskriv de forskjellige token-klassene som regulære uttrykk Eller litt mer fleksibelt, som regulære definisjoner

Detaljer

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

INF2810: Funksjonell Programmering. Mer om Scheme. Rekursjon og iterasjon. INF2810: Funksjonell Programmering Mer om Scheme. Rekursjon og iterasjon. Stephan Oepen Universitetet i Oslo 26. januar 2017 På blokka 2 Forrige uke Introduksjon og oversikt Praktiske detaljer Funksjonell

Detaljer

Kap. 4: Ovenfra-ned (top-down) parsering

Kap. 4: Ovenfra-ned (top-down) parsering Kap. 4: Ovenfra-ned (top-down) parsering Dette bør leses om igjen etter kapittelet: First og Follow-mengder Boka tar det et stykke uti kap 4, vi tok det først (forrige foilbunke) LL(1)-parsering og boka

Detaljer

Lisp 2: Lister og funksjoner

Lisp 2: Lister og funksjoner Eirik Alderslyst Nygaard Øystein Ingmar Skartsæterhagen Programvareverkstedet 11. mars 2010 (Lister) (Par) (Listeoperasjoner) (Assosiasjonslister)... lists are the heart of Lisp... Guy L. Steele Jr. (Par)

Detaljer

Destruktuktive listeoperasjoner

Destruktuktive listeoperasjoner Destruktuktive listeoperasjoner Under bruker vi følgende ikke-destruktive hjelperutine. (define (last pair L) (define (iter L) (if (null? (cdr L)) ; for å kunne returnere siste par, må vistoppe ett par

Detaljer

Destruktuktive listeoperasjoner

Destruktuktive listeoperasjoner Destruktuktive listeoperasjoner Under bruker vi følgende ikke-destruktive hjelperutine. (define (last pair L) (define (iter L) (if (null? (cdr L)) ; for å kunne returnere siste par, må vistoppe ett par

Detaljer

Par og Lister (først et par sider fra forrige uke) Par er byggestener for lister og trær og sammensatte datatyper.

Par og Lister (først et par sider fra forrige uke) Par er byggestener for lister og trær og sammensatte datatyper. Par og Lister (først et par sider fra forrige uke) Par er byggestener for lister og trær og sammensatte datatyper. Par kan representeres grafiske slik: Som vi ser kan vi bruke cons til å lage par hvis

Detaljer

Plan: Parameter-overføring Alias Typer (Ghezzi&Jazayeri kap.3 frem til 3.3.1) IN 211 Programmeringsspråk

Plan: Parameter-overføring Alias Typer (Ghezzi&Jazayeri kap.3 frem til 3.3.1) IN 211 Programmeringsspråk Plan: Parameter-overføring Alias Typer (Ghezzi&Jazayeri kap.3 frem til 3.3.1) Funksjonelle språk (Ghezzi&Jazayeri kap.7 frem til 7.4) Neste uke: ML Ark 1 av 16 Forelesning 16.10.2000 Parameteroverføring

Detaljer

Oppgave 1 Minimum edit distance

Oppgave 1 Minimum edit distance INF-2810 V 2012 Oppgavesett 10, kalenderuke 12. Oppgave 1 Minimum edit distance Vi vil finne det minste antall redigeringsoperasjoner som kreves for å komme fra strengen A til strengen B. Strengene oppgis

Detaljer

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

INF2810: Funksjonell Programmering. Mer om Scheme. Rekursjon og iterasjon. INF2810: Funksjonell Programmering Mer om Scheme. Rekursjon og iterasjon. Stephan Oepen Universitetet i Oslo 26. januar 2016 På blokka Forrige uke Introduksjon og oversikt Praktiske detaljer Funksjonell

Detaljer

Notat 2, ST Sammensatte uttrykk. 27. januar 2006

Notat 2, ST Sammensatte uttrykk. 27. januar 2006 Notat 2, ST1301 27. januar 2006 1 Sammensatte uttrykk Vi har sett at funksjoner ikke trenger å bestå av annet enn ett enkeltuttrykk som angir hva funksjonen skal returnere uttrykkt ved de variable funksjonen

Detaljer

Kap.4 del I Top Down Parsering INF5110 v2005. Arne Maus Ifi, UiO

Kap.4 del I Top Down Parsering INF5110 v2005. Arne Maus Ifi, UiO Kap.4 del I Top Down Parsering INF5110 v2005 Arne Maus Ifi, UiO Innhold Motivering Boka gir først parsering uten First/Follow-mengder og så innfører dem. Vi tar teorien først First og Follow-mengder Fjerning

Detaljer

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser INF2810: Funksjonell Programmering Oppsummering og eksamensforberedelser Erik Velldal & Stephan Oepen Universitetet i Oslo 18. mai 2017 I dag 2 Kort oppsummering Praktisk om eksamen Hvem vant konkurransen

Detaljer

Python: Løkker. TDT4110 IT Grunnkurs Professor Guttorm Sindre

Python: Løkker. TDT4110 IT Grunnkurs Professor Guttorm Sindre Python: Løkker TDT4110 IT Grunnkurs Professor Guttorm Sindre Denne uka Vi trenger å Støttes av Hente data fra bruker Vise data til bruker Lagre data i minnet for bruk videre i programmet Fra tastatur:

Detaljer

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser INF2810: Funksjonell Programmering Oppsummering og eksamensforberedelser Erik Velldal & Stephan Oepen Universitetet i Oslo 18. mai 2017 I dag 2 Kort oppsummering Praktisk om eksamen Hvem vant konkurransen

Detaljer

Hjemmeeksamen 2 i INF3110/4110

Hjemmeeksamen 2 i INF3110/4110 Hjemmeeksamen 2 i INF3110/4110 Innleveringsfrist: onsdag 19. november kl. 1400 Innlevering Besvarelsen av oppgave 2,3,4 og 5 skal leveres skriftlig på papir i IFI-ekspedisjonen. Merk denne med navn, kurskode,

Detaljer

INF5110 V2012 Kapittel 4: Parsering ovenfra-ned

INF5110 V2012 Kapittel 4: Parsering ovenfra-ned INF5110 V2012 Kapittel 4: Parsering ovenfra-ned (top-down) Tirsdag 7. februar Stein Krogdahl, Ifi, UiO Oppgaver som gjennomgås i morgen, onsdag: -Spørsmålene på de to siste foilene fra onsdag 1/2 (Bl.a.

Detaljer

Obligatorisk oppgave 1 INF1020 h2005

Obligatorisk oppgave 1 INF1020 h2005 Obligatorisk oppgave 1 INF1020 h2005 Frist: fredag 7. oktober Oppgaven skal løses individuelt, og må være godkjent for å kunne gå opp til eksamen. Før innlevering må retningslinjene Krav til innleverte

Detaljer

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

INF2810: Funksjonell Programmering. Mer om Scheme. Rekursjon og iterasjon. INF2810: Funksjonell Programmering Mer om Scheme. Rekursjon og iterasjon. Stephan Oepen Universitetet i Oslo 26. januar 2017 På blokka Forrige uke Introduksjon og oversikt Praktiske detaljer Funksjonell

Detaljer

INF5110 V2013 Stoff som i boka står i kap 4, men som er generelt stoff om grammatikker

INF5110 V2013 Stoff som i boka står i kap 4, men som er generelt stoff om grammatikker INF5110 V2013 Stoff som i boka står i kap 4, men som er generelt stoff om grammatikker 29. januar 2013 Stein Krogdahl, Ifi, UiO NB: Ikke undervisning fredag 1. februar! Oppgaver som gjennomgås 5. februar

Detaljer

TDT Øvingsforelesning 1. Tuesday, August 28, 12

TDT Øvingsforelesning 1. Tuesday, August 28, 12 TDT 4165 Øvingsforelesning 1 Øvingsforelesningene Eksempelbaserte Sikter på å være på et snillere nivå enn øvingene og forelesningene Interaktive - spørsmål og dialog oppfordres Matnyttige- vil ta for

Detaljer

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser INF2810: Funksjonell programmering INF2810: Funksjonell Programmering Oppsummering og eksamensforberedelser Erik Velldal Universitetet i Oslo 28. mai 2015 I dag Kort oppsummering Praktisk om eksamen Hvem

Detaljer

INF2810: Funksjonell programmering: Introduksjon

INF2810: Funksjonell programmering: Introduksjon NF2810: Funksjonell programmering: ntroduksjon Stephan Oepen & Erik Velldal Universitetet i Oslo 18. januar, 2013 Tema for i dag 2 ntroduksjon Praktiske detaljer Pensum Obliger Lærebok Hva skal vi lære?

Detaljer

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser INF2810: Funksjonell programmering INF2810: Funksjonell Programmering Oppsummering og eksamensforberedelser Erik Velldal & Stephan Oepen Universitetet i Oslo 31. mai 2016 I dag Kort oppsummering Praktisk

Detaljer

Oppsummering fra sist

Oppsummering fra sist 1 av 34 Kunnskap for en bedre verden TDT4110 Informasjonsteknologi grunnkurs: Tema: Løkker/Sløyfer Utgave 3: Kap. 4 Terje Rydland - IDI/NTNU 2 av 34 Oppsummering fra sist Betingelser i Python: ,

Detaljer

Notat 2, ST januar 2005

Notat 2, ST januar 2005 Notat 2, ST1301 25. januar 2005 1 Sammensatte uttrykk Vi har sett at funksjoner ikke trenger å bestå av annet enn ett enkeltuttrykk som angir hva funksjonen skal returnere uttrykkt ved de variable funksjonen

Detaljer

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser INF2810: Funksjonell Programmering Oppsummering og eksamensforberedelser Erik Velldal & Stephan Oepen Universitetet i Oslo 31. mai 2016 I dag 2 Kort oppsummering Praktisk om eksamen Hvem vant konkurransen

Detaljer

INF2810: Funksjonell Programmering. Huffman-koding

INF2810: Funksjonell Programmering. Huffman-koding INF2810: Funksjonell Programmering Huffman-koding Stephan Oepen & Erik Velldal Universitetet i Oslo 22. februar, 2013 Tema 2 Forrige uke Data-abstraksjon Lister av lister Tre-rekursjon Prosedyrer som datastruktur

Detaljer