Ohjelmoinnin peruskurssien laaja oppimäärä



Samankaltaiset tiedostot
Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Scheme-kesäkurssi luento 1

Ohjelmoinnin peruskurssien laaja oppimäärä

Scheme-kesäkurssi luento 3

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

815338A Ohjelmointikielten periaatteet Harjoitus 7 Vastaukset

Ohjelmoinnin peruskurssien laaja oppimäärä

Scheme-kesäkurssi luento 2

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

Scheme-kesäkurssi luento 5

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Java-kielen perusteet

815338A Ohjelmointikielten periaatteet

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssien laaja oppimäärä

Olio-ohjelmointi Javalla

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssi Y1

Scheme-kesäkurssi luento 4

Alkuarvot ja tyyppimuunnokset (1/5) Alkuarvot ja tyyppimuunnokset (2/5) Alkuarvot ja tyyppimuunnokset (3/5)

815338A Ohjelmointikielten periaatteet

A TIETORAKENTEET JA ALGORITMIT

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

Java-kielen perusteet

18. Abstraktit tietotyypit 18.1

Java-kielen perusteita

Bootstrap / HTDP2 / Realm of Racket. Vertailu

Listarakenne (ArrayList-luokka)

7/20: Paketti kasassa ensimmäistä kertaa

Informaatioteknologian laitos Olio-ohjelmoinnin perusteet / Salo

Ohjelmoinnin perusteet Y Python

Tietorakenteet. JAVA-OHJELMOINTI Osa 5: Tietorakenteita. Sisällys. Merkkijonot (String) Luokka String. Metodeja (public)

Tieto- ja tallennusrakenteet

Sisällys. 18. Abstraktit tietotyypit. Johdanto. Johdanto

tään painetussa ja käsin kirjoitetussa materiaalissa usein pienillä kreikkalaisilla

Luento 4 Aliohjelmien toteutus

Ohjelmoinnin jatkokurssi, kurssikoe

Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005

Aliohjelmatyypit (2) Jakso 4 Aliohjelmien toteutus

Ohjelmoinnin perusteet Y Python

Se mistä tilasta aloitetaan, merkitään tyhjästä tulevalla nuolella. Yllä olevassa esimerkissä aloitustila on A.

Luento 5. Timo Savola. 28. huhtikuuta 2006

Ehto- ja toistolauseet

Ohjelmoinnin perusteet Y Python

Clojure, funktionaalinen Lisp murre

Tietotyypit ja operaattorit

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

Ohjelmoinnin peruskurssien laaja oppimäärä, kevät

Java-kielen perusteet

Metodien tekeminen Javalla

Lyhyt kertaus osoittimista

Ohjelmoinnin perusteet Y Python

Jakso 4 Aliohjelmien toteutus

Luku 3. Listankäsittelyä. 3.1 Listat

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssi Y1

Ohjelmointitaito (ict1td002, 12 op) Kevät Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen

Ohjelmoinnin peruskurssien laaja oppimäärä

Funktionaalinen ohjelmointi

Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 4: Ohjelmointi, skriptaus ja Python

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4)

Jakso 4 Aliohjelmien toteutus

Pythonin alkeet Syksy 2010 Pythonin perusteet: Ohjelmointi, skriptaus ja Python

Ohjelmointi 2 / 2010 Välikoe / 26.3

TIETORAKENTEET JA ALGORITMIT

Ohjelmoinnin peruskurssi Y1

TIEA341 Funktio-ohjelmointi 1, kevät 2008

Ohjelmoinnin perusteet Y Python

Java kahdessa tunnissa. Jyry Suvilehto

Mikä yhteyssuhde on?

Harjoitustyö: virtuaalikone

Ohjelmoinnin peruskurssi Y1

Tyyppejä ja vähän muutakin. TIEA341 Funktio ohjelmointi 1 Syksy 2005

Ohjelmoinnin perusteet Y Python

Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes)

Pythonin Kertaus. Cse-a1130. Tietotekniikka Sovelluksissa. Versio 0.01b

Transkriptio:

Ohjelmoinnin peruskurssien laaja oppimäärä Luento 3: SICP kohdat 2.22.3, 33.1 ja 3.33.3.2 Riku Saikkonen 8. 11. 2010

Sisältö 1 Lisää listoista 2 Symbolit ja sulkulausekkeet 3 Derivoijaesimerkki 4 Muuttujan arvon muuttaminen: set! 5 Tietorakenteen muuttaminen: set-car! ja set-cdr!

Laajennettu map (SICP 2.2.1) edelliseltä luennolta: (map f l) tekee (a b c):sta (f (a) f (b) f (c)):n Schemen map on todellisuudessa monikäyttöisempi: (map f l1 l2) tekee (a b c):sta ja (d e f ):stä (f (a, d) f (b, e) f (c, f )):n listoja voi olla niin monta kuin haluaa (f :lle annetaan jokaisesta listasta yksi argumentti), mutta niiden pitää olla saman pituiset esimerkki: (map (lambda (x y) (+ x (* 2 y))) (list 1 2 3) (list 4 5 6)) (9 12 15)

Apuproseduuri accumulate eli fold-right (SICP 2.2.3) accumulate yhdistää listan alkiot halutulla operaatiolla (accumulate op init (list 1 2 3 4)) ( op 1 ( op 2 ( op 3 ( op 4 init )))) ( op x y) yhdistää x:n aiemman op :n lopputulokseen y (accumulate + 0 (list 1 2 3 4)) (+ 1 (+ 2 (+ 3 (+ 4 0)))) 10 (accumulate cons nil (list 1 2 3 4)) (1 2 3 4) (kopioi listan) vrt. (apply + (list 1 2 3 4)) (+ 1 2 3 4) apply ei toimi kaksiargumenttisilla operaatioilla (esim. cons) monissa Scheme-toteutuksissa on maksimimäärä proseduurikutsun argumenteille (Gambit-C:ssä 8192) accumulate:n määritelmä (ei tule mukana Schemessä) (define (accumulate op initial sequence) (if (null? sequence) initial (op (car sequence) (accumulate op initial (cdr sequence)))))

Accumulaten käyttöesimerkkejä (SICP 2.2.3) Parittomien lukujen neliöiden tulo (define (pr-sq-odd s) (accumulate * 1 (map square (filter odd? s)))) Ajoesimerkki: (pr-sq-odd (list 1 2 3 4 5)) 225 Korkein ohjelmoijan palkka (vain osittainen koodi) (define (salary-of-highest-paid-programmer records) (accumulate max 0 (map salary (filter programmer? records)))) Listana esitettyjen vektorien pistetulo (define (dot-product v w) (accumulate + 0 (map * v w))) Ajoesimerkki: (dot-product (list 1 2 3) (list 4 5 6)) 32

Vielä yksi apuproseduuri: flatmap (SICP 2.2.3) flatmap on kuin map, mutta litistää palautetusta listasta yhden tason pois (map f (list 1 2)) = (list (f 1) (f 2)) (flatmap f (list 1 2)) = (append (f 1) (f 2)) (map list (list 1 2)) ((1) (2)) (flatmap list (list 1 2)) (1 2) Määritelmä ja käyttöesimerkki (define (flatmap proc seq) (accumulate append nil (map proc seq))) (define (around x) (list (- x 1) x (+ x 1))) (map around (list 2 15 22)) ((1 2 3) (14 15 16) (21 22 23)) (flatmap around (list 2 15 22)) (1 2 3 14 15 16 21 22 23)

Funktionaalinen listankäsittely accumulate:sta eli fold-right:sta on peilikuva fold-left (fold-right + 0 (list 1 2 3 4)) (+ 1 (+ 2 (+ 3 (+ 4 0)))) 10 (fold-left + 0 (list 1 2 3 4)) (+ (+ (+ (+ 0 1) 2) 3) 4) 10 ks. kirjan tehtävä 2.38 molemmista on vielä versiot, joissa ei ole init -alkiota, vaan sellaisena käytetään listan ensimmäistä tai viimeistä alkiota funktionaalisessa ohjelmoinnissa listankäsittelyä tehdään usein tällaisten perusprimitiivien avulla varsinkin map, filter ja accumulate:n eri versiot erityisesti Haskell-, ML- ja Ocaml-kielissä lisää tämän kalvon asioista myöhemmällä luennolla...

Sisältö 1 Lisää listoista 2 Symbolit ja sulkulausekkeet 3 Derivoijaesimerkki 4 Muuttujan arvon muuttaminen: set! 5 Tietorakenteen muuttaminen: set-car! ja set-cdr!

Symbolit (SICP 2.3) symboli (symbol) on Schemen tietotyyppi, joka käyttäytyy melkein kuin vakiomerkkijono tai joidenkin muiden kielien enumeraatio symbolia ei voi muuttaa kahta symbolia on nopeaa (vakioaikaista) verrata toisiinsa symbolin sisältöä (mikä on kolmas merkki?) ei ole tarkoitus tutkia symboli tulostetaan pelkällä sen nimellä, esim. foo symboleita voi tuottaa Schemessä quote-nimisellä primitiivillä: 'foo tai (quote foo) foo symbolien vertailu: (eq? 'foo 'foo) #t (eli tosi) symboleita käytetään Schemessä usein enumeraatioina, erikoistapauksina proseduurien argumenteissa ja paluuarvoissa sekä kun ohjelma käsittelee Scheme-koodin näköistä syötettä

Koodi on dataa: sulkulausekkeet sulkulauseke (S-expression, symbolic expression): Lisp-syntaksin mukainen lauseke tai siitä tehty listarakenne esim. (+ (* 3 x) y) tai (if (= x y) 0 1) voi tulkita joko Scheme-koodina tai linkitettynä listana, joka sisältää symboleita, numeroita ja alilistan (read) lukee käyttäjältä sulkulausekkeen ja tekee siitä listarakenteen (write x) tai (display x) tulostaa listarakenteen x sulkulausekkeena (newline) tulostaa rivinvaihdon read lukee sitä mitä write kirjoittaa

Koodi on dataa: quote (SICP 2.3) Scheme-koodissa (quote (+ (* x y) 3)) tai lyhyemmin '(+ (* x y) 3) tuottaa listarakenteen (if (= 2 1) 4 3) on ehtolause (palauttaa kokonaisluvun 3), '(if (= 2 1) 4 3) palauttaa linkitetyn listan, jonka ensimmäinen alkio on symboli if koodissa 'x palauttaa symbolin x, pelkkä x hakee muuttujan x arvon; esim. (if (eq? x 'x)...) tavallisilla listankäsittelyoperaatioilla voi käsitellä myös näin tuotettuja listoja joten Scheme-koodin näköisiä lausekkeita (sulkulausekkeita) on helppo käsitellä

Perus-Schemen tietotyypit numero (kokonaisluku 1, rationaaliluku 1/3, liukuluku 1.2, kompleksiluku 1+3i, epätarkka luku #i1/3; toteutuksessa ei tarvitse olla kaikkia) linkitetty lista (1 2 3) tarkemmin pari (1. 2) tai tyhjä lista nil totuusarvo #t tai #f symboli foo merkkijono foo merkki #\a vektori eli yksiulotteinen taulukko #(1 2 3) proseduuri (primitiivi tai itsemääritelty) portti (esim. avatulle tiedostolle) arvon tietotyyppiä voi kysyä: number? (ja tarkempia), pair? ja null?, boolean?, symbol?, string?, char?, vector?, procedure? sekä port?

Yhtäsuuruudet Schemessä on monta eri yhtäsuuruusvertailua: eq? on tarkin ja nopein vertailufunktio (osoittaa samaan alkioon?, vrt. Javan ==) eqv? toimii myös mm. numeroille (käytetään harvoin) equal? käy listan, vektorin tai merkkijonon läpi rekursiivisesti ja käyttää eqv?:ta yksittäisiin alkioihin (vrt. Javan equals-metodi) käytetään kun halutaan tietää, onko listoilla tai vektoreilla sama sisältö (vaikka ne olisivat eri listoja) = vain numeroille, string=? vain merkkijonoille ja char=? vain merkeille myös esim. <, >=, string<?, string-ci>=?, char<? yleensä käytetään: eq? symboleille ja listoille (onko sama lista?), equal? listoille (onko samanlainen lista?), = numeroille, string=? merkkijonoille

Listoista hakeminen (SICP 2.3.1) Schemen listoista voi etsiä alkioita primitiiveillä memq, memv ja member nämä ovat muuten samanlaisia, mutta käyttävät vertailuun eq?:ta, eqv?:tä ja equal?:ia esim. (memq 'foo '(1 2 b a foo 4)) tosi tarkemmin sanoen nämä palauttavat loppulistan siitä kohdasta eteenpäin, josta alkio löytyi ja totuusarvona käytettäessä mikä tahansa lista on tosi (kaikki arvot paitsi #f ovat tosia) käytännössä: memq etsittäessä symbolia, member etsittäessä alilistaa

Assosiaatiolistat Schemessä voi myös etsiä alkion yhteyteen talletettua alilistaa: (assq 'foo '((a 1) (b 32) (foo 5) (c 3))) (foo 5) primitiivit assq, assv ja assoc toimivat muuten samoin, mutta käyttävät eri primitiiviä vertailuun tällainen lista on nimeltään assosiaatiolista eli alist, sillä se yhdistää avaimia niihin talletettuun dataan tämä on perus-schemen vastine (skripti)kielien assosiatiiviselle taulukolle tai hajautustaululle assosiaatiolista on esim. hajautustaulua paljon tehottomampi, mutta hieman monikäyttöisempi: sillä voi tutkia mitä tahansa oikean muotoista listarakennetta Scheme-toteutuksissa on yleensä myös hajautustaulu tai vastaava, esim. Gambit-C:ssä table

Sisältö 1 Lisää listoista 2 Symbolit ja sulkulausekkeet 3 Derivoijaesimerkki 4 Muuttujan arvon muuttaminen: set! 5 Tietorakenteen muuttaminen: set-car! ja set-cdr!

Symbolinen derivoija (SICP 2.3.2) Miten tekisit ohjelman, joka ottaa aritmeettisen lausekkeen (esim. 2x + 3 eli (+ (* 2 x) 3)) ja muuttujan (x) ja palauttaa derivaatan (2)? Riittää osata summan ja tulon derivointisäännöt: D(x + y) = Dx + Dy Dxy = xy + x y Ja vakion sekä muuttujan derivointisäännöt: d D vakio = 0 x = 1 d y = 0 dx dx Eikä tarvitse sieventää Kuinka paljon työtä tällaisen ohjelman tekemisessä olisi?

Ratkaisu (kokonaan!) (SICP 2.3.2) (define (deriv exp var) (cond ((number? exp) 0) ((symbol? exp) (if (eq? exp var) 1 0)) ((and (pair? exp) (eq? (car exp) '+)) (list '+ (deriv (cadr exp) var) (deriv (caddr exp) var))) ((and (pair? exp) (eq? (car exp) '*)) (list '+ (list '* (cadr exp) (deriv (caddr exp) var)) (list '* (deriv (cadr exp) var) (caddr exp)))) (else (error "unknown expression type -- DERIV" exp)))) Ajoesimerkkejä: (deriv 15 'x) 0 (deriv 'x 'x) 1 (deriv 'y 'x) 0 (deriv '(+ x 3) 'x) (+ 1 0) (deriv '(* x y) 'x) (+ (* x 0) (* 1 y)) (deriv '(+ (* 2 x) 3) 'x) (+ (+ (* 2 1) (* 0 x)) 0)

Abstrahoidumpi ratkaisu (kirjasta) (SICP 2.3.2) (define (deriv exp var) (cond ((number? exp) 0) ((variable? exp) (if (same-variable? exp var) 1 0)) ((sum? exp) (make-sum (deriv (addend exp) var) (deriv (augend exp) var))) ((product? exp) (make-sum (make-product (multiplier exp) (deriv (multiplicand exp) var)) (make-product (deriv (multiplier exp) var) (multiplicand exp)))) (else (error "unknown expression type -- DERIV" exp)))) (define (variable? x) (symbol? x)) (define (same-variable? v1 v2) (and (variable? v1) (variable? v2) (eq? v1 v2))) (define (make-sum a1 a2) (list '+ a1 a2)) (define (sum? x) (and (pair? x) (eq? (car x) '+))) (define (addend s) (cadr s)) (define (augend s) (caddr s)) (define (make-product m1 m2) (list '* m1 m2)) (define (product? x) (and (pair? x) (eq? (car x) '*))) (define (multiplier p) (cadr p)) (define (multiplicand p) (caddr p))

Sisältö 1 Lisää listoista 2 Symbolit ja sulkulausekkeet 3 Derivoijaesimerkki 4 Muuttujan arvon muuttaminen: set! 5 Tietorakenteen muuttaminen: set-car! ja set-cdr!

Sijoituslause (SICP 3.1) (set! muuttuja lauseke ) laskee lausekkeen ja sijoittaa sen arvon muuttujan uudeksi arvoksi sama muuttuja kuin mihin pelkkä muuttujan nimi koodissa viittaa muut samaan arvoon osoittavat muuttujat eivät muutu muuttuja = arvolle annettu nimi (tai: osoitin arvoon), ei arvon tallennuspaikka Esimerkkejä (define x 1) (define y x) (set! x (+ x 1)) ; nyt x = 2, y = 1 (define (f z) (set! z (+ z 1)) x) (f x) ; palauttaa 2; edelleen x = 2, y = 1 (let ((x 5)) (set! y x) ; nyt y = 5 (set! x (+ x 1)) x) ; palauttaa 6, globaali x = 2, y = 5

SICP-tyyliset oliot (SICP 3.1.1) Schemessä ei ole varsinaisia olioita, mutta saman kaltaisen rakenteen voi tehdä palautetulla proseduurilla Luokka yhdellä kentällä (balance) ja kahdella metodilla (define (make-account balance) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) (define (deposit amount) (set! balance (+ balance amount)) balance) (define (dispatch m) (cond ((eq? m 'withdraw) withdraw) ((eq? m 'deposit) deposit) (else (error "Unknown request -- MAKE-ACCOUNT" m)))) dispatch) (define acc (make-account 100)) ((acc 'withdraw) 50) 50 ((acc 'deposit) 40) 90 ; kutsu luo uuden olion

Muunnelma helpommalla metodikutsusyntaksilla Sama luokka kuin edellä (erilainen dispatch) (define (make-account balance) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) (define (deposit amount) (set! balance (+ balance amount)) balance) (define (dispatch m. args) (cond ((eq? m 'withdraw) (apply withdraw args)) ((eq? m 'deposit) (apply deposit args)) (else (error "Unknown request -- MAKE-ACCOUNT" m)))) dispatch) (define acc (make-account 100)) (acc 'withdraw 50) 50 (acc 'deposit 40) 90 ; kutsu luo uuden olion

SICP-olioista olion tila on tallessa palautetussa dispatch-proseduurissa muuttujien näkyvyys: kentät ovat private, metodit myös, paitsi että dispatch-proseduuri tekee niistä public:eja samaan ideaan voisi lisätä: enemmän paikallisia muuttujia eli kenttiä static-kenttiä eli konstruktoriproseduurin ulkopuolella määriteltyjä muuttujia (Javan static-metodi = globaali proseduuri) metodit voivat kutsua itseään ja toisiaan (dispatch on this) dispatch-proseduurissa voisi tarjota useamman rajapinnan samoihin metodeihin edellä ollut ratkaisu ei ole täydellistä olio-ohjelmointia: mm. perintä puuttuu (tästä lisää myöhemmällä luennolla... )

Sisältö 1 Lisää listoista 2 Symbolit ja sulkulausekkeet 3 Derivoijaesimerkki 4 Muuttujan arvon muuttaminen: set! 5 Tietorakenteen muuttaminen: set-car! ja set-cdr!

set-car! ja set-cdr! (SICP 3.3.1) parien (ja siis listojen) osia voi muuttaa set-car!:lla ja set-cdr!:llä vastaavasti merkkijonoja string-set!:llä, vektoreita vector-set!:llä jne. muutos näkyy kaikkialle, joka viittaa muutettuun pariin yksityiskohta: quotella (tai ':llä) tehtyä listaa ei saisi muuttaa: sellainen on vakiolista Esimerkkejä (define x (list 1 2)) (define y x) (define z (cdr x)) (set-car! x 3) ; nyt x = (3 2), y = (3 2), z = (2) (set-cdr! x (list 4)) ; nyt x = (3 4), y = (3 4), z = (2) (set-car! (cdr y) 5) ; nyt x = (3 5), y = (3 5), z = (2) (define (f a) (set-car! a (+ (car a) 1)) (car x)) (f x) ; palauttaa 4; nyt x = (4 5), y = (4 5), z = (2)

Mikä on samaa? (SICP 3.3.1) jos tietorakennetta voi muuttaa, sillä on väliä, tehdäänkö siitä kopioita vai viitataanko samaan rakenteeseen mitä tarkoittaa, että x ja y ovat samat? Schemessä: (eq? x y): sama rakenne (sama muistiosoite); (equal? x y): sama tai samanlainen Javassa vastaavasti x==y ja x.equals(y) omia tietorakenteita tehdessä pitää yleensä ottaa tähän kantaa, mahdollisesti määritellä useampi yhtäsuuruus myös omia rajapintoja tehdessä kannattaa miettiä etukäteen: 1 muuttaako rajapinnan proseduuri f argumenttina saamaansa tietorakennetta? 2 saako joku muu proseduuri muuttaa f:lle antamaansa tietorakennetta myöhemmin (jos f tallettaa sen)? 3 saako f:n palauttamaa tietorakennetta muuttaa? jos tätä ei mieti kunnolla tai ole kerrottu kirjastorajapinnan dokumentaatiossa, päätyy helposti tekemään rakenteista kopioita varmuuden vuoksi

Esimerkki: First In First Out -jono (SICP 3.3.2) (define (empty-queue? queue) (null? (front-ptr queue))) (define (make-queue) (cons '() '())) (define (front-queue queue) (if (empty-queue? queue) (error "FRONT called with an empty queue" queue) (car (front-ptr queue)))) (define (insert-queue! queue item) (let ((new-pair (cons item '()))) (cond ((empty-queue? queue) (set-front-ptr! queue new-pair) (set-rear-ptr! queue new-pair) queue) (else (set-cdr! (rear-ptr queue) new-pair) (set-rear-ptr! queue new-pair) queue)))) (define (delete-queue! queue) (cond ((empty-queue? queue) (error "DELETE! from empty queue" queue)) (else (set-front-ptr! queue (cdr (front-ptr queue))) queue))) (define (front-ptr queue) (car queue)) ; apufunktioita (define (rear-ptr queue) (cdr queue)) (define (set-front-ptr! queue item) (set-car! queue item)) (define (set-rear-ptr! queue item) (set-cdr! queue item)) Ajoesimerkki: (define q (make-queue)) (insert-queue! q 'a) (insert-queue! q 'b) (delete-queue! q) a