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

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

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

INF2810: Funksjonell Programmering. En metasirkulær evaluator

INF2810: Funksjonell Programmering. En metasirkulær evaluator

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme

INF2810: Funksjonell Programmering. Kommentarer til prøveeksamen

INF2810: Funksjonell Programmering. Strømmer og utsatt evaluering

INF2810: Funksjonell Programmering. Strømmer og utsatt evaluering

UNIVERSITETET I OSLO

INF2810: Funksjonell Programmering. Eksamensforberedelser

INF2810: Funksjonell Programmering. Utsatt evaluering og strømmer

INF2810: Funksjonell Programmering. Utsatt evaluering og strømmer

INF2810: Funksjonell Programmering. Utsatt evaluering og strømmer

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

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

INF2810: Funksjonell Programmering

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

INF2810: Funksjonell Programmering. Utsatt evaluering og strømmer

INF2810: Funksjonell Programmering. Mer om strømmer

INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering. Lister og høyereordens prosedyrer

INF2810: Funksjonell Programmering. Mer om strømmer

INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering

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

INF2810: Funksjonell Programmering. Lister og høyereordens prosedyrer

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

INF2810: Funksjonell Programmering

Høyere-ordens prosedyrer

INF2810: Funksjonell Programmering

Eksamen i SLI230, vår 2003.

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser

UNIVERSITETET I OSLO

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser

INF2810: Funksjonell Programmering. Dataabstraksjon og Trerekursjon

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser

INF2810: Funksjonell Programmering. Tilstand og verditilordning

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

INF2810: Funksjonell Programmering. Tilstand og verditilordning

INF2810: Funksjonell Programmering. Tilstand og verditilordning

INF2810: Funksjonell programmering: Introduksjon

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

INF2810: Funksjonell Programmering. Tilstand og verditilordning

INF2810: Funksjonell Programmering. Strømmer

INF2810: Funksjonell Programmering. Eksamensforberedelser

INF2810: Funksjonell Programmering. Muterbare data

INF2810: Funksjonell Programmering. Strømmer

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

Innlevering 2a i INF2810, vår 2017

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

INF2810: Funksjonell Programmering. Mengder og lokal tilstand

INF2810: Funksjonell programmering: Introduksjon

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

INF2810: Funksjonell Programmering. Trær og mengder

INF2810: Funksjonell Programmering. Trær og mengder

UNIVERSITETET I OSLO

Innlevering 2b i INF2810, vår 2017

INF2810: Funksjonell Programmering. Trær og mengder

INF2810: Funksjonell Programmering. Introduksjon

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.

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

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

Appendiks A Kontinuasjoner

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

UNIVERSITETET I OSLO

LISP PVV-kurs 25. oktober 2012

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

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

INF2810: Funksjonell Programmering. Introduksjon

INF2810: Funksjonell Programmering. Lister og høyereordens prosedyrer

Lisp 5: Makroer. Programvareverkstedet. 29. april 2010

INF2810: Funksjonell Programmering. Huffman-koding

INF2810: Funksjonell Programmering. Huffman-koding

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

Runtimesystemer - II. Parameteroverføring Call by value Call by reference Call by value-result Call by name INF 3110/ INF

INF2810: Funksjonell Programmering. Introduksjon

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

Memoisering, utsatt evaluering og strømmer

Memoisering, utsatt evaluering og strømmer

Runtime-omgivelser Kap 7 - II

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

Velkommen til INF2100 Jeg er Dag Langmyhr

Kap.4 Funksjoner. Tre viktig ting ifm. funksjoner: parameter (input) oppskrift (body) for å beregne resultat (output)

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

UNIVERSITETET I OSLO

Lisp 3: Spesielle former, variabler, imperativ programmering

Repetisjon: Statiske språk uten rekursive metoder (C1 og C2) Dagens tema Kjøresystemer (Ghezzi&Jazayeri 2.6, 2.7)

Dagens tema Kjøresystemer (Ghezzi&Jazayeri 2.6, 2.7)

Haskell. Kjetil Ørbekk. Programvareverkstedet, 19. mars 2009

Runtimesystemer - II. Funksjoner som parametere. Virtuelle metoder

INF2810: Funksjonell Programmering. Huffman-koding

Beskrivelse av programmeringsspråket Compila15 INF Kompilatorteknikk Våren 2015

INF2810: Funksjonell Programmering. Introduksjon

Bakgrunnen for INF2100. Velkommen til INF2100. Prosjektet. Hva gjør en kompilator?

Hjemmeeksamen 2 i INF3110/4110

Transkript:

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 programs Metacircular evaluator Scheme-evaluator skrevet i Scheme Omgivelsesmodellen

Tema 2 Forrige uke SICP 4.1. Structure and interpretation of computer programs Metacircular evaluator Scheme-evaluator skrevet i Scheme Omgivelsesmodellen I dag Vi skal se litt mer på koden fra 4.1 og alternativ syntaks. SICP 4.2 og alternativ semantikk; lazy evaluation.

En parentes: 3 Mye av denne forelesningen vil som sist være basert på at vi sammen går igjennom kode i evaluator.scm med kjøringseksempler. http://www.uio.no/studier/emner/matnat/ifi/inf2810/v13/ undervisningsmateriale/evaluator.scm

En evaluator for Scheme, i Scheme 4 Evaluator (interpreter) et program som tolker og utfører et program. Metasirkulær evaluator en evaluator skrevet i samme språket som den skal evaluere.

En evaluator for Scheme, i Scheme 4 Evaluator (interpreter) et program som tolker og utfører et program. Metasirkulær evaluator en evaluator skrevet i samme språket som den skal evaluere. Motivasjon Gjør omgivelsesmodellen eksplisitt gjennom en konkret implementasjon. Bedre forståelse for hvordan ulike uttrykk evalueres. Lar oss eksperimentere med alternativ syntaks og alternativ semantikk. Viser hvordan program er data.

Program = data 5 Evaluatoren vår er en prosedyre som tar kode som argument. Men for evaluatoren er koden bare symbolske data som vi kan manipulere på vanlig måte.

Program = data 5 Evaluatoren vår er en prosedyre som tar kode som argument. Men for evaluatoren er koden bare symbolske data som vi kan manipulere på vanlig måte. Grunnen til at vi kaller den metasirkulære evaluatoren vår mc-eval er at Scheme selv allerede gir oss direkte tilgang til den underliggende evaluatoren sin via den innebygde eval:

Program = data 5 Evaluatoren vår er en prosedyre som tar kode som argument. Men for evaluatoren er koden bare symbolske data som vi kan manipulere på vanlig måte. Grunnen til at vi kaller den metasirkulære evaluatoren vår mc-eval er at Scheme selv allerede gir oss direkte tilgang til den underliggende evaluatoren sin via den innebygde eval:? (let* ((args (1 2 3)) (proc +) (exp (cons proc args))) (display exp) (newline) (eval exp (interaction-environment)))

Program = data 5 Evaluatoren vår er en prosedyre som tar kode som argument. Men for evaluatoren er koden bare symbolske data som vi kan manipulere på vanlig måte. Grunnen til at vi kaller den metasirkulære evaluatoren vår mc-eval er at Scheme selv allerede gir oss direkte tilgang til den underliggende evaluatoren sin via den innebygde eval:? (let* ((args (1 2 3)) (proc +) (exp (cons proc args))) (display exp) (newline) (eval exp (interaction-environment))) (+ 1 2 3) 6

Delene i den metasirkulære evaluatoren 6 Datastrukturer for å representere omgivelser og prosedyreobjekter. Predikater og aksessorer som definerer syntaksen til uttrykk i språket. mc-eval og mc-apply Med spesialiserte varianter for evaluering av special forms. Definerer semantikken. Mekanisme for å kalle primitive / innebygde prosedyrer. REPL

Gjensidig rekursjon 7 Kjernen i evaluatoren eval; tar et uttrykk og en omgivelse, evaluerer del-uttrykkene rekursivt, og kaller apply med en prosedyre og argumenter. apply; tar en prosedyre og argumenter, og kaller eval med nye uttrykk og en ny omgivelse.

To typer evaluering Eager evaluation (Sussman) Lazy evaluation (Abelson) 8

To typer evaluering Eager evaluation Eller applicative-order evaluation / strict evaluation. Argumentene evalueres før en prosedyre anvendes. (Sussman) Lazy evaluation (Abelson) 8

To typer evaluering Eager evaluation Eller applicative-order evaluation / strict evaluation. Argumentene evalueres før en prosedyre anvendes. (Sussman) Lazy evaluation Eller normal-order evaluation / non-strict evaluation. Evaluering av argumentene utsettes til vi faktisk trenger verdiene deres. (Abelson) 8

Evalueringsstrategier: eager vs. lazy 9 Eager evaluation er standardstrategien i Scheme. Kalles også call-by-value. Men i visse tilfeller brukes lazy evaluation:

Evalueringsstrategier: eager vs. lazy 9 Eager evaluation er standardstrategien i Scheme. Kalles også call-by-value. Men i visse tilfeller brukes lazy evaluation: Ved special-forms, som if, and og or.

Evalueringsstrategier: eager vs. lazy 9 Eager evaluation er standardstrategien i Scheme. Kalles også call-by-value. Men i visse tilfeller brukes lazy evaluation: Ved special-forms, som if, and og or.? (define (foo) (foo))? (if (= 0 1) (foo) bar)

Evalueringsstrategier: eager vs. lazy 9 Eager evaluation er standardstrategien i Scheme. Kalles også call-by-value. Men i visse tilfeller brukes lazy evaluation: Ved special-forms, som if, and og or.? (define (foo) (foo))? (if (= 0 1) (foo) bar) bar

Evalueringsstrategier: eager vs. lazy 10? (define (foo) (foo))? (define (proc-if test then-do else-do) (if test then-do else-do))? (proc-if (= 0 1) (foo) bar)??

Evalueringsstrategier: eager vs. lazy 10? (define (foo) (foo))? (define (proc-if test then-do else-do) (if test then-do else-do))? (proc-if (= 0 1) (foo) bar)?? Kallet på proc-if vil her gi en uendelig løkke under eager evaluation. Men fungerer fint under lazy evaluation.

Evalueringsstrategier: eager vs. lazy 10? (define (foo) (foo))? (define (proc-if test then-do else-do) (if test then-do else-do))? (proc-if (= 0 1) (foo) bar)?? Kallet på proc-if vil her gi en uendelig løkke under eager evaluation. Men fungerer fint under lazy evaluation. Lazy evaluation gjør det også mulig å jobbe med uendelige datastrukturer, som strømmer.

Lazy evaluation 11 I noen varianter av normal-order evaluation re-evalueres uttrykkene hver gang de brukes (call-by-name). Men lazy evaluation inkluderer gjerne også memoisering: Argument-uttrykk evalueres kun når de trengs og maksimalt én gang. Ved evaluering lagres verdien for mulig gjenbruk senere. Call-by-need

Lazy evaluation 11 I noen varianter av normal-order evaluation re-evalueres uttrykkene hver gang de brukes (call-by-name). Men lazy evaluation inkluderer gjerne også memoisering: Argument-uttrykk evalueres kun når de trengs og maksimalt én gang. Ved evaluering lagres verdien for mulig gjenbruk senere. Call-by-need Vi skal gjøre Scheme-evaluatoren vår lazy. I stedet for å evaluere argumentene før et prosedyrekall pakker vi sammen uttrykkene og kall-omgivelsen slik at de kan evalueres senere. Vi trenger altså en måte å fryse uttrykk på. (Gjelder kun ikke-primitive prosedyrer.)

Thunks 12 (define (delay-it exp env) (list thunk exp env)) (define (thunk? obj) (tagged-list? obj thunk)) (define (thunk-exp thunk) (cadr thunk)) (define (thunk-env thunk) (caddr thunk)) (define (evaluated-thunk? obj) (tagged-list? obj evaluated-thunk)) (define (thunk-value evaluated-thunk) (cadr evaluated-thunk)) Representerer uttrykk som thunks. Liste av taggen thunk, selve uttrykket, og omgivelsen. Thunk som allerede har blitt evaluert (og verdien memoisert): Taggen evaluated-thunk og verdien til uttrykket. Trenger ikke huske omgivelsen.

Thunks 13 (define (force-it obj) (cond ((thunk? obj) (let ((result (actual-value ; evaluer uttrykket. (thunk-exp obj) (thunk-env obj)))) (set-car! obj evaluated-thunk) (set-car! (cdr obj) result) ; erstatter uttrykk med verdi. (set-cdr! (cdr obj) ()) ; glem omgivelsen. result)) ((evaluated-thunk? obj) ; memoisert? (thunk-value obj)) (else obj))) ; ikke en thunk. (define (actual-value exp env) (force-it (mc-eval exp env))) ; gjensidig rekursjon: actual-value kaller force-it igjen ; i tilfelle mc-eval returnerer en ny thunk.

Lazy Scheme 14 Med thunks har vi nå en måte å fryse uttrykk på. Så må dette plugges inn i eval / apply. Generelt kan vi si at uttrykk kun trenger å evalueres dersom de er argumentene til primitive prosedyrer, predikatet vi skal teste i en kontrollstruktur, eller operatoren vi skal til å anvende i et prosedyrekall.

mc-eval 15 (define (mc-eval exp env) (cond ((self-evaluating? exp) exp) ((variable? exp) (lookup-variable-value exp env)) ((special-form? exp) (eval-special-form exp env)) ((application? exp) (apply (actual-value (operator exp) env) (operands exp) ;; selve uttrykkene, ikke verdiene env))))

mc-apply (define (apply proc args env) (cond ((primitive-procedure? proc) (apply-primitive-procedure proc (list-of-arg-values args env))) ((compound-procedure? proc) (eval-sequence (procedure-body proc) (extend-environment (procedure-parameters proc) (list-of-delayed-args args env) (procedure-environment proc)))))) ; henter faktiske verdier ; lager thunks (define (list-of-arg-values exps env) (if (no-operands? exps) () (cons (actual-value (first-operand exps) env) (list-of-arg-values (rest-operands exps) env)))) (define (list-of-delayed-args exps env) (if (no-operands? exps) () (cons (delay-it (first-operand exps) env) (list-of-delayed-args (rest-operands exps) env)))) 16

NB 17 Vanskelig å forutsi rekkefølgen på operasjoner. Lazy evaluation i kombinasjon med prosedyrer som har side-effekter kan dermed være forvirrende. Forventet effekt kan utebli fordi et uttrykk ikke har blitt evaluert ennå. Et av få språk med lazy evaluation som standardstrategi er Haskell. Et mere rent funksjonelt språk.

Strømmer som late lister 18 Tidligere har vi implementert strømmer som utsatte lister: Brukte special forms delay og cons-stream. Trenger ikke lenger skille mellom strømmer og lister: La cons bruke lazy evaluation. I så fall må vi enten la evaluatoren støtte ikke-strikte primitiver eller implementere cons som en ikke-primitiv. Som vi har sett tidligere kan par f.eks representeres som prosedyrer: (define (cons x y) (lambda (m) (m x y))) (define (car z) (z (lambda (p q) p))) (define (cdr z)

Strømmer som late lister 18 Tidligere har vi implementert strømmer som utsatte lister: Brukte special forms delay og cons-stream. Trenger ikke lenger skille mellom strømmer og lister: La cons bruke lazy evaluation. I så fall må vi enten la evaluatoren støtte ikke-strikte primitiver eller implementere cons som en ikke-primitiv. Som vi har sett tidligere kan par f.eks representeres som prosedyrer: (define (cons x y) (lambda (m) (m x y))) (define (car z) (z (lambda (p q) p))) (define (cdr z) (z (lambda (p q) q)))

Neste gang Om tre uker: 24/5 Eksamensforberedelser Oppsummeringλ 19