Lisp: Różnice pomiędzy wersjami

[wersja przejrzana][wersja przejrzana]
Usunięta treść Dodana treść
m błędny link
m błędny link, WP:SK
Linia 1:
{{Język programowania infobox
|nazwa = Lisp
|logo =
|wielkość_loga =
|data = [[1958]]
|paradygmat = [[Programowanie wieloparadygmatowe|wieloparadygmatowy]] ([[programowanie funkcyjne|funkcyjny]], [[programowanie obiektowe|obiektowy]], [[programowanie symboliczne|symboliczny]])
|typowanie = [[dynamiczne typowanie|dynamiczne]]
|implementacje =
|pochodne = [[Common Lisp]], [[Scheme]], [[Emacs Lisp]], [[AutoLISP]], [[Clojure]] i inne
|wersja =
|wersja testowa =
|twórca = [[John McCarthy]]
|licencja =
|platforma =
|system =
|www =
|grafika =
}}
'''Lisp'''<ref>[http://so.pwn.pl/lista.php?co=lisp Odmiana:] [[Mianownik (przypadek)|M]]. ''Lisp'', [[dopełniacz (przypadek)|D]]. ''Lispu'', [[celownik (przypadek)|C]]. ''Lispowi'', [[Biernik|B]]. ''Lisp'', [[Narzędnik|N]]. ''Lispem'', [[Miejscownik|M]]. ''Lispie''</ref> – rodzina [[język programowania|języków programowania]] z długą historią i charakterystyczną składnią. Zaprojektowany przez [[John McCarthy|Johna McCarthiego]] na [[MIT]] w 1958 roku. Pierwszym interpreterem języka Lisp była implementacja funkcji ''eval'' wykonana przez studenta McCarthiego - Stevea Russella. Lisp jest drugim z kolei pod względem wieku językiem programowania wysokiego poziomu pozostającym w użyciu (starszy jest tylko [[Fortran]]). Podobnie jak Fortran, Lisp wiele się zmienił w porównaniu ze swoimi początkami. W historii istniało wiele dialektów Lispu; dziś do najpopularniejszych należą trzy - [[Common Lisp]] , [[Scheme]] i [[Clojure]].
Linia 60:
* [[Common Lisp|Common Lisp (1984)]], opisany w ''Common Lisp: The Language'' – połączenie kilku różnych podejść (ZetaLisp, [[Spice Lisp]], [[NUL (LISP)|NIL]] i [[S-1 Lisp]]) do stworzenia następcy Maclispu z pewnymi wpływami ze Scheme. Ta wersja Common Lispu była dostępna na wiele platform i uznawana za standard do czasu pojawienia się specyfikacji ANSI Common Lisp (ANSI X3.226-1994).
* [[EuLisp]] – próba stworzenia nowego, wydajnego i oczyszczonego z historycznego bagażu dialektu Lispu.
* [[ISLisp]] – jw. Ustandaryzowany <ref>[http://islisp.info/specification.html Standardy ISLispu ]</ref> jako [http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=22987 ISO/IEC 13816:1997] i później skorygowany w [http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=44338 ISO/IEC 13816:2007] – ''Information technology – Programming languages, their environments and system software interfaces – Programming language ISLISP''.
* [[Scheme|IEEE Scheme]] – standard IEEE, 1178-1990 (R1995).
* [[ANSI Common Lisp]] – specyfikacja [[American National Standards Institute]] (ANSI) Common Lispu, stworzona przez podkomisję [[X3J13]], która rozpoczęła pracę[http://www.nhplace.com/kent/CL/x3j13-86-020.html] wychodząc od ''Common Lisp: The Language'' jako dokumentu bazowego i działała na zasadzie publicznego [[konsensus]]u co do zagadnień przenośności i kompatybilności implementacji Common Lispu. Pomimo iż formalnie jest to standard ANSI, implementacje, sprzedaż, wykorzystanie i wpływ ANSI Common Lispu było i jest widoczne na całym świecie.
Linia 102:
Lisp wpłynął na [[Alan Kay|Alana Kaya]], który prowadził badania nad [[Smalltalk]]iem, by następnie ulec wpływowi Smalltalka przez wprowadzenie cech [[programowanie obiektowe|programowania obiektowego]] (klasy, metody itd.) pod koniec lat 70.
 
Głównie ze względu na wymagania systemowe Lisp nie zyskał takiej popularności poza społecznością badającą [[sztuczna inteligencja|SI]] jak na przykład [[Fortran]] czy [[C (język programowania)|C]]. Nowsze języki, takie jak [[Java]] czy [[Ruby (język programowania)|Ruby]] oferują część jego cech, mimo tego nie jest możliwe spójne zaimplementowanie dla nich wszystkich cech Lispu. W ostatnich latach wiodące implementacje Lispu zaczęły dorównywać wydajnością kompilatorom popularnych języków <ref>[http://www.lispworks.com/products/myths_and_legends.html Common Lisp - Myths and Legends]</ref><ref>[http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&lang=all Computer Language Benchmarks Game]</ref>, w tym przewyższając o rzędy wielkości wydajność popularnych języków skryptowych [http://shootout.alioth.debian.org/u32q/benchmark.php?test=all&lang=sbcl&lang2=perl], głównie ze względu na przejmowanie cech Lispu (GC, dynamiczne typowanie, refleksja) przez względnie "popularne" języki.
 
Zobacz też "The evolution of Lisp"<ref name="STEELE">{{cytuj stronę
Linia 169:
 
=== Komórki cons i listy ===
[[Plik:Cons-cells.svg|thumb|right|300px|Diagram dla listy (42 69 613)]]
[[Lista]] w Lispie jest jednokierunkowa. Każda komórka nazywa się ''cons'' (w Scheme ''para'', [[język angielski|ang.]] ''pair'') i składa się z dwóch [[zmienna wskaźnikowa|wskaźników]], zwanych ''car'' i ''cdr''.
 
Linia 280:
 
W przypadku funkcji która została utworzona z zasięgiem dynamicznym, jeśli dana zmienna nie znajduje się wewnątrz funkcji to jest ona poszukiwana od miejsca w którym została wywołana w górę aż do zasięgu globalnego. W przypadku zasięgu leksykalnego zmienne są poszukiwane od miejsca w którym ta funkcja została zdefiniowana. Drugi przypadek jest najczęściej stosowany w innych językach programowania.
 
 
'''Przykład domknięcia leksykalnego w dialekcie [[Scheme]]'''
Linia 299 ⟶ 298:
;Powyższy kod wyświetli 11 i 12.
</source>
 
 
Funkcja '''make-counter''' tworzy nową funkcję '''counter'''. Chociaż zakres zmiennej '''count''' po zakończeniu wywołania funkcji '''make-counter''' powinien się zakończyć, to funkcja '''counter''' zwrócona przez funkcję '''make-counter''' ma nadal do niej dostęp, tzn. zmienna '''counter''' jest domknięta wewnątrz funkcji '''count'''.
Linia 315 ⟶ 313:
Oto podstawowy opis działania REPL. Jest on uproszczony, nie bierze pod uwagę wielu elementów prawdziwego Lispu, jak na przykład cytowanie czy makra.
 
Funkcja ''read'' akceptuje [[ciąg znaków]] zawierający S-wyrażenie jako argument i zwraca odpowiadającą mu listę. Na przykład jeżeli wprowadzisz ciąg znaków "<code>(+ 1 2)</code>", <code>read</code> przetłumaczy go na listę z trzema elementami: symbolem <code>+</code>, liczbą 1 i liczbą 2. Tak się składa, że ta lista jest również prawidłowym kawałkiem kodu w Lispie, to znaczy może być ewaluowana. Jest to możliwe ze względu na fakt, iż car listy wskazuje na funkcję <code>+</code> – operator dodawania.
 
Funkcja <code>eval</code> ewaluuje listę, zwracając inną listę jako wynik. Ewaluacja nie jest konieczne interpretacją – część systemów Lispu kompiluje w locie każde wyrażenie do kodu maszynowego. Opisywanie ewaluacji jako interpretacji jednak jest dużo prostsze: by zewaluować listę, w której car wskazuje na funkcję, <code>eval</code> najpierw [[rekurencja|rekurencyjnie]] ewaluuje każdy argument w cdr, by następnie z wynikami tych ewaluacji wywołać daną funkcję. W naszym przykładzie funkcją jest dodawanie, wywoływane z listą argumentów <code>(1 2)</code> zwraca wynik <code>3</code>. Jest to wynik ewaluacji.
Linia 386 ⟶ 384:
 
== Funkcje wyższego rzędu ==
Funkcję wyższego rzędu jest to jeden z elementów [[Programowanie_funkcyjneProgramowanie funkcyjne|programowania funkcyjnego]]. W Lispie funkcje można przypisywać do zmiennych przekazywać jako parametry do innych funkcji, mogą być także zwracane jako wartości przez funkcję. Funkcja która operuje na innych funkcjach jest nazywana funkcją wyższego rzędu (and Higher Order Procedure).
 
'''Przykład funkcji w Common Lispie'''
Linia 437 ⟶ 435:
(reduce + list))
</source>
 
 
Inne powszechnie stosowane funkcje wyższego rzędu to funkcja mapująca (wywołująca funkcję dla każdego elementu listy i zwracająca nową listę) i funkcja filtrująca (która zwraca listę pomniejszoną o te elementy dla których funkcja przekazana jako parametr zwraca wartość fałszu).
 
== Makra ==
Makra są to najpotężniejszym elementem języka Lisp, które są dla niego unikalne. Dzięki makrom można dodawać nowe elementy do języka. Makro Lispowe, w odróżnieniu np. od makr występujący w pre procesorze [[Język_CJęzyk C|języka C]] operuje na kodzie języka lisp tak jak na danych. W przypadku funkcji wyrażenia które są przekazywane jako parametry są obliczane przed wywołaniem samej funkcji a wynik tego wyrażenia jest przekazywany jako parametr, w przypadku makra wyrażenia nie są obliczane, ale przekazane w całości jako dane w parametrze, które są przez makro przetwarzane, następnie makro powinno zwrócić kod lispowy także w postaci listy który zostanie obliczony.
 
<source lang="lisp">