Copyright © Peter Seibel
Traducere © Razvan Popa
1. Introducere: De ce Lisp?
Daca esti de parere ca cea mai mare placere in programare vine din a face multe cu cod care iti exprima intentiile intr-un mod clar si simplu, atunci sa programezi in Common Lisp s-ar putea sa fie cea mai tare chestie pe care ai putea s-o faci cu un calculator. Vei realiza mai multe, mai rapid, folosind Lisp decat daca ai realiza cam cu orice alt limbajAsta e o afirmatie indrazneata. Pot sa o dovedesc? Nu doar in cateva pagini intr-un capitol - va trebui sa inveti ceva Lisp si sa vezi singur - si pentru aceasta exista restul cartii de fata. Deocamdata, as vrea sa incep cu niste dovezi anecdotice, povestea caii mele catre Lisp. Apoi, in sectiunea urmatoare, voi explica beneficiile pe care cred ca le poti obtine din invatarea Common Lisp.
(pe scurt ?)
Sunt probabil unul din putinii programatori de a doua generatie in Lisp. Tatal meu a inceput sa lucreze cu calculatoarele scriind un sistem de operare in limbaj de asamblare pentru masina pe care o folosea pentru a strange date pentru dizertatia de doctorat in fizica. Dupa ce a administrat sisteme de calcul la diverse laboratoare de fizica, prin anii '80 a iesit de tot din domeniul fizicii si incepuse sa lucreze la o companie farmaceutica mare. Acea companie avea un proiect in derulare pentru a dezvolta software care sa modeleze procesele de productie in uzinele sale chimice - daca ai creste marimea acestui vas, cum este afectata productia anuala? Echipa originala a consumat jumatate din fonduri si aproape tot timpul alocat programand in FORTRAN fara a avea ceva palpabil de aratat. In anii '80 cand se intampla asta era la moda inteligenta artificiala (AI) si Lisp era in voga. Asa ca tatal meu - la momentul respectiv neavand prea multe legaturi cu Lisp - a purtat o discutie cu cativa oameni de la Universitatea Carnegie Mellon (CMU) care lucrau la ceea ce avea sa devina Common Lisp pentru a vedea daca Lisp ar putea sa fie un limbaj potrivit pentru proiectul respectiv.
Cei de la CMU i-au aratat niste demo-uri la care lucrau si l-au convins. Prin urmare el si-a convins superiorii sa il lase pe el cu echipa sa sa preia proiectul si sa-l faca in Lisp. Un an mai tarziu, folosind doar ce ramasese din bugetul original, echipa sa a terminat o aplicatie in stare de functionare avand chiar si caracteristici pe care echipa originala nici nu mai spera sa le poata face. Tatal meu atributie succesul acesta deciziei lor de a folosi Lisp.
Asta e doar o anecdota, totusi. Si poate ca tatal meu s-a inselat in privinta motivului succesului lor. Sau poate ca Lisp era mai bun doar in comparatie cu celelalte limbaje de la momentul respectiv. Acum exista fel de fel de limbaje performante, din care multe au incorporat caracteristici din Lisp. Oare chiar vreau sa spun ca Lisp poate oferi si astazi aceleasi beneficii pe care le-a oferit tatalui meu in anii '80? Citeste mai departe.
In ciuda tuturor eforturilor tatalui meu, nu am invatat Lisp in liceu. Dupa o cariera in facultate care nu a implicat prea multa programare, am fost sedus de Net si m-am intors la calculatoare. Am lucrat la inceput in Perl, invatand suficient cat sa fiu periculos in timp ce lucram la un forum de discutii online pentru site-ul revistei Mother Jones, ca apoi sa lucrez la un magazin online, Organic Online, unde am lucrat la site-uri mari - pentru vremea respectiva - precum cel pentru Nike in timpul Olimpiadei din 1996. Mai tarziu m-am orientat pe Java ca programator la WebLogic, acum parte din BEA. Dupa ce am plecat de la WebLogic m-am alaturat unui alt startup unde eram programatorul sef intr-o echipa care construia un sistem tranzactional de mesagerie in Java. Intre timp, interesul meu general in limbaje de programare m-a condus sa explorez limbaje cunoscute gen C, C++ si Python, precum si limbaje mai putin cunoscute gen Smalltalk, Eiffel si Beta.
Stiam doua limbaje foarte bine si eram familiar cu inca 6. In cele din urma mi-am dat seama ca interesul meu in limbaje de programare era inradacinat in ideea plantata de povestirile tatalui meu despre Lisp - anume ca limbaje diferite sunt diferite si ca, desi toate sunt echivalente Turing, poti face mai multe lucruri in unele limbaje si sa fie mai interesant. Si totusi, ironic, nu ma ocupasem niciodata prea mult de Lisp. Asa ca am inceput sa explorez Lisp in timpul liber. Si era interesant cand vedeam cat de repede puteam sa trec de la idee la cod care functiona.
De exemplu, intr-un concediu, avand cam o saptamana la dispozitie pentru a lucra in Lisp, m-am decis sa incerc sa scriu o varianta a unui program - un sistem de algoritmi genetici de inmultire care jucau Go - pe care-l scrisesem mai devreme in cariera mea de programator Java. Chiar si impiedicat de cunostintele mele rudimentare de Common Lisp la acea data si fiind nevoit sa caut chiar si cele mai banale functii, tot m-am simtit mai productiv decat daca ar fi trebuit sa rescriu acelasi program in Java, chiar si avand cativa ani de experienta acumulati in Java de la scrierea primei versiuni.
Un experiment similar a dus la biblioteca despre care o sa discut in Capitolul 24. In anii de inceput la WebLogic scrisesem in Java o biblioteca pentru a decoda fisiere .class de Java. Functiona, dar codul era cam dezordonat si dificil de mentinut si extins. Am incercat de mai multe ori, de-a lungul anilor, sa rescriu biblioteca, gandindu-ma ca avand cunostinte mereu sporite de Java as putea gasi o varianta care sa nu fie plina de cod duplicat. N-am gasit niciodata asa o cale. Dar cand am incercat sa o fac in Common Lisp am lucrat doar doua zile si am realizat nu doar un parser de clase Java ci o biblioteca pe care puteam sa o folosesc pentru a decoda orice tip de fisier binar. Vei vedea cum functioneaza aceasta biblioteca in Capitolul 24 si o vei folosit in Capitolul 25 pentru a scrie un parser pentru informatiile ID3 din fisierele MP3.
De ce Lisp?
Este dificil sa explic in doar cateva pagini dintr-un capitol introductiv de ce utilizatorii unui limbaj il plac, si este chiar mai greu sa arati de ce ar trebui investit timp in invatarea unui anumit limbaj. Istoria personala nu ne ajuta. Poate imi place Lisp din cauza modului ciudat in care este construit creierul meu. S-ar putea sa fie genetic, deoarece tatal meu este la fel. Asa ca inainte sa te apuci serios sa inveti Lisp este rezonabil sa vrei sa stii ce avantaje vei avea.
La unele limbaje avantajele sunt evidente. De exemplu, daca vrei sa scrii cod de nivel jos in Unix, ar trebui sa inveti C. Sau daca vrei sa scrii anumite tipuri de aplicatii portabile, ar trebui sa inveti Java. Si exista multe companii care inca folosesc foarte mult C++, deci daca ai vrea sa lucrezi la una din ele ar trebui sa inveti C++.
Pentru majoritatea limbajelor, totusi, avantajele nu sunt atat de usor de recunoscut, din cauza unor criterii subiective cum ar fi sentimentul pe care-l ai cand folosesti limbajul. Avocatilor Perl le place sa spuna ca Perl "face ca lucrurile usoare sa fie usoare si cele grele posibile" si se delecteaza cu ideea ca, dupa cum o spune si motto-ul Perl, "Exista mai mult de un fel in care poti s-o faci."1 Fanii Python, pe de alta parte, cred ca Python este curat si simplu si considera codul Python mai usor de inteles pentru ca, dupa cum o spune si motto-ul lor,"Exista un singur mod de a o face."
Deci, de ce Common Lisp? Nu exista avantaje imediat si evidente pentru adoptarea Common Lisp la fel ca la C, Java sau C++ (desigur, in afara de cazul in care se intampla sa detii o Masina Lisp). Beneficiile Lisp-ului rezulta mai mult din experienta folosirii lui. Pe parcursul restului acestei carti iti voi arata caracteristicile specifice Common Lisp si cum sa le folosesti incat sa vezi si singur cum este. Deocamdata voi incerca sa iti dau o idee despre filozofia Lisp.
Zicala cea mai apropiata de un motto pe care o are Common Lisp este descrierea "limbajul de programare programabil." Desi criptica, aceasta descriere atinge radacina unuia din avantajele cele mai mari pe care le are Common Lisp fata de alte limbaje. Mai mult decat orice alt limbaj, Common Lisp urmeaza filozofia "ceea ce este bun pentru proiectantul unui limbaj este bun si pentru utilizatorii limbajului". De aceea, cand programezi in Common Lisp, nu te gasesti aproape niciodata in situatia de a dori ca limbajul sa suporte vreo caracteristica ce ti-ar face programul mai usor de scris, deoarece, dupa cum vei vedea pe parcursul acestei carti, poti sa adaugi tu insuti acea caracteristica.
In consecinta, un program Common Lisp tinde sa puna la dispozitie o mapare mult mai clara dintre ideile tale despre cum functioneaza programul si codul pe care il scrii. Ideile nu mai sunt ascunse de cod repetitiv sau amanunte minore, ceea ce face codul mai usor de mentinut deoarece nu mai trebuie sa te balacesti prin gramezi de cod de fiecare data cand trebuie sa faci o schimbare. Chiar si schimbarile sistemice in comportamentul unui program pot fi obtinute deseori cu schimbari relativ mici in codul propriu-zis. Asta inseamna si ca vei dezvolta cod mai repede; trebuie sa scrii mai putin si nu pierzi timp cautand o modalitate curata de a te exprima in constangerile limbajului.2
Common Lisp este un limbaj excelent si pentru programarea de proba - daca nu stii exact cum va functiona programul de prima data cand incepi sa scrii la el, Common Lisp pune la dispozitie cateva caracteristici care te ajuta sa dezvolti cod incremental si interactiv.
Pentru inceput, bucla interactiva citeste-evalueaza-printeaza (read-eval-print loop) pe care o voi introduce in capitolul urmator, iti permite sa interactionezi continuu cu programul pe masura ce il dezvolti. Scrii o functie noua. O testezi. O schimbi. Incerci o abordare diferita. Nu trebuie sa te opresti niciodata pentru a compila.3
Alte caracteristici care suporta un stil de programare cursiv, interactiv sunt TIPURILE DINAMICE din Lisp si sistemul de conditii din Common Lisp. Datorita primelor poti sa consumi mai putin timp convingand compilatorul ca ai voie sa iti rulezi codul si mai mult timp rulandu-l propriu-zis si lucrand la el,4 si sistemul de conditii te lasa sa dezvolti interactiv chiar si codul de tratare a erorilor.
Common Lisp, pe langa ca incorporeaza mici schimbari care pot face programele mai usor de scris, poate sa adopte cu usurinta idei noi majore despre cum ar trebui sa functioneze limbajele de programare, fiind "limbajul de programare programabil". De exemplu, implementarea originala a Sistemului de Obiecte din Common Lisp (Common Lisp Object System - CLOS), era o biblioteca scrisa in Common Lisp portabil. Asta a permis programatorilor de Lisp sa adune experienta de lucru cu facilitatile pe care le punea la dispozitie inainte sa fie incorporata oficial in limbaj.
Orice noua paradigma ar mai aparea, este extrem de probabil ca va putea fi absorbita in Common Lisp fara a face schimbari majore in nucleul limbajului. De exemplu, un programator Lisp a scris recent o biblioteca, AspectL, care adauga suport pentru programare aspect-orientata (AOP) in Common Lisp.5 Daca AOP ajunge sa fie noua mare gaselnita, Common Lisp va putea sa o suporte fara nici o schimbare in limbajul de baza si fara proprocesoare sau compilatoare in plus.6
Unde a inceput
Common Lisp este descendentul modern al limbajului Lisp conceput initial de John McCarthy in 1956. Lisp a fost proiectat pentru "procesare de date simbolice"7 si a luat numele din unul din lucrurile la care era foarte bun: Procesarea LIStelor (LISt Processing). Am parcurs un drum lung de atunci: Common Lisp nu numai ca dispune de o gama larga de tipuri moderne de date, pentru toate gusturile; un sistem de conditii care, dupa cum vei vedea in Capitolul 19, pune la dispozitie un nivel de flexibilitate inexistent in sistemele de tratare a exceptiilor din limbaje ca Java, Python si C++; si alte cateva capabilitati care pur si simplu nu exista in alte limbaje. Cum este posibil asa ceva? Ce anume ar putea provoca evolutia unui limbaj atat de bine echipat?
Pai, McCarthy era (si inca este) un cercetator de Inteligenta Artificiala (AI), si multe din capabilitatile pe care le-a construit in versiunea initiala a limbajului au facut-o sa fie un limbaj excelent pentru programarea AI. In timpul modei AI din anii '80, Lisp era o unealta preferata pentru programatorii care scriau software pentru rezolvarea unor probleme dificile ca demonstrarea automata a teoremelor, planificare si organizare, si vedere artificiala. Probleme astea necesitau mult software greu de scris; pentru a putea sa le abordeze, programatorii AI aveau nevoie de un limbaj puternic, si au dezvoltat Lisp in limbajul respectiv. Si Razboiul Rece a ajutat - deoarece Pentagonul a investit multi bani in Agentia de Proiecte Avansate de Cercetare pentru Aparare (Defense Advanced Research Projects Agency - DARPA), multi din acesti bani au ajuns la oameni care lucrau la probleme cum ar fi simulari de campuri de bataie la scara larga, planificare automata si interfate cu limbaje naturale. Acesti oameni au folosit Lisp si au continuat sa-l modifice pentru a putea face ce aveau ei nevoie.
Aceleasi forte care au condus evolutia capabilitatilor Lisp-ului au condus si dezvoltarea altor dimensiuni - problemele mari de AI consuma multe resurse computationale indiferent de modul de programare, si daca rulezi legea lui Moore invers pentru 20 de ani, poti sa-ti imaginezi ce penurie de resurse computationale hardware era in timpul anilor '80. Programatorii Lisp au fost nevoiti sa gaseasca tot felul de moduri in care sa mai scoata un pic de performanta din implementarile lor. Implementarile moderne de Common Lisp sunt mostenitorii acelori eforturi de demult si includ de multe ori compilatoare generatoare de cod masina destul de sofisticate. Azi, datorita legii lui Moore, e posibil sa existe suficienta performanta chiar si intr-un limbaj interpretat, dar asta nu mai era o problema pentru Lisp, oricum. Dupa cum iti voi arata in Capitolul 32, folosind anumite declaratii (optionale), un compilator Lisp poate genera cod masina destul de asemanator cu cel care ar fi fost generate de un compilator C.
Anii 80' au fost si perioada Calculatoarelor Lisp, existand cateva companii, dintre care cea mai cunoscuta a fost Symbolics, care produceau calculatoare ce puteau rula Lisp nativ, la nivel hardware. Astfel incat Lisp a ajuns un limbaj de programarea sistemelor, folosit pentru scrierea de sisteme de operare, editoare, compilatoare si cam tot ce rula pe Calculatoare Lisp.
De fapt, la inceputul anilor '80, datorita existentei atator laboratoare de AI si a atator implementari Lisp oferite de producatorii de calculatoare Lisp, era o atat de mare diversitate de sisteme si dialecte Lisp incat cei de la DARPA au incept sa se ingrijoreze din cauza fragmentarii comunitatii Lisp. Pentru a adresa aceasta ingrijorare, un grup de hacker-i Lisp s-au adunat in 1981 si au inceput procesul de standardizare a unui nou limbaj numit Common Lisp care combina cele mai bune capabilitati din limbajele Lisp existente. Munca lor a fost documentata in cartea Common Lisp the Language (Limbajul Common Lisp ) de Guy Steele (Digital Press, 1984) - CLtL pentru cunoscatori.
In 1986 existau primele implementari de Common Lisp, si dialectele care trebuiau sa fie inlocuite de acestea se apropiau de finalul carierei. In 1996, Institutul American National de Standarde (ANSI) a emis un standard de Common Lisp care se baza pe limbajul specificat in CLtL si il extindea, adaugand capabilitati majore cum ar fi CLOS si sistemul de conditii. Si inca nu a fost spus ultimul cuvant: ca si CLtL inaintea sa, standardul ANSI lasa intentionat loc implementatorilor sa experimenteze cu cele mai bune cai de lucru: o implementare Lisp deplina pune la dispozitie un mediu de rulare bogat cu acces la interfete grafice pentru utilizator (GUI), fire multiple de control, socket-uri TCP/IP si altele. Acum Common Lisp evolueaza ca majoritatea celorlalte limbaje open-source - oamenii care il folosesc scriu bibliotecile de care au nevoie si de multe ori le pun si la dispozitia celorlalti. In ultimii ani, mai ales, a existat o crestere insemnata a activitatii in domeniul bibliotecilor open-source pentru Lisp.
Deci, pe de o parte, Lisp este unul din limbajele "clasice" in stiinta calculatoarelor, bazat pe idei care au rezistat testului timpului. 8 Pe de alta, este un limbaj in intregime modern, cu scop general al carui design reflecta o apropiere profund pragmatica in rezolvarea problemelor reale cat de eficient si robust se poate. Unicul dezavantaj al mostenirii "clasice" este ca multi oameni au idei despre Lisp bazate pe o anumita varianta de Lisp de care au luat cunostinta la un anumit moment in ultima jumatate de secol de cand a fost inventat limbajul de catre McCarthy. Daca cineva iti zice ca Lisp poate fi rulat numai interpretat, ca e incet, sau ca trebuie sa folosesti recursivitate pentru orice, intreaba-l despre ce dialect de Lisp vorbeste si cata vreme a trecut de cand l-a invatat.9
Dar Am Invatat Lisp Mai Demult, Si Nu Era Asa Cum Zici Tu
Daca ai folosit Lisp in trecut, s-ar putea sa ai idei despre ce este "Lisp" care au putin in comun cu Common Lisp. Desi Common Lisp a inlocuit majoritatea dialectelor din care provine, nu este singurul dialect ramas, si in functie de unde si cand ai luat cunostinta de el, s-ar putea sa fi invatat unul din celelalte dialecte.
In afara Common Lisp, celalalt dialect Lisp de uz general care inca are o comunitate activa este Scheme. Common Lisp a imprumutat cateva parti din Scheme dar nu a intentionat niciodata sa-l inlocuiasca.
Initial proiectat la M.I.T., unde a fost folosit din prima ca limbaj predat la cursurile de calculator la inceput, Scheme a fost totdeauna destinat unei alte nise decat Lisp. In particular, proiectantii Scheme s-au concentrat pe pastrarea nucleului limbajului cat de mic si simplu posibil. Aceasta are avantaje evidente pentru un limbaj folosit la predare si chiar si pentru cercetatorii in programare carora le place sa poata sa demonstreze formal diverse lucruri despre limbaje.
Are si avantajul de a fi usor de inteles limbajul conform specificatiei din standard. Dar costul pentru aceste avantaje este omisiunea multor parti utile care sunt standard in Common Lisp. Implementari individuale de Scheme pot sa puna aiba aceste parti incluse, dar omisiunea lor din standard face sa fie mai greu de scris cod portabil in Scheme decat este de scris in Common Lisp.
Scheme pune accentul pe stilul functional de programare si pe folosirea recursivitatii mai mult decat Common Lisp. Daca ai studiat Lisp in facultate si ai ramas cu impresia ca este un limbaj academic fara aplicatii in lumea reala, e posibil sa fie invatat Scheme. Nu este o caracterizare neaparat cinstita a lui Scheme, dar este si mai putin aplicabila in Lisp, care a fost proiectat expres ca limbaj de inginerie pentru probleme reale decat un limbaj teoretic "pur".
Daca ai invatat Scheme, ar trebui sa fii constient si de faptul ca un numar de diferente subtile dintre Scheme si Common Lisp te pot incurca. Aceste diferente sunt si baza pentru "razboaiele religioase" dintre impatimitii din comunitatile Common Lisp si Scheme. Voi incerca sa indic cele mai importante diferente pe masura ce avansam.
Alte doua dialecte Lisp raspandite sunt Elisp, limbajul de extensie pentru editorul Emacs, si Autolisp, limbajul de exentsie pentru programul de proiectare asistata pe calculator AutoCAD, de la Autodesk. Desi e posibil sa se fi scris mai multe linii in Elisp si Autolisp decat in oricare alt dialect de Lisp, nici unul nu poate fi folosit in afara aplicatiei gazda, si amandoua sunt destul de demodate prin comparatie cu Scheme si Common Lisp. Daca ai folosit vreunul din aceste dialecte, pregateste-te sa sari in masina timpului Lisp si sa avansezi cateva decenii in timp.
In afara Common Lisp, celalalt dialect Lisp de uz general care inca are o comunitate activa este Scheme. Common Lisp a imprumutat cateva parti din Scheme dar nu a intentionat niciodata sa-l inlocuiasca.
Initial proiectat la M.I.T., unde a fost folosit din prima ca limbaj predat la cursurile de calculator la inceput, Scheme a fost totdeauna destinat unei alte nise decat Lisp. In particular, proiectantii Scheme s-au concentrat pe pastrarea nucleului limbajului cat de mic si simplu posibil. Aceasta are avantaje evidente pentru un limbaj folosit la predare si chiar si pentru cercetatorii in programare carora le place sa poata sa demonstreze formal diverse lucruri despre limbaje.
Are si avantajul de a fi usor de inteles limbajul conform specificatiei din standard. Dar costul pentru aceste avantaje este omisiunea multor parti utile care sunt standard in Common Lisp. Implementari individuale de Scheme pot sa puna aiba aceste parti incluse, dar omisiunea lor din standard face sa fie mai greu de scris cod portabil in Scheme decat este de scris in Common Lisp.
Scheme pune accentul pe stilul functional de programare si pe folosirea recursivitatii mai mult decat Common Lisp. Daca ai studiat Lisp in facultate si ai ramas cu impresia ca este un limbaj academic fara aplicatii in lumea reala, e posibil sa fie invatat Scheme. Nu este o caracterizare neaparat cinstita a lui Scheme, dar este si mai putin aplicabila in Lisp, care a fost proiectat expres ca limbaj de inginerie pentru probleme reale decat un limbaj teoretic "pur".
Daca ai invatat Scheme, ar trebui sa fii constient si de faptul ca un numar de diferente subtile dintre Scheme si Common Lisp te pot incurca. Aceste diferente sunt si baza pentru "razboaiele religioase" dintre impatimitii din comunitatile Common Lisp si Scheme. Voi incerca sa indic cele mai importante diferente pe masura ce avansam.
Alte doua dialecte Lisp raspandite sunt Elisp, limbajul de extensie pentru editorul Emacs, si Autolisp, limbajul de exentsie pentru programul de proiectare asistata pe calculator AutoCAD, de la Autodesk. Desi e posibil sa se fi scris mai multe linii in Elisp si Autolisp decat in oricare alt dialect de Lisp, nici unul nu poate fi folosit in afara aplicatiei gazda, si amandoua sunt destul de demodate prin comparatie cu Scheme si Common Lisp. Daca ai folosit vreunul din aceste dialecte, pregateste-te sa sari in masina timpului Lisp si sa avansezi cateva decenii in timp.
Pentru Cine Este Aceasta Carte
Aceasta carte este pentru tine daca esti curios in privinta Common Lisp, indiferent daca esti deja convins ca vrei sa-l folosesti sau vrei doar sa stii ce e cu toata agitatia asta.
Daca deja ai invatat ceva Lisp dar ai probleme in a face trecerea de la exercitii academice la programe reale, aceasta carte ar trebui sa te indrume. Pe de alta parte, nu trebuie sa fii deja convins ca vrei sa folosesti Lisp pentru a gasi informatii bune in aceasta carte.
Daca esti un pragmatic ce vrea sa stie ce avantaje iti poate oferi Common Lisp fata de alte limbaje precum Perl, Python, Java, C, sau C#, cartea aceasta ar trebui sa-ti dea niste idei. Sau poate nici nu-ti pasa sa folosesti Lisp - poate deja esti sigur ca Lisp nu este mai bun decat alte limbaje pe care le stii dar esti plictisit de cineva pasionat de Lisp care-ti spune ca asta e din cauza ca pur si simplu nu "intelegi." Daca e asa, aceasta carte iti va da o introducere in Common Lisp la obiect. Daca, dupa citirea acestei carti inca vei considera ca nu este mai bun Common Lisp decat limbajele tale preferate, vei avea si argumente sa explici aceasta pozitie.
Voi acoperi nu numai sintaxa si semantica limbajului dar si cum poti sa-l folosesti pentru a scrie software care face lucruri utile. In prima parte a cartii voi acoperi limbajul propriu-zis, intercaland cateva capitole "practice", in care iti voi arata cum sa scrii cod real. Apoi, dupa ce voi fi acoperit mare parte din limbaj, inclusiv cateva parti pe care alte carti te lasa sa le intelegi de unul singur, restul cartii consta din inca noua capitole practice unde te voi ajuta sa scrii cateva programe de marime medie care chiar fac lucruri utile: filtreaza SPAM-ul, analizeaza (parseaza) fisiere binare, catalogheaza MP3-uri, emit MP3-uri in retea, si pun la dispozitie o interfata Web pentru server-ul si catalogul de MP3-uri.
Dupa ce termini aceasta carte, vei fi familiar cu cele mai importante capabilitati ale limbajului si modul in care acestea relationeaza, vei fi folosit Common Lisp pentru a scrie cateva programe mai complexe si vei fi destul de pregatit pentru a continua explorarea limbajului pe cont propriu. Drumul tuturor spre Lisp e diferit, dar sper ca aceasta carte il va netezi pe al tau. Sa incepem.
1Perl merita invatat si ca "scociul Internet-ului."
2Din pacate, sunt putine date concrete despre productivitatea diferitelor limbaje de programare. Un raport in care Lisp este comparat favorabil cu C++ si Java in combinatia programator - eficienta programului este discutat la adresa
3Psihologistii au identificat o stare a mintii numita "fluidizare" (flow) in care suntem capabil de concentrare si productivitate incredibile. Importanta fluidizarii in programare este recunoscuta de aproape doua decenii de cand a fost discutata in cartea clasica despre factorul uman in programare Peopleware: Productive Projects and Teams de Tom DeMarco si Timothy Lister (Dorset House, 1987). Cele doua mari caracteristici ale fluidizarii sunt ca dureaza cam 15 minnut sa intri in starea respectiva si apoi orice intrerupere, oricat de scurta, te poate scoate din stare, fiind nevoie de inca alte 15 minute pentru a reintra in stare. DeMarco si Lister, ca majoritatea autorilor ulteriori, erau ingrijorati mai ales in privinta factorilor perturbatori gen apeluri telefonice si vizite inoportune ale sefului. Mai putin bagate in seama dar probabil la fel de importante pentru programatori sunt intreruperile provocate de uneltele folosite. Limbajele care necesita, de exemplu, o compilare lunga inainte sa poti sa incerci ultimele linii de cod scrise pot fi la fel de daunatoare fluidizarii ca si un telefon zgomotos sau un sef bagacios. Deci, un alt mod de a privi Lisp este ca un limbaj proiectat pentru a te tine intr-o stare de fluidizare.
4Acest punct de vedere e destinat sa fie controversat, cel putin pentru unii oameni. Tipuri de date statice versus dinamice - asta e unul din razboaiele clasice in programare. Daca vii dinspre C++ si Java (sau dinspre limbaje functionale cu tipuri statice ca Haskel si ML) si refuzi sa lucrezi fara verificari de tipuri statice, ai putea la fel de bine sa pui cartea jos. Dar, inainte chiar sa faci asta, s-ar putea sa te intereseze ceea ce Robert Martin (autor al Proiectarii Aplicatiilor Obiect Orientate in C++ folosind metoda Booch [Prentice Hall, 1995]), auto-proclamat "bigot in tipuri statice" si Bruce Eckel (autor al Gandind in C++ [Prentice Hall, 1995] si Gandind in Java [Prentice Hall, 1998]) au avut de spus despre tipuri dinamice pe blog-urile lor (
5AspectL este un proiect interesant in masura in care AspectJ, predecesorul lui bazat pe Java, a fost scris de Gregor Kiczales, unul din proiectantii sistemelor de obiecte si metaobiecte din Common Lisp. Pentru multi Lisp-eri, AspectJ pare a fi incercarea lui Kiczales de a aduce ideile lui din Common Lisp in Java. Totusi, Pascal Constanza, autorul AspectL, crede ca exista idei interesante in AOP care pot fi folositoare in Common Lisp. Desigur, el poate sa implementeze AspectL ca biblioteca datorita incredibilei flexibilitati ale Protocolului de Meta Obiecte (Meta Object Protocol) din Common Lisp proiectat de Kiczales. Pentru a implementa AspectJ, Kiczales a trebuit sa scrie in esenta un compilator separat care complieaza un linbaj nou in cod sursa Java. Pagina proiectului AspectL este la adresa
6Sau, privind dintr-un unghi mai corect dpdv tehnic, Common Lisp include facilitati pentru integrarea compilatoarelor pentru limbaje incapsulate.
7Manualul Programatorului in Lisp 1.5(M.I.T. Press, 1962)
8Printre ideile aparute prima data in Lisp sunt constructia if/then/else, apelurile de functii recursive, alocarea dinamica a memoriei, colectarea gunoiului (garbage collection), functii de prima mana, inchideri lexicale, programare interactiva, compilare incrementala si tipuri dinamice.
9Unul din cele mai repetate mituri despre Lisp este ca e "mort." Desi este adevarat ca nu este la fel de folosit ca si Visual Basic sau Java, pare ciudat sa descrii un limbaj care continua sa fie folosit pentru dezvoltare si care continua sa atraga noi utilizatori ca fiind"mort." Printre povestile de succes recente se afla site-ul Viaweb al lui Paul Graham, care a devenit Yahoo! Store cand Yahoo! a cumparat compania; QPX, sistemul de cumparare de bilete pentru linii aeriene a ITA Software, folosit de Orbitz si altii; Jak and Daxter, jocul facut de Naughty Dog pentru PlayStation 2, scris in mare parte intr-un dialect de Lisp inventat de Naughty Dog, GOAL, al carui compilator este scris in Common Lisp; si Roomba, aspiratorul robotic autonom, al carui software este scris in L, un subset de Common Lisp. Poate si mai graitoare sunt cresterea site-ului Common-Lisp.net, care gazduieste proiecte Common Lisp open-source, si numarul de grupuri locale de utilizatori Lisp care au aparut in ultimii ani.
2Din pacate, sunt putine date concrete despre productivitatea diferitelor limbaje de programare. Un raport in care Lisp este comparat favorabil cu C++ si Java in combinatia programator - eficienta programului este discutat la adresa
http://www.norvig.com/java-lisp.html
.3Psihologistii au identificat o stare a mintii numita "fluidizare" (flow) in care suntem capabil de concentrare si productivitate incredibile. Importanta fluidizarii in programare este recunoscuta de aproape doua decenii de cand a fost discutata in cartea clasica despre factorul uman in programare Peopleware: Productive Projects and Teams de Tom DeMarco si Timothy Lister (Dorset House, 1987). Cele doua mari caracteristici ale fluidizarii sunt ca dureaza cam 15 minnut sa intri in starea respectiva si apoi orice intrerupere, oricat de scurta, te poate scoate din stare, fiind nevoie de inca alte 15 minute pentru a reintra in stare. DeMarco si Lister, ca majoritatea autorilor ulteriori, erau ingrijorati mai ales in privinta factorilor perturbatori gen apeluri telefonice si vizite inoportune ale sefului. Mai putin bagate in seama dar probabil la fel de importante pentru programatori sunt intreruperile provocate de uneltele folosite. Limbajele care necesita, de exemplu, o compilare lunga inainte sa poti sa incerci ultimele linii de cod scrise pot fi la fel de daunatoare fluidizarii ca si un telefon zgomotos sau un sef bagacios. Deci, un alt mod de a privi Lisp este ca un limbaj proiectat pentru a te tine intr-o stare de fluidizare.
4Acest punct de vedere e destinat sa fie controversat, cel putin pentru unii oameni. Tipuri de date statice versus dinamice - asta e unul din razboaiele clasice in programare. Daca vii dinspre C++ si Java (sau dinspre limbaje functionale cu tipuri statice ca Haskel si ML) si refuzi sa lucrezi fara verificari de tipuri statice, ai putea la fel de bine sa pui cartea jos. Dar, inainte chiar sa faci asta, s-ar putea sa te intereseze ceea ce Robert Martin (autor al Proiectarii Aplicatiilor Obiect Orientate in C++ folosind metoda Booch [Prentice Hall, 1995]), auto-proclamat "bigot in tipuri statice" si Bruce Eckel (autor al Gandind in C++ [Prentice Hall, 1995] si Gandind in Java [Prentice Hall, 1998]) au avut de spus despre tipuri dinamice pe blog-urile lor (
http://www.artima.com/weblogs/viewpost.jsp?thread=4639
si http://www.mindview.net/WebLog/log-0025
). Pe de alta parte, cei care vin dinspre Smalltalk, Python, Perl, sau Ruby ar trebui sa se simta acasa in privinta acestui aspect al Common Lisp.5AspectL este un proiect interesant in masura in care AspectJ, predecesorul lui bazat pe Java, a fost scris de Gregor Kiczales, unul din proiectantii sistemelor de obiecte si metaobiecte din Common Lisp. Pentru multi Lisp-eri, AspectJ pare a fi incercarea lui Kiczales de a aduce ideile lui din Common Lisp in Java. Totusi, Pascal Constanza, autorul AspectL, crede ca exista idei interesante in AOP care pot fi folositoare in Common Lisp. Desigur, el poate sa implementeze AspectL ca biblioteca datorita incredibilei flexibilitati ale Protocolului de Meta Obiecte (Meta Object Protocol) din Common Lisp proiectat de Kiczales. Pentru a implementa AspectJ, Kiczales a trebuit sa scrie in esenta un compilator separat care complieaza un linbaj nou in cod sursa Java. Pagina proiectului AspectL este la adresa
http://common-lisp.net/ project/aspectl/
.6Sau, privind dintr-un unghi mai corect dpdv tehnic, Common Lisp include facilitati pentru integrarea compilatoarelor pentru limbaje incapsulate.
7Manualul Programatorului in Lisp 1.5(M.I.T. Press, 1962)
8Printre ideile aparute prima data in Lisp sunt constructia if/then/else, apelurile de functii recursive, alocarea dinamica a memoriei, colectarea gunoiului (garbage collection), functii de prima mana, inchideri lexicale, programare interactiva, compilare incrementala si tipuri dinamice.
9Unul din cele mai repetate mituri despre Lisp este ca e "mort." Desi este adevarat ca nu este la fel de folosit ca si Visual Basic sau Java, pare ciudat sa descrii un limbaj care continua sa fie folosit pentru dezvoltare si care continua sa atraga noi utilizatori ca fiind"mort." Printre povestile de succes recente se afla site-ul Viaweb al lui Paul Graham, care a devenit Yahoo! Store cand Yahoo! a cumparat compania; QPX, sistemul de cumparare de bilete pentru linii aeriene a ITA Software, folosit de Orbitz si altii; Jak and Daxter, jocul facut de Naughty Dog pentru PlayStation 2, scris in mare parte intr-un dialect de Lisp inventat de Naughty Dog, GOAL, al carui compilator este scris in Common Lisp; si Roomba, aspiratorul robotic autonom, al carui software este scris in L, un subset de Common Lisp. Poate si mai graitoare sunt cresterea site-ului Common-Lisp.net, care gazduieste proiecte Common Lisp open-source, si numarul de grupuri locale de utilizatori Lisp care au aparut in ultimii ani.
Sus
Pentru o experienta de programare mai neobisnuita, pentru gimnastica mentala.
Poti sa scapi de necesitatea de a scrie niste cod repetitiv (boilerplate code).
Tipuri dinamice, o variabila poate sa contina un tip de date apoi alt tip de date; de ex: numar intreg apoi sir de caractere.
Sistemul de conditii, folosit pentru tratarea exceptiilor, este mai puternic decat corespondentii sai din alte limbaje - vezi Capitolul 19.
Independenta utilizatorului unei implementari fata de standard, acesta putand sa extinda limbajul fara a fi nevoit sa astepte interventie de la un tert, cum ar fi furnizorul implementarii sale. Sistemul de obiecte (CLOS) a putut fi scris in original ca o biblioteca in Common Lisp portabil.
Niciun comentariu:
Trimiteți un comentariu
S-ar putea sa nu vedeti comentariul aparand imediat, asta inseamna ca el asteapta aprobarea mea. Aceasta e o masura anti-SPAM.