LISP n LISP list processing obradba struktura simbola
LISP n LISP (list processing) – obradba struktura simbola Herbert Simon, Allen Newell – IPL (1956) John Mc. Carthy – LISP kao Touringov stroj (1960) Zašto LISP – zato jer je to optimalna razina apstrakcije za obradbu simbola Od 10 najpopularnijih udžbenika o inteligentnim sustavima, u 6 su primjeri dati u LISP-u, 3 u pseudokodu, 1 u Prologu. Referentna literatura: n Guy L Steele, Common Lisp: The Language Digital Press, CLTL 1 (1984), CLTL 2 (1990). n Association of Lisp Users: http: //www. lisp. org/. Uvod u programiranje: n David S. Touretzky, A Gentle Introduction to Symbolic Computation, Benjamin/Cummings, 1990. n Paul Graham, ANSI Common Lisp. Prentice Hall, 1995. 1
LISP i funkcijsko programiranje n n Imperativni jezici (Basic, Fortran, C, Pascal, Java …) – intenzivno korištenje pridruživanja. Funkcijski jezici (Haskell, ML, LISP ? , Scheme, …) n n n Gradbeni blokovi su izrazi koji se evaluiraju kroz primjenu funkcija. U čistim funkcijskim jezicima nema pridruživanja. Funkcije dohvaćaju ulazne parametre temeljem čitaj-samo (engl. read only) pristupa te konstruiraju rezultat. Nema promjene ranijih vrijednosti stanja (npr. globalnih ili “static” varijabli). Microsoft predložio F# (čitaj: F sharp) kao varijantu ML u kojem se kombinira funkcijski i objektno usmjeren pristup u . NET Visual Studio okruženju. 2
LISP – temeljne značajke n n n n Viša razina apstrakcije od imperativnih jezika (npr. C), jer izvođenje ovisi o tipovima parametara, a program i podaci mogu se modificirati tijekom izvođenja. LISP se pokreće funkcijama: funkcije prenose rezultate drugim funkcijama, koje prenose daljnjim funkcijama itd. LISP je visoko rekurzivan glede struktura podataka (liste, stabla, …) i algoritama. Održava jednakost programa i podataka. Temeljna struktura podataka je lista. LISP programi su također formulirani kao liste. Suprotno C-u, funkcije u LISP-u objekti prvoga reda: mogu se kreirati, modificirati i evaluirati kao da su jednostavne varijable. Tip varijable ne mora se deklarirati unaprijed. Podaci nose tip pa funkcije za vrijeme izvođenja odlučuju o specifičnoj akciji (kasnije prihvaćeno u OO paradigmi). Implicitan rad s pokazivačima. Zbog interpreterskog rada i brzog oblikovanja prototipa, LISP je pogodan za probleme koji početno nisu potpuno razumljivi, kao što je oblikovanje ekspertnih (inteligentnih) sustava. 3
LISP – Zašto je (ali stvarno) nepopularan ? n n Funkcijski jezik, novo (još jedna) paradigma programiranja. Neobična sintaksa. Polagan u izvođenju. Gdje su radna mjesta ? n n Odgovor: vidi http: //lispjobs. wordpress. com/ Temeljno: n n Izgleda tako različito prema postojećim popularnim jezicima. Ako programeri ne mogu biti produktivni u jednom danu, nova tehnologija ih ne privlači. 4
LISP (Scheme – 30 godina temeljni jezik na MIT) H. Abelson and G. J. Sussman Structure and Interpretation of Computer Programs, MIT Press, 1996. http: //mitpress. mit. edu/sicp/full-text/book. html 5
LISP na CMU David S. Touretzky Common Lisp: A Gentle Introduction to Symbolic Computation, This book may be distributed in hardcopy form, for non-profit educational purposes, provided that no fee is charged to the recipient beyond photocopying costs. All other rights reserved. You may not redistribute the Postscript file, e. g. , you may not put a copy on another web page, or include it on a CDROM. Entire book -- PDF (1 MB file) http: // www-2. cs. cmu. edu/~dst/Lisp. Book/index. html 6
LISP – najpopularnija komercijalna inačica Allegro CL® n Allegro CL ® is the most powerful dynamic object-oriented development system available today, and is especially suited to enterprise-wide, complex application development. n n Complex applications with billions of objects are now made easy with Allegro CL. The complexity of today's software applications and the explosion of data size are pervasive in all fields ranging from Life Sciences to Manufacturing to Financial Analytics. Allegro CL , is the most effective system for developing and deploying applications to solve these complex problems in the real world. For more information, contact info@franz. com. 7
XLISP – LISP za kolegij: Ekspertni sustavi Tom Almy The XLISP-PLUS Home Page: http: //www. almy. us/xlisp. html n n XLISP-PLUS is an evolutionary improvement over David Betz's Xlisp 2. 1. It contains many enhancements and bug fixes. XLISP-PLUS contains the work of many individuals. While most have contributed their efforts to the public domain, a few reserve their copyrights when XLISP is used commercially. XLISP-PLUS is only distributed for non-commercial (or educational) use. CMU Common LISP n CMUCL is a free Common Lisp implementation, originally developed at Carnegie Mellon University. n CMUCL runs on most Unix-like platforms, including Linux and BSD; there is an experimental Windows port. 8
LISP – sintaksa i semantika n n n Sintaksu čine simbolički izrazi, t. j. s-izrazi (engl. s-expressions). S-izrazi su atomi ili liste. Atomi: n n Liste - rekurzivan definicija n n n Brojevi (3. 14, 100, …) Niz znakova = string ("ovo je string") – navodnici (dvostruki) Simboli (a, ana, x 101, blok, b, 3 a, …) Atom je s-izraz. Ako su S 1, S 2, …, Sn s-izrazi, tada je s-izraz (S 1 S 2 … Sn) lista. Semantiku određuje petlja izvođenja: čitaj-evaluiraj-ispiši svakog s-izraza. n Evaluiraj znači: nađi pridijeljenu/povezanu (engl. bound) vrijednost ili strukturu podataka. n "Binding" – povezivanje imena s memorijskom lokacijom. 9
LISP – primjeri u interpreterskom radu, “>” je “prompt” Evaluacija atoma: U pravilu se ne razlikuju mala i velika slova. >5 5 >"zagorje" >a ERROR >t t >nil >() nil ; broj kao atom se evaluira u samoga sebe ; ovo je odziv sustava ; string kao atom, evaluira se u samoga sebe ; pogreška, simbol nije povezan ni s čim : LISP uvijek traži izraz povezan sa simbolom ; rezervirani simboli istinitosti t=true, nil=false ; evaluiraju se sami u sebe. ; prazna lista je neistinost 10
LISP – primjeri >(1 2 3) ; evaluacija liste ERROR: 1 undefined function >(+ 1 2 3) 6 Evaluacija liste: (fn a 1 a 2 a 3 …) Evaluiraju se argumenti a 1 …, (od lijeva na desno) te se zatim na rezultat primijeni postojeća definicija funkcije fn (u LISP su ugrađene/definirane mnoge funkcije). Prvi član liste mora biti ugrađena ili naknadno definirana funkcija. >(+ (* 2 3) (- 5 1)) ; evaluacija iznutra prema van 10 >’(1 2 3) ; evaluaciju možemo zabraniti na dva načina (1 2 3) >(quote (1 2 3)) (1 2 3) 11
LISP – primjeri Povezivanje simbola (“set equal”): >(setq a ‘(1 2 3)) ; simbol povežemo s listom koja se evaluira (1 2 3) ; ako nije eksplicitno zabranjeno (ovdje jest) >a (1 2 3) >(setq bla_bla (+ 1 2 3)) ; evaluacija liste prije povezivanja 6 ; atomički simbol bla_bla >bla_bla 6 >(setq c ‘(sir vrhnje)) (sir vrhnje) >(setq d (sir vrhnje)) ERROR – sir nedefinirana funkcija >’e E ; nije pogreška jer je zabrana evaluacije 12
LISP – primjeri Ugrađene funkcije - Obradba listi : >(car '(a b c)) ; vraća prvi član, lista se ne evaluira A >(cdr '(a b c)) ; vraća ostatak (B C) >(cons 'a '(b c)) ; dodaj na početak (dva argumenta) (A B C) >(list 'a '(b c) 'd) ; konstruktor više argumenata (A (B C) D) >(append '(a) '(b c)) ; spaja liste, list bi dala ((A) (B C)) (A B C) >(first '(a b)) ; second, third, fourth, rest-lista od ostatka A ; "first" i "rest" umjesto "car" i "cdr" >(nth 9 '(a b c d e f g h i j)) J ; započinje s 0 -th 13
LISP – primjeri Neke Booleove funkcije(ugrađene), vraćaju T, impicitno T, ili NIL: >(zerop 0) T >(minusp 4) NIL >(member 'b '(a b c)) (B C) >(listp '(a)) T >(atom 'x) T >(atom x) NIL >(setq x 7) 7 >(atom x) T ; eksplicitna istinitost ; eksplicitna neistinitost ; implicitna istinitost ; (a) je ispravna lista ; x je atom bez evaluacije ; evaluacija "x", nije povezan ; sad je vezan pa je istina, T 14
LISP – primjeri Još o Booleovim i logičkim funkcijama: Ugrađene Booleove: evenp, oddp, numberp, greaterp, lessp (<), >=, <=, … Logičke funkcije: (and arg 1 arg 2 …) ; ako svi non-NIL vraća zadnij arg ; inače NIL (propada na prvom NIL). (or arg 1 arg 2 …) ; vraća prvi evaluirani non-NIL arg. (not arg) ; T ako evaluacija arg je NIL i ; obratno 15
LISP – primjeri Uvjetne funkcije (omogućuju grananja) cond, if, do, while (cond (test 1 akcija 1) (test 2 akcija 2) … (test. N akcija. N)) Ako svi testovi negativni, rezultat je NIL. Primjer: (cond ((< x 0) (* x -1)) ; ako x neg. pomnoži s -1 (t x)) ; inače (t je uvijek pozitivan test) x (if <test> <arg 1> <arg 2>) then else ; if ima strogo 3 argumenta Učitavanje s tastature: >(+ 5 (read)) ; upis s-izraza, bez () "read" je simbol 4<ret> ; zagrada mu daje oblik funkcije 9 16
LISP – programiranje Programiranje = definiranje novih funkcija (defun <f_symbol> (<formal_params>) <tijelo_funkcije>) Tipičan primjer: >(defun fact (n) (cond ((zerop n) 1) (t (* n (fact (- n 1)))))) FACT >(fact 3) 6 >(fact 3. 14) ? ? ; rekurzivna procedura !! ; ako parametar nije cijeli broj: “stack overflow” jer nikad n=0 17
LISP – primjeri DO-petlja: (do ((var_1 vri_1 update_1) (var_2 vri_2 update_2) … ) (test pov_vriednost) (<s-izrazi>) ) ; ako test=NIL continue ; eval, i update var Primjer: Definiraj funkciju koja ispisuje članove liste: >(defun printem (lis) (do ((xx lis (cdr xx)) ; init, update (i 1 (+ 1 i)) ) ; i=counter ((null xx) (princ "gotovo") (terpri)) ; test = T, terpri no eval (prin 1 i) ; ako NIL ispiši i “update” (princ ": ") ; redni broj elementa i : ((prin 1 (car xx)) ; ispiši element (terpri))) ; novi red PRINTEM 18
LISP - Globalni i lokalni simboli (varijable) >(setq a 1) ; globalno vezanje simbola a 1 >(fact a) ; funkcija koristi globalnu varijablu, pažnja ! 1 >(defun f (x) (setq a (+ a 1)) (+ x a)) ; def jednu novu funkciju "f" f >(f 5) ; f nije prava funkcija jer joj rez. ne ovisi 7 ; isključivo o vrijednosti param. pri zvanju (5). >(f 5) ; Popratni efekt, vezanje glob var se promijenilo 8 >(let ((a 5) (b 4)) (+ a b)) ; globalno vezanje izbjegavamo s let 9 ; lokalno vezanje simbola a->5, b->4 > ; nakon izlaza nestaju sva lokalna vezanja >a ; globalno vezanje simbola "a" ostaje sačuvano 3 ; nakon 2 zvanja funkcije f: a->3 >b ; za svaki simbol postoje posebne liste vezanja ERROR: b nije povezan na najvišoj razini 19
LISP - Simboli i varijable n Simboli su atomički tip podataka u LISP-u. Simbol je podatkovni objekt s imenom, vrijednosti, funkcijom, paketom itd. U listi (otac ivan ante) nalaze se tri simbola. n Kad simbol označuje vrijednost (ne nužno brojčanu), to je varijabla: n n >(setq first 'prvi) prvi >first prvi U isto vrijeme isti simbol može predstavljati i ime funkcije. >(first '(1 2 3)) 1 n n n Kada nije na početku liste simbol predstavlja varijablu. U različitom kontekstu simbol predstavlja različiti objekt. Simboli su meta reprezentacija varijabli. 20
LISP - Funkcije višeg reda (parametri su druge funkcije) >(funcall #'car '(a b c)) ; prima funkciju (ovdje car) kao argument a ; i primjenjuje na argumente #' - leksičko okruženje, prenosi i povezane varijable >(mapcar #'+ '( 1 2 3) '(4 5 6)) ; map funkcija s više argumenata (5 7 9) ; sukcesivna primjena + Definiraj funkciju filter koja na elemente liste primjenjuje neki po volji test (t. j. neku drugu funkciju) i konstruira listu iz filtriranih elemenata. U pozivu filter se definira koji test. >(defun filter (lista test) ; lista i funkcija za test (cond ((null lista) nil) ; ako nije prazna filtriraj ((funcall test (car lista)) ; test 1. člana i ako OK uzmi (cons (car lista) (filter (cdr lista) test))) ; cons listu od njega i dalje (t (filter (cdr lista) test)))) ; ako raniji test neg. idi dalje s cdr FILTER >(filter '(1 2 3 4) #'plusp) (1 2 3 4) >(filter '(1 2 3 4) #'zerop) ; bilo koju regularnu funkciju za test NIL 21
LISP - Funkcije višeg reda i Lambda izrazi Funkcija "apply“: slična "funcall" prihvaća LISTU argumenata: >(apply #'+ '( 1 2 3 4)) 10 >(funcall #'+ 1 2 3 4) 10 ; arg (jedan) je lista ; više argumenata, sukcesivna primjena Lambda izrazi: (lambda (<formalni-parametri>) <tijelo>) Ranije, funkcija koja se prenosi kao parametar mora biti definirana. Definicija funkcije može se prenijeti izravno Lambda izrazom. >(funcall #'(lambda (x) (* x x)) 4) 16 >(mapcar #’(lambda (x) (* x 2)) '(1 2 3 4)) (2 4 6 8) 22
LISP – datoteke i petlja interpretera Upis datoteka >(load 'moj_prog. lsp) T Primjer “moj-lisp”: >(defun moj-lisp () (print 'daj_izraz) (print (eval (read)) (terpri) (moj-lisp)) MOJ-LISP >(moj-lisp) DAJ_IZRAZ (* 3 6) 9 DAJ_IZRAZ ; prompt ; izvedi glavnu petlju LISP-a ; novi red ; opet 23
LISP – primjeri Definiraj rekurzivnu funkciju "postoji" koja vraća T ako se dati atom pojavljuje bilo gdje u nekom izrazu, a NIL inače. Npr. postoji li varijabla x u izrazu: >(postoji 'x '(sqrt (/ (+ (exp x 2) (exp y 2))) T ; ; definicija funkcije "postoji“ (defun postoji (item s) (cond ((eql s item) t) ((null s) nil) ((atom s) nil) (t (or (postoji item (first s)) (postoji item (rest s)))))) ; postoji item u izrazu s ; item=s, gotovo ; s je prazna, gotovo ; s samo atom, gotovo ; rekurzivno gledaj ; prvi član ili ostatak 24
LISP – primjeri Simbolu se može pridružiti obilježje koje ima neku vrijednost. Npr. simbolu "kosara" moze se pridružiti obilježje (svojstvo, engl. property) "sadrzaj" s vrijednoscu "(kruh mlijeko sir)“ : >(get 'kosara 'sadrzaj) ; get vadi vrijednost obilježja simbola “košara” Nil ; jos nije ništa pridruženo obilježju >(setf (get 'kosara 'sadrzaj) '(kruh mlijeko sir)) ; setf pridružuje (KRUH MLIJEKO SIR) ; setf je kao setq samo na složene strukture >(get 'kosara 'sadrzaj) ; sada postoji vrijednost (KRUH MLIJEKO SIR) n Definiraj imena očeva iz nekog rodoslovnog stabla kao vrijednosti obilježja "otac" za niz osoba (simbola). Primjer kao gore. Definiraj funkciju koja vraća najdaljeg pretka neke osobe. Pretpostavi da nema ponavljanja imena u rodoslovnom stablu. (defun najdalji_predak (x) ; x je simbol osobe (if (get 'x 'otac) ; ako obilježje ‘otac ima vrijednost (najdalji_predak (get 'x 'otac)) ; idi dalje i traži vrijednost 'x)) ; inače stani (if-then-else) n 25
LISP – složene strukture podataka (1/2) (defstruct <ime_struct> (<ime_polja_1> <default_vrijednost_1>) … (<ime_polja_N> <default_vrijednost_N>)) >(defstruct osoba (sex nil) (osobnost 'blaga)) OSOBA >(setf osoba_1 (make-osoba)) ; konstruktor make-osoba #S(OSOBA SEX NIL OSOBNOST BLAGA) >(setf osoba_2 (make-osoba : sex 'zensko)) ; nova vrijednost "S(OSOBA SEX ZENSKO OSOBNOST BLAGA) >(osoba-sex osoba_2) ; vadi vrijednost polja ZENSKO >(setf (osoba-sex osoba_2) 'musko) ; mijenja vrijednost MUSKO >(osoba-sex osoba_2) MUSKO 26
LISP – složene strukture podataka (2/2) Nasljeđivanje struktura: >(defstruct (hacker (: include osoba)) ; nova struct - proširena (programira lisp)) ; novo polje HACKER >(setf nn make-hacker) ; konstrukcija objekta “nn” #S(HACKER SEX NIL OSOBNOST BLAG PROGRAMIRA LISP) >(hacker-sex nn) NIL ; hacker je "naslijedio" od osobe >(hacker-programira nn) LISP >(osoba-programira nn) ; osoba nema ovo polje ERROR: nedefinirana funkcija "osoba-programira" 27
LISP – Objektno usmjerenje CLOS (defclass <class_name> <list_of_superclasses> ((slot_name 1 : accessor <accesor_procedure_1> : initform <init_value_1> : initarg <arg_marking_1>) (slot_name 2 … )) Opcije slotova: : accessor : initform : initarg - procedura za čitati/pisati u slot (nepotrebno zvati "slot-value") - početna vrijednost - pridruženo ime kao slot, potrebno samo za "make-instance“ instanciranje slota (defclass person () ((name : accessor person-name : initform 'bill : initarg : name) (age : accessor person-age : initform 10 : initarg : age))) 28
LISP – Objektno usmjerenje CLOS Instanciranje razreda "pearson" u objekt "p 1": >(setq p 1 (make-instance 'person : name 'jill : age 100)) #<person @ #x 7 bf 826> > (person-name p 1) ; ispis vrijednost slota jill >(setf (person-age p 1) 101) ; promjena vrijednosti 101 >(person-age p 1) 101 >(slot-value p 1 'name) ; drugi nacin pristupa objektu p 1 jill ; vrijednost slota name >(setf (slot-value p 1 'name) 'jillian) jillian >(person-name p 1) jillian 29
LISP – Objektno usmjerenje CLOS Nasljeđivanje (razreda "pearson"): >(defclass teacher (person) ; može nasljeđivanje od više razreda ! ((subject : accessor teacher-subject : initarg : subject))) #<clos: standard-class teacher @ #x 7 cf 796> >(defclass maths-teacher (teacher) ((subject : initform "Mathematics"))) #<clos: standard-class maths-teacher @ #x 7 d 94 be> >(setq p 2 (make-instance 'maths-teacher : name 'john : age 34)) #<maths-teacher @ #x 7 dcc 66> >(describe p 2) #<maths-teacher @ #x 7 dcc 66> is an instance of class #<clos: standardclass maths-teacher @ #x 7 d 94 be>: The following slots have : INSTANCE allocation: age 34 name john subject "Mathematics" 30
LISP – Objektno usmjerenje CLOS Generičke funkcije (poruke objektu, operacije, metode): Poruka se šalje: (operation-name instance arg*) Definicija funkcije: (DEFMETHOD generic-function-name specialized-lambda-list form*) <specialized-lambda-list>: ((var 1 class 1) ; specijalizira za class 1 (var 2 class 2). . . ) ; lambda list su parametri, varijable se specijaliziraju za pojedine razrede ; bez specijalizacija = moguća primjena na sve razrede Za klasu (razred) teacher: (defmethod change-subject ((teacher) new-subject) (setf (teacher-subject teach) new-subject)) - setf mijenja vrijednost unutar složene strukture (setg ne) - varijabla teach prenosi novu vrijednost u slot subject razreda teacher 31
LISP – Objektno usmjerenje CLOS Primjeri generičkih funkcija: (defmethod area ((figure triangle) (* 1/2 (triangle-base figure) (triangle-altitude) figure))) ; za klasu trokuta (defmethod area ((figure rectangle) (* (rectangle-width figure) (rectangle-heigh figure))) ; za kasu četverokuta Obje metode imaju isto ime : area Pojedina metoda se uključuje samo ako: figure parametar povezan sa triangle ili rectangle specijalizatorom area = generička funkcija 32
LISP – Upravljanje memorijom (1/2) Unutarnja organizacija Prikaz s-izraza točkastim parovima: neki_atom => (a b) => ((a b) c) => (neki_atom. Nil) (a. (b. nil)) ((a. (b. nil)). (c. nil)) Svaka lista može se prikazati u notaciju točkastog para (obrat ne) Smještaj u memoriji: Konstruktorske ćelije (cons cells) sadrže dva kazala (na "car" i "cdr") liste u prikazu točkastim parovima: atom: �� car cdr a nil Npr. (a b) Npr. c 33
LISP – Upravljanje memorijom (2/2) Liste: (a b c) a b c nil ((a b) c) a c nil b nil Destruktori ? >(setq x 'rex) rex >(setq y x) rex Simboli x i y povezani su istom vrijednosti (memorijskom lokacijom). Mehanizmi dealokacije memorije (engl. garbage collection): brojanje referencija (sinkrono), "označi i očisti" (asinkrono) 34
Lisp Internals David Matuszek Dept. of Computer & Information Science University of Pennsilvania, USA 35
A problem with lists • In Lisp, a list may “contain” another list – For example, (A (B C)) contains (B C) • So, how much storage do we need to allocate for a list? – If any list can contain any other list, there is no limit to the size of storage block we may need – This is impractical; we need another solution 36
Pointers • Instead of actually putting one list inside another, we put a pointer to one list inside another – A pointer is a fixed, known size • This partially solves the problem, but. . . – A list can contain any number of elements – For example, the list ((A)(B)(A)(C)) contains four lists – This still leaves us needing arbitrarily large blocks of storage 37
CAR and CDR • We can describe any list as the sum of two parts: its “head” (CAR) and its “tail” (CDR) – The head is the first thing in the list – The head could itself be an arbitrary list – The tail of a list is another (but shorter) list • Thus, any list can be described with just two pointers • This provides a complete solution to our problem of arbitrarily large storage blocks 38
S-expressions • In Lisp, everything is an S-expression • An S-expression is an atom or a list • You can think of these as using two different kinds of storage locations--one kind for atoms, another kind for the parts of a list – This is an oversimplification, but it will do for now 39
Atoms • An atom is a simple thing, and we draw it in a simple way: HELLO ABC NIL • Sometimes we don’t bother with the boxes: HELLO ABC NIL 40
Lists • A list has two parts: a CAR and a CDR • We draw this as a box , called a cons cell, with two compartments, called the car field and the cdr field car field cdr field • In each of these compartments we put an arrow pointing to its respective value: value of car value of cdr 41
Example I (A) A NIL 42
Example II (ABC) A (B C) B A B (C) C NIL 43
Example III ((A) B) A NIL B NIL 44
Example IV ((A B) (C D)) A NIL B NIL C D NIL 45
Dotted pairs • In a simple list, every right-pointing arrow points to a cons cell or to NIL • If a right-pointing arrow points to an atom, we have a dotted pair (A. B) A B 46
Lisp lists are implemented with dotted pairs (A) = = A (A. NIL) NIL • Therefore, (A) = (A. NIL) • All structures in Lisp can be created from atoms and dotted pairs 47
Example V ((A. B). (C. D)) A B C D 48
Writing dotted pairs • A dotted pair is written (and printed) using parentheses and a dot: (A. B) • If the CDR of a dotted pair is NIL, the dot and the NIL are omitted: (A. NIL) = (A) • If the CDR is another cons cell, Lisp doesn’t print the dot or the parentheses – (A. (B. (C. NIL))) = (A B C) – (A. (B. (C. D))) = (A B C. D) 49
Efficiency of CDR Suppose L is the list (A B C D E) Then (CDR L) is the list (B C D E) Isn’t it expensive to create this new list? Answer: NO! It’s incredibly cheap! Lisp just copies a pointer: • • • (CDR L) L A (B C D E) 50
Efficiency of CAR and CONS • CAR is just like CDR; you just copy a pointer • CONS takes more work; you have to allocate and fill one cons cell Here’s the cons cell we add to create the list (A B) A Here’s the atom A B NIL Here’s the list (B) 51
Sharing structure • List L and list (CDR L) are said to share structure • But if L = (A B C D E) and M = (CDR L), then when you change L, won’t M be changed? • Yes, but. . . – this is where the real genius of Lisp comes in. . . • You never change L ! • None of the basic functions ever change anything that’s already there • Only CONS adds anything • The result is an extraordinarily efficient language! 52
Memory • If you only add structure, and never change or delete anything, won’t you run out of memory? • Lisp uses garbage collection to recover structures that you are no longer using – More convenient for the programmer – Safer (less subject to human error) – Extremely effective in general 53
- Slides: 53