Paradigmata programování II Přednáška 1: Vedlejší efekt

Podobné dokumenty
PARADIGMATA PROGRAMOVÁNÍ 2A VEDLEJŠÍ EFEKT

PARADIGMATA PROGRAMOVÁNÍ 2 PŘÍSLIBY A LÍNÉ VYHODNOCOVÁNÍ

Paradigmata programování II Přednáška 2: Mutace

Paradigmata programování II Korutiny a nedeterminismus

Paradigmata programování 1

PARADIGMATA PROGRAMOVÁNÍ 2A INTERPRET S VEDLEJŠÍMI EFEKTY A MAKRY

PARADIGMATA PROGRAMOVÁNÍ 2 KORUTINY, NEDETERMINISMUS

Paradigmata programování 1

PARADIGMATA PROGRAMOVÁNÍ 2A MUTACE

PARADIGMATA PROGRAMOVÁNÍ 2A MAKRA III

1. Od Scheme k Lispu

Paradigmata programování 1

Paradigmata programování 1

Stream API. Petr Krajča. Základy programovaní 4 (Java) Katedra informatiky Univerzita Palackého v Olomouci

Paradigmata programování II Přednáška 6: Líné vyhodnocování, proudy a kešované vyhodnocování

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

Základní datové struktury

Paradigmata programování 2

PARADIGMATA PROGRAMOVÁNÍ 2A MAKRA I

Přednáška 3. Rekurze 1

PARADIGMATA PROGRAMOVÁNÍ 2 AKTUÁLNÍ POKRAƒOVÁNÍ

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Datové struktury. alg12 1

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Obsah přednášky. programovacího jazyka. Motivace. Princip denotační sémantiky Sémantické funkce Výrazy Příkazy Vstup a výstup Kontinuace Program

Úvod do programovacích jazyků (Java)

typová konverze typová inference

Abstraktní datové typy: zásobník

Sdílení dat mezi podprogramy

Slepé prohledávání do šířky Algoritmus prohledávání do šířky Při tomto způsobu prohledávání máme jistotu, že vždy nalezneme koncový stav, musíme ale p

FUNKCIONÁLNÍ A LOGICKÉ PROGRAMOVÁNÍ 5. CVIČENÍ

Více o konstruktorech a destruktorech

Vyučovací hodina. 1vyučovací hodina: 2vyučovací hodiny: Opakování z minulé hodiny. Procvičení nové látky

Algoritmizace a programování

Generické programování

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

IB015 Neimperativní programování. Organizace a motivace kurzu, programovací jazyk Haskell. Jiří Barnat

Struktura programu v době běhu

Konstruktory a destruktory

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

FUNKCIONÁLNÍ A LOGICKÉ PROGRAMOVÁNÍ 3. CVIČENÍ

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

4. Rekurze. BI-EP1 Efektivní programování Martin Kačer

Jazyk C# (seminář 6)

IB111 Úvod do programování skrze Python Přednáška 13

Funkcionální programování úvod

Semestrální práce z předmětu. Jan Bařtipán / A03043 bartipan@studentes.zcu.cz

Stromy. Karel Richta a kol. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze Karel Richta a kol.

Základní pojmy. Úvod do programování. Základní pojmy. Zápis algoritmu. Výraz. Základní pojmy

Matematika v programovacích

Základy objektové orientace I. Únor 2010

PB161 Programování v jazyce C++ Přednáška 7

PB161 Programování v jazyce C++ Přednáška 7

PSK3-9. Základy skriptování. Hlavička

Programování v C++ 2, 4. cvičení

IB111 Programování a algoritmizace. Programovací jazyky

Funkcionální programování

Jazyk Scheme: jeho syntax a sémantika

DTP Základy programování Úvod do předmětu

Objektově orientované programování

2 Datové typy v jazyce C

Úvod. Programovací paradigmata

IRAE 07/08 Přednáška č. 2. atr1 atr2. atr1 atr2 -33

2.1 Podmínka typu case Cykly Cyklus s podmínkou na začátku Cyklus s podmínkou na konci... 5

Programovací jazyk Haskell

Programování v C++, 2. cvičení

DSL manuál. Ing. Jan Hranáč. 27. října V této kapitole je stručný průvodce k tvorbě v systému DrdSim a (v

Funkcionální programování. Kristýna Kaslová

1. Programování proti rozhraní

Úvod do programovacích jazyků (Java)

Hanojská věž. T2: prohledávání stavového prostoru. zadání [1 1 1] řešení [3 3 3] dva možné první tahy: [1 1 2] [1 1 3]

VÝUKOVÝ MATERIÁL. Bratislavská 2166, Varnsdorf, IČO: tel Číslo projektu

Functional and Logic Programming Functional languages

Lokální definice (1) plocha-kruhu

Programovací í jazyk Haskell

Základy jazyka C# Obsah přednášky. Architektura.NET Historie Vlastnosti jazyka C# Datové typy Příkazy Prostory jmen Třídy, rozhraní

PB161 Programování v jazyce C++ Přednáška 4

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

Implementace LL(1) překladů

Program a životní cyklus programu

Seznamy a iterátory. Kolekce obecně. Rozhraní kolekce. Procházení kolekcí

SII - Informatika. 1. Atribut relace, jehož hodnota jednoznačně určuje prvek v jiné relaci, se nazývá:

int ii char [16] double dd název adresa / proměnná N = nevyužito xxx xxx xxx N xxx xxx N xxx N

Ukazatel (Pointer) jako datový typ - proměnné jsou umístěny v paměti na určitém místě (adrese) a zabírají určitý prostor (počet bytů), který je daný

Rekurzivní algoritmy

Úvod do informatiky. Miroslav Kolařík

LISP Definice funkcí

ŘÍKÁME, ŽE FUNKCE JE ČÁSTEČNĚ SPRÁVNÁ (PARTIALLY CORRECT), POKUD KDYŽ JE SPLNĚNA PRECONDITION

Správa paměti. Karel Richta a kol. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze Karel Richta, 2016

14. Složitější konstrukce

(pracovní verze textu určená pro studenty)

1 Základních pojmy z oblasti programování, vyšší programovací jazyky, programovací paradigmata

Programovací jazyky. imperativní (procedurální) neimperativní (neprocedurální) assembler (jazyk symbolických instrukcí)

CZ.1.07/1.5.00/

PODOBÁ SE JAZYKU C S NĚKTERÝMI OMEZENÍMI GLOBÁLNÍ PROMĚNNÉ. NSWI162: Sémantika programů 2

Programování 2 (NMIN102) Soubory. RNDr. Michal Žemlička, Ph.D.

IW5 - Programování v.net a C# 4 Pokročilé konstrukce C#

11. Přehled prog. jazyků

Začínáme vážně programovat. Řídící struktury Přetypování Vstupně výstupní operace Vlastní tvorba programů

Logické programování

Transkript:

Paradigmata programování II Přednáška 1: Vedlejší efekt Vilém Vychodil Katedra informatiky, Univerzita Palackého v Olomouci 15. února 2007 Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 1 / 75

Co je vedlejší efekt? Imperativní rysy při programování funkcionální programování = založené na postupné aplikaci procedur (funkcí) LISP, Scheme, ML, Haskell,... procedurální programování = založená na postupném vykonávání příkazů, které mají vedjělší efekt C, PASCAL, FORTRAN,... Trend: objektově orientované programování funkcionálně objektové = založené na generických procedurách CLOS (Common LISP Object System), GOOPS (objektový Scheme) procedurálně objektové = založené na zasílání signálů PERL, PYTHON, Java, C++, C,... většina soudobých PJ Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 3 / 75

Jaké typy vedlejších efektů rozeznáváme hodně typů vstupně / výstupní operace (některé FJ umí i bez vedlejšího efektu, třeba Haskell) změnou vazby symbolu tím se budeme zabývat dnes destruktivné změnou datové staruktury tím se budeme zabývat příště Připomínáme: FJ je čistý, pokud programátorovi neumožňuje vytvořit vedlejší efekt Scheme není čistý (máme define), Haskell je čistý Náš interpret z Lekce 12 byl čistý (ačkoliv byl napsán nečistě ). vedlejší efekt není ve FJ na škodu, musí se ale umět používat Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 5 / 75

Čím se budeme zabývat obohatíme Scheme o několik ryze imperativních konstruktů demonstrujeme na tom rysy imperativních jazyků Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 7 / 75

Sekvencování příkazů Speciální forma begin: ;; postupne vyhodnoceni vyrazy a vraceni ;; vysledku vyhodnoceni posledniho z nich (begin (+ 1 2) (* 3 4)) ;; zde uz mame vedlejsi efekt -- vytisteni na obrazovku (begin (display (+ 1 2)) (newline) (* 3 4)) Pozor: (display "Ahoj") vytiskne na obrazovku, řetězec nelze chápat jako výsledek vyhodnocení, tím je nedefinovaná hodnota, ukázat studentům v DrScheme. Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 9 / 75

Sekvencování příkazů Chování begin vzhledem k prostředím ;; vyhodnocovani vyrazu probiha v aktualnim prostredi (define x 100) (begin (define x 10) (* 2 x)) x = 10 Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 11 / 75

;; tohle je begin v novem prostredi ((lambda () (begin (define x 10) (* 2 x)))) x = nedef. ;; prepis predchoziho (let () (begin (define x 10) (* 2 x))) x = nedef. Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 13 / 75

Těla procedur obsahují implicitní begin opět se můžeme vrátit ke konceptu jednoho výrazu v těle procedury (define f (lambda (x) (define local (lambda (y) (+ x y))) (local 20))) (define f (lambda (x) (begin (define local (lambda (y) (+ x y))) (local 20)))) (begin) = nedef. hodnota Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 15 / 75

Použití při ladění (define depth-map (lambda (f l) (cond ((null? l) '()) ((not (list? (car l))) (cons (f (car l)) (depth-map f (cdr l)))) (else (cons (depth-map f (car l)) (depth-map f (cdr l))))))) ;; ukazat v interpretu, protoze se mi to sem nevleze Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 17 / 75

Provedení příkazů pro každý prvek seznamu (for-each (lambda (x) (display "Cislo: ") (display x) (newline)) '(10 20 30 40)) = nedef. hodn. (for-each (lambda (x) x) '(1 2 3)) ; nedef. (map (lambda (x) x) '(1 2 3)) ; (1 2 3) (for-each (lambda (x y z) (newline) (display (list x y z)) (newline)) '(10 20) '(#t #f) '(a b)) Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 19 / 75

Proceduru for-each snadno uděláme ;; for-each lze jednoduse naprogramovat (verze pro 1 s.): ;; vzimnete si pouziti `if' bez alternativniho vyrazu (define for-each (lambda (f l) (if (not (null? l)) (begin (f (car l)) (for-each f (cdr l)))))) ;; a obecna verze je taky jednoducha: (define for-each (lambda (f. lists) (if (not (null? (car lists))) (begin (apply f (map car lists)) (apply for-each f (map cdr lists)))))) Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 21 / 75

Příkaz přiřazení Obecné schéma LVALUE := RVALUE. LVALUE... paměťové místo (adresa) RVALUE... adresa Ve Scheme: reprezentován speciální formou set! (set! symbol výraz ) sémantika 1 v hierarchii prostředí vyhledej symbol symbol, začni aktuálním (lokálním) prostředím a pokračuj přes jeho rodiče směrem ke globálnímu; 2 pokud symbol nemá vazbu v žádném prostředí, zahlas chybu; 3 v opačném případě nahraď vazbu symbolu symbol hodnotou vzniklou vyhodnocením výraz. Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 23 / 75

;; srovnej: (define x 100) (let () (define x 10) (+ x 1)) x = 100 ;; versus (define x 100) (let () (set! x 10) (+ x 1)) x = 10 Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 25 / 75

(define x 100) (let ((x 10)) (set! x (+ x 1)) (+ x 1)) x = 100 Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 27 / 75

Programování s příkazem přiřazení čisté řešení ve funkcionálním stylu: (define fib (lambda (n) (let iter ((a 1) (b 1) (i n)) (if (<= i 1) a (iter b (+ a b) (- i 1)))))) V jazycích jako je C, PASCAL, FORTRAN a spol. cyklus Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 29 / 75

Programování s příkazem přiřazení int fib (n) int n; { int a = 1, b = 1, c, i; for (i = n; i > 1; i --) { c = b; b = a + b; a = c; } return a; } můžeme otrocky přepsat i ve Scheme, není ale pěkné, ani efektivní: Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 31 / 75

(define fib (lambda (n) (define a 1) (define b 1) (define c 'pomocna-promenna) (define i n) (define loop (lambda () (if (> i 1) (begin (set! c b) (set! b (+ a b)) (set! a c) (set! i (- i 1)) (loop))))) (loop) a)) Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 33 / 75

na druhou stranu v C lze programovat bez vedlejšího efektu: int fib_iter (a, b, i) int a, b, i; { if (i <= 1) return a; else return fib_iter (b, a + b, i - 1); } int fib_wse (n) int n; { return fib_iter (1, 1, n); } C nemá TRO; programovací styl programovací jazyk Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 35 / 75

Varování Scheme má vše k dispozici k tomu, abychom se na něl mohli dívat jako na plnohodnotný imperativní jazyk, při praktickém programování ve Scheme by ale měly převládat funkcionální rysy. Důvod: vedlejší efekt obrovský zdroj chyb v programech Někdy se vedlejší efekty hodí. (let ((i 0)) ; nastav i na 0 (for-each (lambda (x) (display "Index: ") (display i) (display ", prvek: ") (display x) (newline) (set! i (+ i 1))) ; zvedni i o 1 '(a b c d e f))) Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 37 / 75

Procedury pracující s globálními symboly ;; globalne zavedeny symbol (define value 0) ;; procedura pracujici s,,globalnim symbolem'' (define inc (lambda (x) (set! value (+ value x)) value)) (inc 10) = 10 (inc 10) = 20 (inc 10) = 30 value = 30 Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 39 / 75

Dočasné překrytí lexikální vazby symbolu Speciální forma fluid-let (fluid-let ((value 200)) (display (inc 10)) zobr. 210 (newline) (display (inc 10)) zobr. 220 (newline)) (inc 10)... vrati se k puvodni vazbe (let ((value 200)) (display (inc 10)) (newline) (display (inc 10)) (newline)) pracuje s glob. vazbou pracuje s glob. vazbou Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 41 / 75

Procedury držící si vnitřní stav ;; procedura udrzujici si vlastni vnitrni stav ;; misto globalniho symbolu menime vazbu symbolu ;; na ktery neni videt,,zvenci'' (define inc (let ((value 0)) (lambda (x) (set! value (+ value x)) value))) (inc 5) ; 5 (inc 5) ; 10 (inc 5) ; 15 value ; nedef. Stav (vazba symbolu value) je držen v prostředí vzniku procedury. Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 43 / 75

Procedury držící si vnitřní stav Pozor, následující nefunguje! ;; POZOR: nasledujici nefunguje (zamena `lambda' a `let') (define inc (lambda (x) (let ((value 0)) (set! value (+ value x)) value))) Při používání procedur s vedlejším efektem se podstatně hůř ladí už nestačí pouze testovat vstupy a výstupy procedury, musíme vždy počítat s tím, jaký má procedura zrovna vnitřní stav! Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 45 / 75

Na co je třeba dát pozor ;; build list pracujici,,zepredu'' (define build-list (lambda (n f) (let iter ((i 0)) (if (= i n) '() (cons (f i) (iter (+ i 1))))))) ;; build list pracujici,,zezadu'' (define build-list (lambda (n f) (let iter ((i (- n 1)) (aux '())) (if (< i 0) aux (iter (- i 1) (cons (f i) aux)))))) Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 47 / 75

Na co je třeba dát pozor Předchozí dvě verze build-list byly z funkcionálního hlediska nerozlišitelné. Po zavedení vedlejšího efektu již tak tomu ale není. ;; pricita jednicku (predavane arg. jsou ignorovany) (define inc1 (let ((value 0)) (lambda args (set! value (+ value 1)) value))) z funkcionalniho pohledu obe b.l. nerozlisitelne (build-list 10 (lambda (x) x)) ; (0 1 2 3 4 5 6 7 8 9) ; muzeme je ale odlisit pomoci vedlejsiho efektu (build-list 10 inc1) ; v prvnim pripade: (1 2 3 4 5 6 7 8 9 10) ; v druhem pripade: (10 9 8 7 6 5 4 3 2 1) Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 49 / 75

Procedury generující procedury s vnitřním stavem ;; procedura (bez argumentu), ktera vraci proceduru 1 arg ;; reprezentujici jeden scitac (instance) (define make-inc (lambda () (let ((value 0)) (lambda (x) (set! value (+ value x)) value)))) (define i (make-inc)) (define j (make-inc)) (define k (make-inc)) i ; #<procedure> (prvni citac) j ; #<procedure> (druhy citac) k ; #<procedure> (treti citac) Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 51 / 75

Procedury generující procedury s vnitřním stavem (i 1) ; 1 (i 1) ; 2 (i 1) ; 3 (j 5) ; 5 (j 5) ; 10 (j 5) ; 15 (j 0) ; 15 (k 10) ; 10 (k 20) ; 30 (k 0) ; 30 Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 53 / 75

;; novy map, ktery spolu s prvkem predava i jeho index ;; vyresili jsme pomoci map a procedury, ;; ktera vyuziva zmenu stavu (define map-index (lambda (f l) (let ((i -1)) (map (lambda (x) (set! i (+ i 1)) (f i x)) l)))) (map-index cons '(a b c d e)) ; ((0. a) (1. b) (2. c) (3. d) (4. e)) Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 55 / 75

;; v predchozi ukazce jsme tise predpokladali, ;; ze map funguje,,odpredu'' ;; pokud nekdo zmeni samotny map, dostaneme se do maleru: ;; ukazkova verze map, ktera pracuje,,odzadu'' (define map (lambda (f l) (let iter ((l (reverse l)) (aux '())) (if (null? l) aux (iter (cdr l) (cons (f (car l)) aux)))))) (map-index cons '(a b c d e)) ; ((4. a) (3. b) (2. c) (1. d) (0. e)) Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 57 / 75

Procedury sdílející týž stav (define p (make-pred <=)) ((car p) 10 20) ; #t ((car p) 20 30) ; #f ((car p) 30 20) ; #f ((cadr p)) ; ((10. 20) (20. 30) (30. 20)) Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 59 / 75 ;; vytvoreni,,chytreho predikatu'', ;; ktery si pamatuje s jakymi hodnotami byl volan (define make-pred (lambda (pred?) (let ((called-with-values '())) `(,(lambda (x y) (set! called-with-values (cons (cons x y) called-with-values)) (pred? x y)),(lambda () (reverse called-with-values))))))

Použití ;; nyni muzeme videt, jak mergesort postupne porovnava prvk (let* ((pred (make-pred <=)) (new-pred? (car pred)) (get-called (cadr pred))) (display (mergesort '(4 2 8 5 6 4 5 3 5 6 7 8) new-pred?) (newline) (get-called)) ;; nebo quicksort (let* ((pred (make-pred <=)) (new-pred? (car pred)) (get-called (cadr pred))) (display (quicksort '(4 2 8 5 6 4 5 3 5 6 7 8) new-pred?) (newline) (get-called)) Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 61 / 75

Jednoduchý objektový systém Objektové paradigma (zabývá se jím celý třetí semestr PP) my se jím nebudeme přímo zabývat základní myšlenka: programator spravuje systém elementů (objektů), které mají svůj stav; vypočetní proces v OO jazyku je složen ze vzajemné interakce objektů a změn jejich stavu (nejznámější objektové systémy jsou založeny na zasíláni (emisi) signálů a jejich příjmu (pomoci slotů), tzv. message-passing style of programming) Některé problémy se pomocí OO řeší pohodlně např. okna, tlačítka a jiné prvky GUI mají svůj přirozený stav, lze je chápat jako objekty v terminologii OO. Ukážeme jednoduchý objektový systém umožňující vytváření instancí to jest elementů jednoho typu, které mají vnitřní stav a komunikují s vnějším světem pomocí signálů Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 63 / 75

(define stack ;; data (vnitrni stav objektu) (let ((stack '()) (depth 0)) (define is-empty? (lambda ()...)) (define push (lambda (elem)...)) (define pop (lambda ()...)) (define top (lambda ()...)) ;; dispatch (aktivuje jednotlive procedury podle jmen s (lambda (signal. args) (cond ((equal? signal 'empty?) (is-empty?)) ((equal? signal 'push) (push (car args))) ((equal? signal 'pop) (pop)) ((equal? signal 'top) (top)) (else (error "unknown signal")))))) Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 65 / 75

; priklad pouziti (stack 'push 10) (stack 'top) ; 10 (stack 'push 20) (stack 'top) ; 20 (stack 'push 30) (stack 'top) ; 30 (stack 'empty?) ; #f (stack 'pop) (stack 'pop) (stack 'pop) (stack 'empty?) ; #t (stack 'pop) ; cannot perform `pop', stack is empty Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 67 / 75

;; je zasobnik prazdny? (define is-empty? (lambda () (= depth 0))) ;; pridej prvek na vrchol (define push (lambda (elem) (set! stack (cons elem stack)) (set! depth (+ depth 1)))) Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 69 / 75

;; odstran prvek z vrcholu (define pop (lambda () (if (is-empty?) (error "cannot perform `pop', stack is empty") (begin (set! stack (cdr stack)) (set! depth (- depth 1)))))) ;; vrat prvek nachazejici se na vrcholu (define top (lambda () (if (is-empty?) (error "stack is empty") (car stack)))) Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 71 / 75

(define make-stack (lambda () (let ((stack '()) (depth 0)) (define is-empty? (lambda ()...)) (define push (lambda (elem)...)) (define pop (lambda ()...)) (define top (lambda ()...)) (lambda (signal. args) (cond ((equal? signal 'empty?) (is-empty?)) ((equal? signal 'push) (push (car args))) ((equal? signal 'pop) (pop)) ((equal? signal 'top) (top)) (else (error "unknown signal"))))))) Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 73 / 75

(define s1 (make-stack)) (define s2 (make-stack)) (s1 'push 10) (s2 'push 'a) (s1 'push 20) (s2 'push 'b) (s1 'push 30) (s1 'top) ; 30 (s2 'top) ; b Vilém Vychodil (UP Olomouc) PP II, Př. 1: Vedlejší efekt 15. února 2007 75 / 75