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

Podobné dokumenty
PARADIGMATA PROGRAMOVÁNÍ 2A MUTACE

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

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

Paradigmata programování 1

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

Paradigmata programování 1

Paradigmata programování II Korutiny a nedeterminismus

PARADIGMATA PROGRAMOVÁNÍ 2A VEDLEJŠÍ EFEKT

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

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

Paradigmata programování 1

PARADIGMATA PROGRAMOVÁNÍ 2 KORUTINY, NEDETERMINISMUS

PARADIGMATA PROGRAMOVÁNÍ 2A MAKRA III

1. Od Scheme k Lispu

Základní datové struktury

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

Přednáška 3. Rekurze 1

Dynamické datové struktury I.

Paradigmata programování 2

PARADIGMATA PROGRAMOVÁNÍ 2A MAKRA I

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

Lineární spojový seznam (úvod do dynamických datových struktur)

Dynamické datové struktury IV.

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

Spojová implementace lineárních datových struktur

Abstraktní datové typy

LISP Definice funkcí

Funkcionální programování úvod

Šablony, kontejnery a iterátory

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

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

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

Lineární datové struktury

Kolekce, cyklus foreach

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

Více o konstruktorech a destruktorech

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

PROGRAMOVÁNÍ V C++ CVIČENÍ. Michal Brabec

Abstraktní datové typy FRONTA

Stromy, haldy, prioritní fronty

Lisp 7-1. opakování destruktivních změn seznamů

Programování 3. hodina. RNDr. Jan Lánský, Ph.D. Katedra informatiky a matematiky Fakulta ekonomických studií Vysoká škola finanční a správní 2015

Paradigmata programování 1

Šablony, kontejnery a iterátory

Prioritní fronta, halda

Mělká a hluboká kopie

Datové struktury 2: Rozptylovací tabulky

Databázové systémy. - SQL * definice dat * aktualizace * pohledy. Tomáš Skopal

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

ABSTRAKTNÍ DATOVÉ TYPY (ADT)

typová konverze typová inference

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.

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

ALGORITMIZACE 2010/03 STROMY, BINÁRNÍ STROMY VZTAH STROMŮ A REKURZE ZÁSOBNÍK IMPLEMENTUJE REKURZI PROHLEDÁVÁNÍ S NÁVRATEM (BACKTRACK)

Da D to t v o é v ty t py IB111: Datové typy

Implementace LL(1) překladů

Fronta (Queue) Úvod do programování. Fronta implementace. Fronta implementace pomocí pole 1/4. Fronta implementace pomocí pole 3/4

Lokální definice (1) plocha-kruhu

Základní způsoby: -Statické (přidělění paměti v čase překladu) -Dynamické (přiděleno v run time) v zásobníku na haldě

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

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

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

Amortizovaná složitost. Prioritní fronty, haldy (binární, d- regulární, binomiální, Fibonacciho), operace nad nimi a jejich složitost

5 Rekurze a zásobník. Rekurzivní volání metody

Programování v jazyce JavaScript

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

Ú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]

Struktura programu v době běhu

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

Programování v jazyce JavaScript

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

Základní datové struktury III: Stromy, haldy

Základní způsoby: -Statické (přidělění paměti v čase překladu) -Dynamické (přiděleno v run time) v zásobníku na haldě

Reprezentace aritmetického výrazu - binární strom reprezentující aritmetický výraz

Algoritmy a datové struktury

Datové struktury. Obsah přednášky: Definice pojmů. Abstraktní datové typy a jejich implementace. Algoritmizace (Y36ALG), Šumperk - 12.

Definice uživatelského typu. Uživatelem definované typy. Součinové datové typy. Součtové datové typy. FLP - Uživatelem definované typy

Jazyk C++ II. STL knihovna kontejnery část 1

Spojový seznam. Jan Kybic.

PB přednáška (26. října 2015)

Pokročilé programování v jazyce C pro chemiky (C3220) Statické proměnné a metody, šablony v C++

Anotace. Spojové seznamy, haldy. AVL-stromy, A-B stromy. Martin Pergel,

Konstruktory a destruktory

ABSTRAKTNÍ DATOVÉ TYPY

Teorie programovacích jazyků

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

ALGORITMIZACE 2010/03 STROMY, BINÁRNÍ STROMY VZTAH STROMŮ A REKURZE ZÁSOBNÍK IMPLEMENTUJE REKURZI PROHLEDÁVÁNÍ S NÁVRATEM (BACKTRACK)

Informační systémy 2008/2009. Radim Farana. Obsah. Dotazy přes více tabulek

Dynamické datové struktury III.

Úvod do databázových systémů

2 Datové struktury. Pole Seznam Zásobník Fronty FIFO Haldy a prioritní fronty Stromy Hash tabulky Slovníky

bfs, dfs, fronta, zásobník, prioritní fronta, halda

Čtvrtek 8. prosince. Pascal - opakování základů. Struktura programu:

Datové struktury 1: Základní datové struktury

Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody

X36UNX 16. Numerické výpočty v sh příkazy expr, bc, dc. Zdeněk Sojka

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

PŘETĚŽOVÁNÍ OPERÁTORŮ

Abstraktní třídy, polymorfní struktury

Transkript:

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

;; nedojde ke zmene prvku, ale k vytvoreni noveho seznamu (define s '(1 2 3)) (set! s '(1 blah 3)) ;; mutatory paru: procedury set-car!, set-cdr! ;; destruktive zmeni par, vraci nedefinovanou hodnotu (define p (cons 1 2)) (set-car! p 'ahoj) (set-cdr! p 'svete) ;; Priklad: (define s '(1 2 3)) (set-car! (cdr s) 'blah) s = (1 blah 3) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 3 / 85

;; provazene seznamy, nutno dbat zvysene obezretnosti! ;; riziko vzniku chyb:,,nechtena mutace seznamu'' (define s '(1 2 3)) (define r (list 10 s 20)) r = (10 (1 2 3) 20) (set-car! (cadr r) 'neco) r = (10 (neco 2 3) 20) s = (neco 2 3) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 5 / 85

;; pro n=3 vytvor: ((#f #f #f) (#f #f) (#f)), etc. ;; slozitost: O(n(1+n)/2) (define f-list (lambda (n) (build-list n (lambda (i) (build-list (- n i) (lambda (x) #f)))))) (define s (f-list 4)) s = ((#f #f #f #f) (#f #f #f) (#f #f) (#f)) (set-car! (car (reverse s)) 'blah) s = ((#f #f #f #f) (#f #f #f) (#f #f) (blah)) (set-car! (cadr (reverse s)) 100) s = ((#f #f #f #f) (#f #f #f) (100 #f) (blah)) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 7 / 85

;; ta sama procedura ale efektivnejsi ;; slozitost: O(n) (define f-list (lambda (n) (if (= n 1) '((#f)) (let ((rest (f-list (- n 1)))) (cons (cons (caar rest) (car rest)) rest))))) (define s (f-list 4)) s = ((#f #f #f #f) (#f #f #f) (#f #f) (#f)) ;; ROZDIL OPROTI PREDCHOZIMU: (set-car! (car (reverse s)) 'blah) s = ((#f #f #f blah) (#f #f blah) (#f blah) (blah)) (set-car! (cadr (reverse s)) 100) s = ((#f #f 100 blah) (#f 100 blah) (100 blah) (blah)) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 9 / 85

(f-list 3)... prvni verze pouzivajici build-list (f-list 3)... druha verze (rekurzivni) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 11 / 85

;; program = data = mutovatelny seznam ;; je mozne destruktivne modifikovat samotny program (define proc (lambda (x) (display (list "Input parameter: " x)) (newline) (set-car! x (+ (car x) 1)) x)) (define test (lambda () (proc '(0)))) (test) = (1) ;; (Input parameter: (0)) (test) = (2) ;; (Input parameter: (1)). Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 13 / 85

;; konstrukce mutovatelneho paru (define cons (lambda (x y) ;; modifikatory vazby symbolu x a y (define set-x! (lambda (value) (set! x value))) (define set-y! (lambda (value) (set! y value))) ;; dispatch (lambda (signal) (cond ((equal? signal 'car) x) ((equal? signal 'cdr) y) ((equal? signal 'set-car!) set-x!) ((equal? signal 'set-cdr!) set-y!) (else 'unknown-signal))))) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 15 / 85

;; selektory car a cdr (define car (lambda (pair) (pair 'car))) (define cdr (lambda (pair) (pair 'cdr))) ;; mutace prvniho prvku (define set-car! (lambda (pair value) ((pair 'set-car!) value))) ;; mutace druheho prvku (define set-cdr! (lambda (pair value) ((pair 'set-cdr!) value))) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 17 / 85

;; klasicka nedestruktivni (funkcionalni) verze (define list-set (lambda (l index value) (let iter ((l l) (i 0)) (if (= i index) (cons value (cdr l)) (cons (car l) (iter (cdr l) (+ i 1))))))) ;; destruktivni modifikace prvku (define list-set! (lambda (l index value) (let iter ((l l) (i 0)) (if (= i index) (set-car! l value) (iter (cdr l) (+ i 1)))) l)) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 19 / 85

;; klasicky nedestruktivni (funkcionalni) append2 (define append2 (lambda (l1 l2) (if (null? l1) l2 (cons (car l1) (append2 (cdr l1) l2))))) ;; destruktivne spoj dva seznamy (define append2! (lambda (l1 l2) (if (null? l1) l2 (let iter ((l l1)) (if (null? (cdr l)) (begin (set-cdr! l l2) l1) (iter (cdr l))))))) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 21 / 85

;; pri spojeni seznamu dochazi k mutaci prvniho argumentu: (define x '(a b c)) (define y '(10 20)) (append2! x y) = (a b c 10 20) x = (a b c 10 20) y = (10 20) ;; neplati v pripade prazdneho seznamu (neni to par) (define x '()) (define y '(10 20)) (append2! x y) = (10 20) x = () y = (10 20) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 23 / 85

;; muzeme rozsirit na libovolne argumenty: (define append! (lambda lists (foldr append2! '() lists))) ;; dochazi k destrukci vsech krome posledniho ;; vsechny neprazdne seznamy se postupne,,provazou'' (define a '(a b c)) (define b '(#t #f)) (define c '(2 4 6 8)) (define d '(foo bar baz)) (append! a b c d) = (a b c #t #f 2 4 6 8 foo bar baz) a = (a b c #t #f 2 4 6 8 foo bar baz) b = (#t #f 2 4 6 8 foo bar baz) c = (2 4 6 8 foo bar baz) d = (foo bar baz) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 25 / 85

;; destruktivni pridavani prvku do seznamu (define s '(a b c)) (list-insert! s 0 'd) (list-insert! s 1 'd) ;; destruktivni odebirani prvku ze seznamu (define s '(a b c)) (list-delete! s 0) (list-delete! s 1) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 27 / 85

;; destruktivni pridavani prvku do NEPRAZDNEHO ze seznamu ;; pro prazdny seznam nelze (nejsou mutovatelne) (define list-insert! (lambda (l index value) (if (= index 0) ; vkladani na zacatek (begin (set-cdr! l (cons (car l) (cdr l))) (set-car! l value)) (let iter ((l l) (index index)) ; vkladani doprostred (if (= index 1) (set-cdr! l (cons value (cdr l))) (iter (cdr l) (- index 1))))))) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 29 / 85

;; destruktivni mazani prvku z aspon DVOUPRVKOVEHO sezn. ;; jednoprvkove seznamy nelze,,zmutovat na prazdne'' (define list-delete! (lambda (l index) (if (= index 0) (begin (set-car! s (cadr s)) ; mazani z prvni pozice (set-cdr! s (cddr s))) (let iter ((l l) ; mazani ze zbytku seznamu (index index)) (if (= index 1) (set-cdr! l (cddr l)) (iter (cdr l) (- index 1))))))) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 31 / 85

;; efektivni implementace FRONTY: vkladani+mazani v O(1) ;; vytvor prazdnou frontu (define make-queue (lambda () (cons '() '()))) ;; testuj, zda-li je dana fronta prazdna (define empty-queue? (lambda (queue) (and (null? (car queue)) (null? (cdr queue))))) ;; vrat prvek na vrcholu fronty (define queue-get caar) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 33 / 85

;; vkladani prvku na konec fronty ;; smazani prvku ze zacatku fronty Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 35 / 85

;; vloz prvek na konec fronty (define queue-insert! (lambda (queue elem) (if (empty-queue? queue) (begin (set-car! queue (cons elem (car queue))) (set-cdr! queue (car queue))) (begin (set-cdr! (cdr queue) (list elem)) (set-cdr! queue (cddr queue)))))) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 37 / 85

;; smaz prvek z vrcholu fronty (define queue-delete! (lambda (queue) (if (not (empty-queue? queue)) (begin (set-car! queue (cdar queue)) (if (null? (car queue)) (set-cdr! queue '())))))) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 39 / 85

(define q (make-queue)) q = (()) (queue-insert! q 10) (queue-insert! q 20) (queue-insert! q 30) q = ((10 20 30) 30) (queue-get q) = 10 (queue-delete! q) (queue-insert! q 40) q = ((20 30 40) 40) (queue-delete! q) (queue-delete! q) q = ((20 30 40) 40) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 41 / 85

;; nejjednodussi priklad (define a '(ahoj)) (set-cdr! a a) a = (ahoj ahoj ahoj = DrScheme vypise: #0=(ahoj. #0#) ;; tradicne napsany length: (selhava) (define length (lambda (l) (if (null? l) 0 (+ 1 (length (cdr l)))))) (length a) = (length a) = length: exp. arg. of type <prop. list>; given #0=(ahoj. #0#) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 43 / 85

(define a '(1 2 3)) (set-cdr! (cddr a) a) a = (1 2 3 1 2 3 1 2 3 = #0=(1 2 3. #0#) (define a '(10 20 30)) (set-car! (cdr a) a) a = (10 (10 (10 (10 30) 30) 30) 30) = #0=(10 #0# 30) (length a) = 3 (define a '(#f)) (set-car! a a) a = (((( )))) = #0=(#0#) (length a) = 1 Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 45 / 85

;; zacykleni linearniho seznamu (vraci nedef. hodnotu) ;; do posledniho paru misto () vlozi ukazatel na prvni par (define cycle! (lambda (l) (let iter ((aux l)) (if (null? (cdr aux)) (set-cdr! aux l) (iter (cdr aux)))))) (define s '(a b c d e)) (cycle! s) s = #0=(a b c d e. #0#) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 47 / 85

;; OTAZKA: jek detekovat cyklus v seznamu? ;; naivni (nefunkcni) reseni (define cycle? (lambda (l) (if (null? l) #f (cycle? (cdr l))))) ;; potrebujeme porovnavat fyzicke umisteni paru v pameti ;; predikal equal? nam NIJAK NEPOMUZE, protoze: (define a (cons 1 2)) (define b (cons 1 2)) (equal? a b) = #t... problem (set-car! a 10) a = (10. 2) b = (1. 2) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 49 / 85

;; eq?: je #t na cislech p.k. maji shodnou reprezentaci ;; na symbolech p.k. jmenuji se stejne ;; na parech p.k. maji stejne ulozeni v pameti ;; POZOR: predikat je castecne implementacne zavisly ;; lze jej chapat jako zakladni predikat rovnosti (eq? 1.2 1.2) = #f (eq? 2 2) = #t (eq? 'ahoj 'ahoj) = #t (eq? (cons 1 2) (cons 1 2)) = #f ;; eqv?: je #t na cislech p.k. jsou numericky rovne ;; na symbolech p.k. jmenuji se stejne ;; na parech p.k. maji stejne ulozeni v pam. ;; POZOR: predikat je castecne implementacne zavisly (eqv? 1.2 1.2) = #t (eqv? 2 2) = #t (eqv? 'ahoj 'ahoj) = #t (eqv? (cons 1 2) (cons 1 2)) = #f Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 51 / 85

(define both (lambda (type? x y) (and (type? x) (type? y)))) (define eqv? (lambda (x y) (if (and (both number? x y) (or (both exact? x y) (both inexact? x y))) (= x y) (eq? x y)))) (define equal? (lambda (x y) (or (eqv? x y) (and (both pair? x y) (equal? (car x) (car y)) (equal? (cdr x) (cdr y)))))) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 53 / 85

;; test zacyklenosti linearniho seznamu (define cyclic? (lambda (l) (let test ((rest (if (null? l) '() (cdr l)))) (cond ((null? rest) #f) ((eq? rest l) #t) (else (test (cdr rest))))))) ;; priklad pouziti (cyclic? '()) = #f (cyclic? '(a b c)) = #f (define s '(a b c)) (cycle! s) (cyclic? s) = #t Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 55 / 85

;; odcykleni linearniho seznamu ;; rozetnuti cyklu vlozenim () misto ukazatele na pocatek (define uncycle! (lambda (l) (let iter ((aux l)) (if (eq? (cdr aux) l) (set-cdr! aux '()) (iter (cdr aux)))))) ; zacyklenim + odcyklenim nemusime ziskat vychozi seznam (define s '(a b c)) (cycle! s) (set! s (cdr s)) s = #0=(b c a. #0#) (uncycle! s) s = (b c a) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 57 / 85

;; Analogicky jako existuji eq?, eqv?, equal? ;; maji sve varianty i member a assoc ;; member... pouziva k porovnani prvku equal? ;; memv... pouziva k porovnani prvku eqv? ;; memq... pouziva k porovnani prvku eq? (member '(a) '(1 2 (a) 3 4)) = ((a) 3 4) (memq '(a) '(1 2 (a) 3 4)) = #f ;; assoc... pouziva k porovnani klicu equal? ;; assv... pouziva k porovnani klicu eqv? ;; assq... pouziva k porovnani klicu eq? (assoc '(2) '((1. a) ((2). b) (3. c))) = ((2). b) (assq '(2) '((1. a) ((2). b) (3. c))) = #f Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 59 / 85

;; TEST CYKLU DO HLOUBKY ;; cyclic? testuje pouze jeden typ zacykleni ;; selhava na mnoha cyklickych stukturach ; Priklad: (define s '(a b c d e f)) (set-car! (cdddr s) (cdr s)) s = (a. #0=(b c #0# e f)) (length s) = 6 (cyclic? s) = #f Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 61 / 85

;; TEST CYKLU DO HLOUBKY ;; behem sestupu seznamem si udrzujeme seznam ;; jiz navstivenych paru, procedura vyuziva memq: (define depth-cyclic? (lambda (l) (let ((found '())) (let test ((l l)) (if (pair? l) (if (memq l found) #t (begin (set! found (cons l found)) (or (test (car l)) (test (cdr l))))) #f))))) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 63 / 85

;; OBOUSMERNE SEZNAMY: SPECIALNI CYKLICKE STRUKTURY ;; (elem. (ptr1. ptr2)) ;; ptr1.. ukazatel na predchudce ;; ptr2.. ukazatel na naslednika ;; konstruktor obousmerneho seznamu (define cons-dlist (lambda (elem dlist) (let ((new-cell (cons elem (cons '() dlist)))) (if (not (null? dlist)) (set-car! (cdr dlist) new-cell)) new-cell))) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 65 / 85

;; konstrukce obousm. sezn. (cons-dlist zkaceno consd) (define s (consd 'b (consd 'c (consd 'd '())))) (define r (consd 'a s)) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 67 / 85

;; (elem. (ptr1. ptr2)) ;; selektory car, cdr, cir (define dlist-car (lambda (dlist) (car dlist))) (define dlist-cdr (lambda (dlist) (cddr dlist))) (define dlist-cir (lambda (dlist) (cadr dlist))) ; Priklad: (zkracujeme jmena na consd, dcar, dcdr, dcir) (define s (consd 'a (consd 'b (consd 'c (consd 'd '()))))) = #0=(a (). #1=(b #0#. #2=(c #1# d #2#))) (dcar s) = a (dcir s) = () (dcdr s) = #0=(b (a (). #0#). #1=(c #0# d #1#)) (dcar (dcdr s)) = b (dcir (dcdr s)) = #0=(a (). #1=(b #0#. #2=(c #1# d #2#))) (dcdr (dcdr s)) = #1=(c #0=(b (a (). #0#). #1#) d #1#) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 69 / 85

;;; PREDAVANI ARGUMENTU PROCEDURAM (define add2 (lambda (x) (set! x (+ x 2)) x)) (define val 10) (add2 val) = 12 val = 10 ;; Chceme umoznit predevat argumenty,,odkazem'' ;; Vytvorime: BOX = mutovatelny kontainer na hodnotu Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 71 / 85

Metody předávání argumentů procedurám Předávání parametrů = metoda navázání parametrů na formální argumenty souvisí s příkazem přiřazení: A := B A... L-hodnota... paměťové místo, na které ukládáme B... R-hodnota... obsah, který ukládáme Volání hodnotou (Call by Value) volané proceduře jsou předány R-hodnoty argumentů hodnoty jsou uchovávána (vázány) v lokálním prostředí volaná procedura nemůže přiřazovat hodnoty přes argumenty jazyky: Scheme, LISP, C Volání odkazem (Call by Reference) volané proceduře jsou předány L-hodnoty argumentů volaná procedura má k dispozici odkazy na úložiště hodnot přiřazení do proměnné v těle procedury mění hodnotu argumentu v prostředí ze kterého byla procedura volána jazyky: C++ (reference &), PL1 Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 72 / 85

Metody předávání argumentů procedurám (pokr.) Volání hodnotou-výsledkem (Call by Value-Result) někdy se principu říká Copy-restore Linkage volané proceduře jsou předány L-hodnoty hodnoty jsou uchovávána (vázány) v lokálním prostředí po dokončení výpočtu se provede kopie lokálně uložených hodnot na paměťová místa předaných argumentů zdánlivě totéž jako volání odkazem rozdíl je například při paralelním vyhodnocování jazyky: FORTRAN, MPD Volání jménem (Call by Name) volané proceduře jsou předána jména argumentů pokaždé, když je během vyhodnocování těla procedury narazeno na argument zastupovaný jménem, je toto jméno vyhodnoceno jazyky: Algol 60, makra v jazyku C (přísně vzato nejsou procedury) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 73 / 85

;;; BOX (MUTOVATELNY KONTAINER NA HODNOTU) ;; vytvori box: novy objekt reagujici na dva signaly ;; signal SET... zapis hodnotu do boxu ;; signal GET... vrat hodnotu z boxu (define make-box (lambda (value) (lambda (signal. new-value) (cond ((equal? signal 'get) value) ((equal? signal 'set) (set! value (car new-value))) (else "neznamy signal"))))) ; Priklad: (define val (make-box 10)) (val 'get) = 10 (val 'set 100) (val 'get) = 100 Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 75 / 85

;; Priklad: ;; vypocti faktorial a zapis vysledek do argumentu ;; vraci vzdy symbol 'hotovo (define proc (lambda (box n) (letrec ((f (lambda (n) (if (= n 1) 1 (* n (f (- n 1))))))) (box 'set (f n)) 'hotovo))) ; pouziti: (proc val 20) = hotovo (val 'get) = 2432902008176640000 Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 77 / 85

;;; DALSI MUTOVATELNE ELEMENTY: vektory (analogie pole) ;; vytvareni vektoru pomoci hodnot (vector) = #0() (vector 10 20 30) = #2(10 20 30) (vector 10 10 10) = #3(10) (vector 'ahoj 'svete) = #2(ahoj svete) (vector 1 #f 'blah) = #3(1 #f blah) ;; vrat delku vektoru (vector-length (vector)) = 0 (vector-length (vector 'a 'b 'c)) = 3 ;; vytvareni vektoru o dane delce (hodnoty nespecif.) (make-vector 10) = #10(0) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 79 / 85

;; naplneni vektoru jednou hodnotou (define v (make-vector 10)) (vector-fill! v 'blah) v = #10(blah) ;; vytvareni vektoru o dane delce s pocatecnim naplnenim (make-vector 10 'blah) = #10(blah) ;; ziskani hodnoty podle indexu / mutace hodnoty (define v (vector 'a 'b 'c 'd 'e 'f)) (vector-ref v 2) = c (vector-set! v 2 'blah) (vector-ref v 2) = blah v = #6(a b blah d e f) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 81 / 85

;; muzeme definovat dalsi procedury, treba: ;; build-vector (analogicky jako build-list) (define build-vector (lambda (len f) (let ((new-vector (make-vector len))) (let iter ((i 0)) (if (>= i len) new-vector (begin (vector-set! new-vector i (f i)) (iter (+ i 1)))))))) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 83 / 85

Prace se seznamy / vektory:,,stejne PROCEDURY'' MAJI JINOU SLOZITOST ;;;; POROVNANI SLOZITOSTI (ZHRUBA) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; build-list O(n) build-vector O(n) ; car O(1) vector-car O(1) ; cdr O(1) vector-cdr O(n) ; cons O(1) cons-vector O(n) ; length O(n) vector-length O(1) ; list-ref O(n) vector-ref O(1) ; list-set! O(n) vector-set! O(1) ; map O(n) vector-map O(n) Vilém Vychodil (UP Olomouc) PP II, Př. 2: Mutace 22. února 2007 85 / 85