Documente Academic
Documente Profesional
Documente Cultură
1
1.1 Introducere – CHEZ SCHEME
2
Modul de lucru al limbajului este prin bucla read-evaluate-print,
astfel orice expresie introdusă în linie comandă este citită, apoi
evaluată şi apoi se afişează rezultatul evaluării.
3
1.2 Elementele de bază ale limbajului
• simboluri;
• expresii;
• variabile;
4
1.2.1 Tipurile primitive de date
5
<exponent> ::= e | E <integer>
6
Chez Scheme nu este „case sensitive” (nu face distincţie între literele
mici si literele mari).
7
6) Vectori – se definesc prin #(<lista-elemente>) sau
#<numar-elemente>(<lista-elemente>).
Exemplu:
>(define v ’#(a b c))
>v
#3(a b c)
>
8
>(define c1 (make-rectangular -1 1))
> c1
-1+1i
>(define c2 (make-rectangular -1 -1))
> c2
-1-1i
> (complex? c1)
#t
> (real-part c1)
-1
> (imag-part c1)
1
> (define c2 (make-rectangular -1.0 -1.0))
> c2
9
-1.0-1.0i
> (- c1 c2)
0.0+2.0i
> (+ c1 c2)
-2.0+0.0i
>
8) Numere raționale – se definesc (/ <numar1>) pentru sau
(/ <numar1> <numar2> <numar3>...) pentru .
∗
∗…
> (/ 3)
1/3
> (/ -3)
10
-1/3
> (/ 4 6)
2/3
> (/ 2)
1/2
> (/ 2.0)
0.5
> (/ 2+2i 2-2i)
0+1i
> (/ 2 2-2i)
1/2+1/2i
> (/ 2+2i 2)
1+1i
11
> (numerator 4)
4
> (denominator 4)
1
> (numerator 2/4)
1
> (denominator 2/4)
2
> (numerator 2/3)
2
> (denominator 2/3)
3
> (numerator 4.0)
4.0
12
> (denominator 4.0)
1.0
> (numerator 0.25)
1.0
> (denominator 0.25)
4.0
> (numerator -1.25)
-5.0
> (denominator -1.25)
4.0
13
1.2.2 Expresii
14
1.2.3 Variabile
15
>a
12.56
>(define a 3.e-2)
>a
0.03
>(define sir ’sirul)
>sir
sirul
>(define s ”sir de caractere”)
>s
„sir de caractere”
>
16
Pentru a afişa numele unei variabile şi nu valoarea acesteia, se
foloseşte funcţia quote cu sintaxa:
(quote <nume-variabila>)
Exemple:
>(quote a)
a
>(quote s)
s
Acelaşi rezultat se obţine dacă se tastează numele variabilei precedat
de ‘.
Exemple:
>’a
a
17
Pentru a iniţializa o variabilă cu o expresie înainte de a fi folosită
pentru o evaluare se foloseşte predicatul let cu următoarea sintaxă:
(let ((<variabila-1> <valoare-1>)
…(<variabila-n> <valoare-n>)…)
Variabilele utilizate în corpul predicatului let sunt variabile locale
acestuia şi nu sunt vizibile în afara lui.
Exemple:
>(let ((x 1))(+ x 1))
2
>(let ((x 1) (z 2)) (* x z))
2
>
18
1.3 Funcţii predefinite
1.3.1 Funcţii de interacţiune cu mediul
• load
(load „nume-fişier.ss”)
Încarcă constructori din fişierul specificat ca argument (împreună cu
calea de directoare).
• current-directory
(current-directory „cale-directoare”)
Setează directorul curent, care trebuie să fie precizat complet, iar
între subdirectoare se trece \\. Dacă calea de directoare nu este
precizată afişează directorul curent.
19
• exit
(exit)
Opreşte şi închide aplicaţia Scheme.
20
1.3.2 Funcţii numerice
•+
•-
•*
•/
• <, >
• <=, =>
•=
21
• (abs <numar>)
Întoarce valoarea absolută a argumentului său.
• (exp <numar>)
Ridică numărul e la puterea indicată de argument.
• (number? <expresie>)
Verifică dacă argumentul este număr.
22
• (symbol? <expresie>)
Verifică dacă argumentul este simbol.
• (boolean? <expresie>)
Verifică dacă argumentul are valorile de adevăr #t sau #f.
23
• (eqv? <expresie> <expresie>)
Întoarce #t dacă primul argument este echivalent cu toate celelalte
argumente.
• (even? <int>)
Întoarce #t este par și #f dacă este impar.
• (odd? <int>)
Întoarce #t este impar și #f dacă este par.
24
• (log <expresie-numerică>)
Întoarce logaritmul natural al argumentului.
• (random <expresie-numerică>)
Întoarce aleator un întreg cu o valoare în intervalul 0 şi argument.
• (sqrt <expresie-numerică>)
Întoarce rădăcina pătrată a argumentului.
• (round <expresie-numerică>)
Rotunjeşte argumentul către cel mai apropiat întreg, iar rezultatul este
un număr real.
25
• (max <expresie-numerică>+)
Întoarce valoarea celui mai mare argument numeric.
• (min <expresie-numerică>+)
Întoarce valoarea celui mai mic argument numeric.
26
Exemple:
(- 25 5)
(/ 13 3)
(/ 13.0 -2)
(/ 13 2.0)
(truncate (/ 34 3))
(modulo 20 6)
(sqrt 16)
(cos 0.5)
(sqrt -4)
(+ (* 6 2) (/ 99 33))
(number? 2.4)
(symbol? 'bq)
27
(boolean? #t)
(eq? 'adf 'afghg)
(equal? 2 2.0)
28
1.4 Liste
29
Predicate de lucrul cu listele sunt:
• (list <element1> <element2>...)
Alcătuieşte o listă din elementele specificate ca argumente.
• (list? <lista>)
Întoarce #t dacă lista primită ca argument este corectă.
• (car <lista>)
Întoarce primul element al unei liste, iar lista primită ca argument
nu trebuie să fie vidă.
30
• (cdr <lista>)
Întoarce coada listei, dar lista primită ca argument nu trebuie să fie
vidă.
• (cxxxr <lista> )
xxx pot fi a sau r şi se obţine o combinaţie a predicatelor car şi cdr.
De exemplu cadr înseamnă (car (cdr ...)), sau caadr este echivalent
cu (car (car (cdr ...))).
• (null? <lista>)
Verifică dacă o listă este vidă.
31
• (cons <lista1> <lista2>)
Construieşte o listă prin concatenarea argumentelor.
• (length <lista> )
Întoarce lungimea listei.
32
• (list-ref <lista> <pozitie>)
Întoarce elementul de pe poziţia specificată ca argument.
Numerotarea elementelor unei liste începe cu poziţia 0.
• (append <lista> …)
Adaugă elemente la coada listei specificate.
33
• (reverse <lista>)
Creează o listă ale cărei elemente sunt elementele listei iniţiale în
ordine inversată.
• (last-pair <lista>)
Întoarce ultimul element al unei liste.
34
• (list-copy <lista>)
Întoarce o copie a listei primite ca argument.
35
• (remv <obiect> <lista>)
Şterge din listă obiectul specificat ca argument.
36
Pentru definirea unei liste de literali, elementele listei sunt scrise între
paranteze ( şi ) şi sunt precedate de apostrof ’ sau se foloseşte funcţia
quote în loc de apostrof. Atunci când o expresie este precedată de
apostrof sau de quote, expresia se numeşte expresie „quote”. O astfel
de expresie nu este considerată de către Scheme ca o procedură şi nu
sunt evaluate argumentele.
Exemplu:
>(define l1 ’(a b c d e))
>(define l2 ’())
>(null? 11)
#f
>(null? l2)
#t
>(car l1)
37
a
>(cdr l1)
(b c d e)
>(cons l2 ‘(w x z))
(() w x z)
>(cons ‘a ‘(x y))
(a x y)
>(let ((x ’(a b 3)))(set-car! x 1))
>(let ((x ’(a b 3)))(set-car! x 1) x)
(1 b 3)
>(list ‘x ‘y ‘z)
(x y z)
>(list ‘0234 l1)
(234 ( a b c d e))
38
>(list ‘aa ‘bb l1)
(aa bb ( a b c d e))
>(define x ‘(a b c d e))
>(set-car! x ‘aa)
>x
(aa b c d e)
>(set-cdr! x ‘(w ww www))
>x
(aa w ww www)
>(sort < ‘(2 6 4 0))
(0 2 4 6)
39
> (define ll2 (list '( e r t) '(2 e 4)))
> ll2
((e r t) (2 e 4))
> (define ll2 (cons '( e r t) '(2 e 4)))
> ll2
((e r t) 2 e 4)
> (define ll2 (append '( e r t) '(2 e 4)))
> ll2
(e r t 2 e 4)
40
1.5 Funţii definite de utilizator
Folosind predicatul lambda se pot defini proceduri cu un număr
specificat de argumente sau cu un număr nedefinit de argumente.
Sintaxa pentru definirea unei proceduri cu:
• n argumente este:
(lambda (<var1>... <varn>) <exp1> <exp2>...)
• un argument:
(lambda <r> <exp1> <exp2>...)
41
• n sau mai multe argumente:
(lambda (<var1>... <varn>.<r>) <exp1>
<exp2>...)
unde <var>, <var1>,..., <varn> sunt parametri formali ai
procedurii, iar <exp1> <exp2>... reprezintă corpul procedurii,
evaluate secvenţial.
<r> este un parametru formal căruia i se asociază o listă cu argumente
(în număr variabil), altele decât primii n parametri formali.
Variabilele utilizate în corpul predicatului lambda sunt variabile
locale acestuia şi nu sunt vizibile în afara lui.
Valoarea ultimei expresii evaluate este valoarea returnată de funcţie.
42
Cu ajutorul procedurii lambda nu se pot defini proceduri care acceptă
un număr variabili de argumente. Pentru a crea proceduri cu
argumente opţionale se utilizează predicatul case-lambda, împreună
cu predicate de verificare a lungimii şi predicatele car şi cdr.
43
Exemplu de calculare a elementelor unei liste cu formula x+10. Într-
un fişier se scrie:
(define f (lambda (x) (+ x 10)))
; se defineste f(x)=x+10
(define conc-list (lambda (x y) (cons x y)))
;se defineste conc-list = concatenarea lui x
si y
(define l1 (list (f (* 2 3))
(f (- 27 7))
(f (/ 27 3))))
;se defineste l1 o lista ale carei elemente
;sunt evaluari ale functiei f
(define l2 (list (f (- 12 2))
(conc-list '(a b) '(c d))
44
(f 0)
))
;l2 este o lista cu elemente de diferite
tipuri
După ce se încarcă fişierul se tastează l1 şi se obţine (16 30 19), iar
apoi l2 şi se obţine (20 ((a b) c d) 10).
20 ... 10
(...c d)
(a b)
45
Exemplu: de aplicare a funcţiilor de comparare între valori numerice
(define op (lambda (o x y) (o x y)))
;f este o functie care aplica operatorul o
asupra expresiilor x si y
;intoarce un rezultat boolean
(define l (list
(cons '(2 < 3 este) (op < 2 3))
(cons '(2 = 3 este) (op = 2 3))
(cons '(2 > 3 este) (op > 2 3))
))
;lista l contine trei subliste, fiecare
continand operandul, ;operatorii si rezultatul
obtinut in urma aplicarii functiei f
46
1.6 Structuri de control
• if
(if <test-conditie> <expresie1> <expresie2>)
Testează condiţia. Dacă este adevărată execută expresie1, altfel
execută expresie2.
• cond
(cond (<test> <expresie>) ...
[else <expresie>])
Această structură este similară cu structura „if”, cu deosebirea că
poate testa mai multe condiţii. Clauza else poate să lipsească.
47
• when
(when <test-conditie> <expresie1>
<expresie2>…)
Testează condiţia. Dacă este adevărată atunci sunt evaluate
expresie1, expresie2. Dacă evaluarea condiţiei are rezultat fals, nici
una din expresii nu mai este evaluată.
• unless
(unless <test-conditie> <expresie1>
<expresie2>…)
Testează condiţia. Dacă este adevărată atunci nu este evaluată nici
una din expresii. Dacă evaluarea condiţiei are rezultat adevărat,
atunci sunt evaluate expresiile.
48
• record-case
(record-case <expresie> <clauza1>
<clauza2>...)
<clauza> ::= ((<cheie> ...) <variabile-
formale> <exp1 ><exp2 >...)
Ultima clauză poate avea şi forma:
<clauza> ::= (else <exp1 ><exp2 >...)
Este o formă redusă a structurii switch-case din limbajele de
programare. Se evaluează <expresie> utilizând predicatul eqv?
şi se compară cu <cheie> din fiecare clauză. Dacă se găseşte o
cheie care este echivalentă cu expresia, atunci variabilele formale
primesc valorile specificate ca argumente în apelul funcţiei, iar
<exp1 ><exp2 > sunt evaluate.
49
Exemple:
• de utilizare a structurii condiţionale if. Se defineşte o funcţie
„abs” care calculează modulul unui număr introdus ca argument.
Condiţia de verificat pentru structura if este (< n 0), expresia
1 care se execută dacă evaluarea condiţiei este adevărată este (-
0 n), iar expresia 2 care se execută când condiţia este falsă
este n. Apelul funcţiei se realizează astfel (abs 30).
(define abs
(lambda (n)
(if (< n 0)
(- 0 n)
n)))
50
• de utilizare pentru record case pentru utilizarea cifrelor romane
(define cifre
(lambda (x)
(cond
((eqv? x 'I) 1)
((eqv? x 'V) 5)
((eqv? x 'X) 10)
((eqv? x 'L) 50)
((eqv? x 'C) 100)
((eqv? x 'D) 500)
((eqv? x 'M) 1000)
;daca lista are un simbol
( (null? (cdr x)) (cifre (car x)) )
51
;trateaza cazuri in care cifrele sunt in
ordine crescatoare
; de tipul IM=1000-1=999, IL=50-1=49
( (< (cifre (car x)) (cifre (cadr x)) )
(- (cifre (cdr x)) (cifre (car x))) )
;trateaza cazuri in care cifrele sunt in
ordine descrescatoare
( (> (cifre (car x)) (cifre (cadr x)) )
(+ (cifre (cdr x)) (cifre (car x))) )
)))
52
>(cifre ’(i))
1
>(cifre ’(i m))
999
>(cifre ’(m i))
1001
53
>(cifre ’(m c m x c x v))
2005
m c m x c x v
1000 100- 1000 10- 100 10 5
1000+ 900+ 90+ 10+ 5
=2005
54
• de utilizare a structurilor when şi unless.
În funcţia verific1 se testează dacă „a” se află în lista x. Dacă da,
se afişează un mesaj folosind funcţia prinf, care afişează pe
monitor mesajul cuprins între ghilimele. ~s reprezintă un şablon
pentru a afişa valoarea variabilei care se află după ce s-au închis
ghilimelele. ~% reprezintă trecerea la rândul următor.
În funcţia verific2 afişează un mesaj, utilizând funcţia error.
Primul argument al funcţiei error reprezintă numele procedurii în
care a apărut eroarea, iar apoi sunt trecute argumente similar cu
sintaxa funcţiei de afişare printf.
(define verific1
(lambda (x)
(when (member 'a x)
55
(printf "'a se afla in lista ~s ~%" x))
))
(define verific2
(lambda (x)
(unless (member 'a x)
(error 'verific2 "a NU se afla in lista
~s" x))
))
56
• de utilizare a structurii record-case pentru operaţii aritmetice
(define calc
(lambda (x)
(record-case x
[(adunare) (x y) (+ x y)]
[(scadere) (x y) (- x y)]
[(inmultire) (x y) (* x y)]
[(impartire) (x y) (/ x y)]
[else (error 'calc "expresie gresita ~s"
x)])))
57
• de calcul al factorialului prin metoda iterativa şi recursivă
;calculeaza iterativ factorialul pornind de
la
; definitia n! = n × (n - 1) × (n - 2) × ...
× 1
(define factorial1
(lambda (n)
;initializeaza fact(i,a) astfel i=n si a=1
(let fact ((i n) (a 1))
;variabila a memoreaza produsele intermediare
(printf "fact(i,a)=(~s ~s)~%"i a)
;daca i=0 afiseaza a
(if (= i 0) a
58
;altfel calculeaza fact(i,a) unde i=i-1 si
a=a*i
(fact (- i 1) (* a i))
)
)
)
)
59
(printf "fact(i)=(~s)~%"i)
;daca i=0 atunci afiseaza 1
;altfel afiseaza i*fact(i-1)
(if (= i 0)
1
(* i (fact (- i 1)))
)
)
)
)
60