Cflp

Laborator

 

Facultatea de Automatica şi Calculatoare

Departamentul de Calculatoare


 
  Lucrarea 8 Lucrarea 9 Lucrarea 10 Lucrarea 11 Lucrarea 12 Lucrarea 13 Proiect Orar


  Lucrarea 8
 

Subiecte

  

Parametri opţionali

La definirea unei funcţii putem specifica faptul că un parametru este opţional:

OPTIONAL

(defun putere (x &optional y)
              (cond ((not y) x) ; y == 1
                    (t (expt x y))))

Funcţia de mai sus dacă primeşte un singur argument, consideră că cel de al doilea este 1. Putere dă şi o valoare implicită parametrului opţional:

OPTIONAL

(defun putere (x &optional (y 1))
              (expt x y))

Pot exista oricâţi parametri opţionali. Poate exista şi un singur parametru semnalat de &rest, a cărui valoare devine o listă cu toate argumentele în plus faţă de cele specificate la definirea funcţiei.

REST

(defun my-or (&rest r)
   (cond ((null r) nil)
         ((car r))
         (t (apply 'my-or (cdr r)))))

Macrouri

Macrourile sunt definite ca şi funcţiile dar ele nu îşi evaluează niciodată argumentele.

DEFMACRO

Urmăriţi cu atenţie exemplul următor:

(defmacro demo (par)
     (print par))
(setq this 'value-of-this)
(demo this)
this
value-of-this

La apelul macroului nu se încearcă evaluarea lui this, deci chiar this devine valoarea lui par şi se afişează this. La returnare însă this se evaluează.

OUR-IF

În exeplul următor se implementează un macro our-if.

(defmacro our-if (test success failure)
     (subst test 'test
     (subst success 'success
     (subst failure 'failure
        '(cond (test success) (t failure))))))

Parametrul failure poate fi declarat opţional.

Backquote

Mecanismul backquote permite uşor generarea de expresii a căror mare parte este fixată şi doar câteva variabile trebuie înlocuite. Caracterul backquote (`) acţionează asemănator cu quote (') cu observaţia că orice virgule ce apar în interior au efect de unquoting. pentru expresia următoare.

Backquote

(setq variable 'example)
example
`(this is an ,variable)
(this is an example)

OUR-IF 2

Folosind mecanismul backquote our-if devine:

(defmacro our-if (test success &optional failure)
    `(cond (,test ,success) (t ,failure)))

Problema 1

Definiţi un macro define care defineşte o funcţie dar având sintaxa:

(define (<nume functie> <param 1> ... <param n>)
             <corp>)

Problema 2

Definiţi un macro dotimes cu sintaxa:

(dotimes (<var> <count> <rezultat>) <corp>)

Prima dată se evaluează <count> care trebuie să dea un întreg. Apoi <var> este succesiv legata la întregi de la 0 la valoarea lui <count> minus 1. Corpul este evaluat de fiecare dată iar <rezultat> este returnat la sfârşit.
Observaţie: căutaţi o formă folosind do care este echivalentă şi apoi scrieţi macroul dotimes.

CONS

CONS construieşte noi liste folosind celule libere.
LISP pastrează o listă de celule libere din care se consumă la cerere celule. (La epuizarea celulelor libere se execută un algoritm garbage collection). CONS ia prima celulă din lista de celule libere şi îi modifică pointerul de legatură cu urmatoarea celulă.

CONS

Presupunem că avem:

(setq exemplu '(b c))

Evaluarea lui

(cons 'a exemplu)

va scoate din câmpul listei de celule libere o celulă al cărui conţinut va fi a iar pointerul către celula următoare va fi la adresa celulei al cărei conţinut este b din lista (b c). Se va retuna adresa celulei ce conţine pe a (câmpul noii liste).

APPEND

APPEND construieşte o nouă listă prin copiere.

APPEND

Să presupunem că evaluăm expresiile:

(setq abc '(a b c))
(setq xyz '(x y z))

Avem acum două liste, (a b c) şi (x y z) al căror adresă de început este memorată de abc respectiv xyz.
Ce se întâmplă la evaluarea expresiei (setq abcxyz (append abc xyz)) ?
Ceea ce am fi tentaţi să credem, dar nu se întâmplă, este următorul lucru: lista (a b c) este legată de lista (x y z) prin faptul că pointerul ce indică celula următoare a lui c (care iniţial este nil) va pointa începutul listei (x y z) (deci valoarea lui xyz), iar ceea ce retunează append este valoarea lui abc. Dacă lucrurile descrise mai sus s-ar întâmpla atunci după evaluarea expresiei listele pointate de abc şi abcxyz vor fi identice, lucru care nu se întâmplă. Felul în care append lucrează este urmatorul: creează o nouă listă copiind lista (a b c) (folosind desigur celule libere), iar listei nou creeate îi modifică ultimul pointer legându-l la începutul liste (x y z), după care reurnează începutul noii liste. Astfel primele trei celule din lista (a b c x y z)sunt copii ale celulelor din lista (a b c)pe când ultimele trei celule sunt exact celulele din lista (x y z).

Funcţii cu efect distructiv

NCONC, RPLACA, RPLACD şi DELETE

Aceste predicate alterează conţinutul celulelor de memorie şi trebuie folosite cu mare atenţie.
NCONC face exact ceea ce am fost tentaţi să credem că face APPEND. Concatenează două liste modificând ultima celulă a primei liste şi nu prin copiere.

NCONC

(setq abcxyz (nconc abc xyz))
(a b c x y z)
abc
(a b c x y z)
xyz
(x y z)

NCONC, la fel ca şi APPEND, poate lua mai multe argumente alterând sfârşitul fiecărei liste în afară de ultima.
RPLACA primeşte două argumente din care primul trebuie să fie o listă. Alterează această lista înlocuind conţinutul primei celule cu al doilea argument. Numele provine de la RePLAce CAr.
RPLACD este complementar, alterează restul listei (pointerul către celula următoare al primei celule).
DELETE elimină apariţiile primului argument în primul nivel al celui de al doilea argument, dar fizic nu alterează lista iniţială.

DELETE

(delete 'a '(a b b a b))
(b b b)

EQUAL diferă de EQL

Pentru EQL două liste sunt identice doar dacă sunt reprezentate în aceleaşi celule de memorie. Copiile nu sunt considerate identice de către EQL , dar sunt considerate egale de către EQUAL.

Problema 3

REVERSE inversează o lista prin copiere. Scrieţi o funcţia REV care inversează fizic celulele dintr-o listă. Funcţia trebuie să returneze o listă formată din acelaşi celule - construirea şi/sau returnarea unei noi liste nu este permisă!

(setq l ' (a b c d))
((a b c d)
(rev l)
(d c b a)
l
(d c b a)

Probleme

Problema 1. Define

Problema 2. Dotimes

Problema 3. Reverse destructiv