Lisp (programski jezik) — разлика између измена

Садржај обрисан Садржај додат
Нема описа измене
latinica-ćirilica
Ред 14:
}}
 
'''Lisp''' (istorijski, '''LISP''') je familija [[programski jezici|programskih jezika]] sa dugom istorijom. Lisp je drugi najstariji viši programski jezik koji se i danas veoma koristi. Jedino je [[Fortran]] stariji (godinu dana).<ref>{{cite web|url=http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-5.html|quote=Lisp is a survivor, having been in use for about a quarter of a century. Among the active programming languages only Fortran has had a longer life.|title=SICP: Foreword}}</ref><ref>{{cite web|url=http://www-formal.stanford.edu/jmc/history/lisp/node6.html#SECTION00060000000000000000|title=Conclusions}}</ref> Danas postoji veliki broj dijalekata Lisp-a, a najpoznatiji među njima su [[-{Common Lisp}-]] i [[Scheme (programski jezik)|-{Scheme}-]].
 
Ime LISP je nastalo od "-{LISt Processor}-". Povezane liste su jedan od glavnih tipova podataka.
 
== Istorijat ==
Ред 25:
Prvi kompletan Lisp kompajler, napisan u Lisp-u, implementirali su Tim Hart i Majk Levin 1962. godine.
 
Tokom 1980-ih i 1990-ih radilo se na ujedinjavanju novih dijalekata Lisp-a. Tako je nastao programski jezik [[-{Common Lisp}-]]. Prvi standard za -{Common Lisp}-, "-{ANSI X3.226-1994 Information Technology Programming Language Common Lisp}-.", objavio je [[Амерички национални завод за стандардизацију|-{ANSI}-]] 1994. godine.
 
[[Edsger Dajkstra]] je na dodeli [[Tjuringova nagrada|Tjuringove nagrade]] 1972. godine rekao:
Ред 66:
(+ 1 2 3 4)
</syntaxhighlight>
Ovaj izraz ima vrednost 10. Ekvivalentan izraz u [[Infiksna notacija|infiksnuinfiksnoj notacijunotaciji]] jeste "1 + 2 + 3 + 4". Aritmetički operatori u Lisp-u su n-arne funkcije, tako da mogu imati bilo koliko argumenata. Operator inkrementiranja u C-u "++" ovde je implementiran kao:
 
<syntaxhighlight lang=Lisp>
Ред 118:
Zbog toga što su <code>cons</code> i liste univerzalne u Lisp sistemima, česta je zabluda da su oni jedine strukture podataka u Lisp-u. U stvari, postoje i druge strukture podataka, poput vektora (nizova), heš tabeli...
 
<code>Cons</code> može da se napiše u ''-{dotted-pair}-'' notaciji kao <code>(a . b)</code>, gde <code>a</code> predstavlja <code>car</code>, a <code>b</code> predstavlja <code>cdr</code>.
 
==== Funkcije za rad sa listama ====
Ред 155:
 
==== Deljene strukture ====
Lisp liste, koje su jednostruko povezane, mogu da podele strukturu međusobno. To jest, dve liste mogu da imaju isti rep ili krajnji niz <code>cons</code> ćelija. Na primer, nakon izvršenja sledećeg -{Common Lisp}- koda
 
Lisp liste, koje su jednostruko povezane, mogu da podele strukturu međusobno. To jest, dve liste mogu da imaju isti rep ili krajnji niz <code>cons</code> ćelija. Na primer, nakon izvršenja sledećeg Common Lisp koda
 
<syntaxhighlight lang=Lisp>
Линија 185 ⟶ 184:
 
=== Prostor imena ===
Lisp je podeljen oko upotrebe dinamičke i statičke (odnosno leksičke) upotrebe prostora imena. -{Clojure}-, -{Common Lisp}- i -{Scheme}- podrazumevano koriste statičko definisanje polja promenljive, dok -{Newlisp}-, -{Picolisp}- i ugrađeni jezici u -{Emacs}--u i -{AutoCAD}--u koriste dinamičko.
 
=== Spisak struktura programskog koda; makroi i kompajleri ===
Osnovna razlika između Lisp-a i ostalih jezika je u tome što je tekstualna reprezentacija programa prilično čitljiv opis same unutrašnje strukture podataka (povezanih listi, simbola, brojeva, karaktera, itd.) kao što je u osnovi Lisp sistema.
 
Zahvaljujući tome, Lisp implementira veoma jak sistem makroa. Kao i u ostalim makro jezicima kao što je [[C (програмски језик)|-{C}-]], makro vraća kod koji može biti kompajliran. Za razliku od -{C}--ovih makroa, u Lisp-u su makroi funkcije i u njima je moć Lisp-a.
 
Pošto kod u Lisp-u ima istu strukturu kao liste, makroi mogu biti izraženi pomoću bilo koje funkcije za rad sa listama. Ukratko, sve što može Lisp sa strukturom podataka, Lisp makroi mogu sa kodom.
 
U jednostavnoj implementaciji Lisp-a, ova struktura u vidu liste je direktno [[Интерпретатор (рачунарство)|interpretirana]] da pokrene program; funkcija je doslovno deo strukture liste koja prevedena od strane interpretatora pri izvršavanju. Većina Lisp sistema sadrži i kompajler. On prevodi strukturu liste na mašinski jezik ili [[Бајткод|bajtkod]] za izvršavanje. Ovaj kod može biti pokrenut jednako brzo kao i u -{C}--u, na primer.
 
Makroi nude interesantne opcije.
Neke implementacije Lisp-a imaju mehanizam <code>eval-when</code> koji omogućava kodu da bude prisutan za vreme kompilacije (kad zatreba makrou) ali nije prisutan u emitujućem modulu.<ref>[https://www.gnu.org/software/emacs/manual/html_node/cl/Time-of-Evaluation.html Time of Evaluation - Common Lisp Extensions]. Gnu.org. Retrieved on 2013-07-17.</ref>
 
=== Evaluacija i -{read–eval–print}- petlja ===
Lisp jezici su najčešće korišćeni sa interaktivnom [[Интерфејс командне линије|komandnom linijom]], koja se može kombinovati sa [[Интегрисано развојно окружење|-{IDE}--om]]. Lisp ''čita'' unete izraze, ''evaluira'' ih i ''štampa'' rezultat. Zbog ovoga, Lisp komandna linija se naziva "-{read–eval–print}- petlja", odnosno ''-{REPL}-''.
 
<code>read</code> funkcija prihvata tekstualni S-izraz kao ulaz i parsira ga u unutrašnju strukturu podataka.
Линија 209 ⟶ 208:
<code>123</code> će se pročitati kao broj sto dvadeset tri, a <code>"123"</code> će se pročitati kao string "123".
 
<code>eval</code> funkcija evaluira podatke, vraća nula ili više Lisp podataka kao rezultat. Evaluacija ne mora značiti isto što i interpretacija; pojedini Lisp sistemi kompajliraju svaki izraz u mašinski kod koji se može izvršiti direktno od strane -{CPU}-. Svakako je jednostavno objasniti evaluaciju kao interpretiranje: Da bi se evaluirala lista čiji <code>car</code> imenuje funkciju,
<code>eval</code> prvo evaluira svaki od argumenata koji je prosleđen njenom -{cdr}--u, potom primenjuje funkciju na argumente. U ovom slučaju, funkcija je sabiranje i primenjujući je na argumente liste <code>(1 2)</code> daje rezultat <code>3</code>. To je, zapravo, rezultat evaluacije.
 
Simbol <code>foo</code> evaluira vrednost simbola foo. Podatak kao što je string "123" evaluira isti string. Lista <code>(quote(1 2 3))</code> evaluira (1 2 3).
Линија 216 ⟶ 215:
Posao funkcije <code>print</code> je da prikaže izlaz korisniku. Za jednostavan rezultat kao što je <code>3</code> to je trivijalno. Izraz koji evaluira deo strukture liste bi zahtevao da <code>print</code> prođe kroz listu i štampa je kao S-izraz.
 
Za implementaciju -{Lisp REPL}--a, neophodno je implementirati navedene tri funkcije i funkciju "beskonačna petlja". Naravno da implementacija funkcije <code>eval</code> nije jednostavna, posebno jer je potrebno implementirali sve specijalne operatore kao što su <code>if</code> ili <code>lambda</code>.
 
Kada je ovo završeno, -{REPL}- nije ništa drugo do jedna linija koda: -{(loop (print (eval (read))))}-.
 
-{Lisp REPL}- omogućava redigovanje ulaza, istoriju ulaza, upravljanje greškama kao i interfejs dibagera.
 
Lisp se uglavnom evaluira [[Похлепни алгоритам|pohlepno]].
 
=== Kontrolne strukture ===
Lisp je prvobitno imao samo nekoliko struktura, ali veliki broj je dodavan tokom evolucije jezika. (Lisp-ov prvobitni uslovni operator, ''-{cond}-'', je prethodnik kasnije -{if-then-else}- strukture.
 
Lisp je prvobitno imao samo nekoliko struktura, ali veliki broj je dodavan tokom evolucije jezika. (Lisp-ov prvobitni uslovni operator, ''cond'', je prethodnik kasnije if-then-else strukture.
 
Pojedine Lisp-ove kontrolne strukture su specijalni operatori, ekvivalenti sintaksnim ključnim rečima drugih jezika. Izrazi koji koriste ove operatore imaju isti izgled kao pozivi funkcija, razlika je jedino u tome što argumenti ne moraju biti evaluirani ili u iterativnom slučaju mogu biti evaluirani više od jedanput.
Линија 232 ⟶ 230:
Za razliku od ostalih viših programskih jezika, Lisp dopušta programeru da implementira kontrolne strukture koristeći jezik. Nekoliko kontrolnih strukutura je implementirano kao Lisp makroi, a nekoliko njih mogu biti makro razvijeni od strane programera koji znaju kako to radi.
 
I -{Common Lisp}- i -{Scheme}- imaju operatore za nelokalnu kontrolu toka. Razlike u ovim operatorima ujedno čine i razlike između ova dva dijalekta.
 
Neretko, isti algoritam u Lisp-u može biti iskaan i imperativnim i funkcionalnim stilom. -{Scheme}- preferira funkcionalni stil koristeći repnu rekurziju. Kako god, imperativni stil je još uvek moguć. Stil koji preferiraju -{Common Lisp}- programeri bliži je programerima koji koriste struktuirane jezike kao što je -{C}-, dok je onaj koji preferiraju -{Scheme}- programeri bliži čisto funkcionalnim jezicima kao što je -{Haskell}-.
 
Lisp ima široki spektar funkcija višeg reda koje su u relaciji sa itaracijom u naredbama. U mnogim slučajevima gde bi u drugom jeziku bila neophodna petlja (kao -{for}- u -{C}--u) u Lisp-u stvar rešava funkcija višeg reda.
 
== Primeri ==
Evo primera -{Common Lisp}- koda.
 
Osnovni "[[-{Hello World}-]]" program:
<syntaxhighlight lang=Lisp>
(print "Hello world")
Линија 260 ⟶ 258:
(factorial (- n 1) (* acc n))))
</syntaxhighlight>
Iterativna verzija u -{Common Lisp}--u:
<syntaxhighlight lang=Lisp>
(defun factorial (n)
Линија 268 ⟶ 266:
</syntaxhighlight>
 
Naredna funkcija obrće listu. (Ugrađena funkcija ''-{reverse}-'' radi istu stvar.)
<syntaxhighlight lang=Lisp>
(defun -reverse (list)
Линија 277 ⟶ 275:
 
== Objektni sistemi ==
* -{The [[Common Lisp Object System]], CLOS}-
* -{ObjectLisp{{sfn|Bobrow|1986|p=17}}}- ili [[-{Object Lisp}-]], korišćen od strane [[-{Lisp Machines Incorporated}-]] i ranije verzije -{Macintosh Common Lisp}--a
* -{LOOPS (Lisp Object-Oriented Programming System)}- i kasniji [[-{CommonLOOPS}-]]
* [[-{Flavors (computer science)|Flavors}-]], nastao na [[Масачусетски технолошки институт|MIT]], i njegov nasldniknaslednik -{New Flavors }-(-{developed by [[Symbolics]]}-).
* [[-{Knowledge Engineering Environment|KEE}-]] korišćen kao objektni sistem nazvan -{UNITS}- i ugrađen u [[-{inference engine}-]]{{ -{sfn|Veitch|1988|p=108}-}} and ai [[-{Truth maintenance systems|truth maintenance system}-]] (ATMS).
 
== Spoljašnje veze ==