Lisp: Różnice pomiędzy wersjami

[wersja przejrzana][wersja przejrzana]
Usunięta treść Dodana treść
WikitanvirBot (dyskusja | edycje)
m r2.7.1) (Robot poprawił hu:Lisp (programozási nyelv)
Linia 5:
|data = [[1958]]
|paradygmat = [[Programowanie wieloparadygmatowe|wieloparadygmatowy]] ([[programowanie funkcyjne|funkcyjny]], [[programowanie obiektowe|obiektowy]], [[programowanie symboliczne|symboliczny]])
|typowanie = [[dynamiczneTypowanie typowaniedynamiczne|dynamiczne]]
|implementacje =
|pochodne = [[Common Lisp]], [[Scheme]], [[Emacs Lisp]], [[AutoLISP]], [[Clojure]] i inne
Linia 17:
|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 [[Massachusetts Institute of Technology|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]].
 
Lisp powstał jako wygodna [[matematyka|matematyczna]] notacja dla [[program komputerowy|programów komputerowych]], oparta na [[rachunek lambda|rachunku lambda]] stworzonym przez [[Alonzo Church]]a. Szybko został najchętniej wybieranym językiem do badania i rozwoju [[sztuczna inteligencja|sztucznej inteligencji]]. Ponieważ należy do najstarszych języków programowania wysokiego poziomu, wywodzi się z niego wiele technik programistycznych, takich jak [[struktura drzewiasta|struktury drzewiaste]], [[garbage collection|odśmiecanie pamięci]], [[Typowanie dynamiczne|dynamiczne typowanie]] czy nowe koncepcje w [[programowanie obiektowe|programowaniu obiektowym]].
 
Nazwa ''Lisp'' pochodzi od ''LISt Processing''. Podstawową strukturą danych w Lispie jest [[lista]]; [[kod źródłowy]] programów w Lispie składa się z list. W wyniku tego programy w Lispie mogą manipulować kodem źródłowym jak zwykłą strukturą danych. Umożliwia to pisanie [[makro|makr]], pozwalających programiście tworzyć nową składnię lub nawet małe zagnieżdżone w Lispie języki.
Linia 53:
* LISP 1.5 [http://community.computerhistory.org/scc/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf] – Pierwsza szeroko rozprzestrzeniona wersja, stworzona przez McCarthy'ego i innych pracowników MIT. Zawierała trochę ulepszeń w stosunku do oryginalnego interpretera "LISP 1", nie była jednak całkowicie nowa, jaka miała być wersja "LISP 2", zatem zdecydowano się na taki właśnie numer wersji.
* [[Stanford LISP 1.6]] [http://community.computerhistory.org/scc/projects/LISP/stanford/SAILON-28.6.pdf] – Wersja następna po LISP 1.5 stworzona w [[Stanford AI Lab]] i szeroko rozprzestrzeniona pod systemem [[TOPS-10]] na maszynach [[PDP-10]]. Została zastąpiona przez Maclisp i InterLisp.
* [[Maclisp|MACLISP]] [http://web.archive.org/web/20080420150707/http://zane.brouhaha.com/~healyzh/doc/lisp.doc.txt] – stworzony dla "Projektu MAC" w MIT (bez związku z [[Macintosh|Apple Macintosh]] ani z McCarthym), bezpośredni spadkobierca LISP 1.5. Działał na PDP-10 pod [[MulticsMULTICS|Multicsem]]em. (MACLISP później został przemianowany na Maclisp, często bywa również nazywany MacLispem).
* [[InterLisp]] [http://www.bitsavers.org/pdf/xerox/interlisp/1974_InterlispRefMan.pdf] – stworzony w [[BBN Technologies]] na komputery PDP-10 działające z systemem [[TOPS-20|Tenex]], później zaadoptowany dla maszyn Lispu [[Xerox]]a. Mała wersja zwana "InterLISP 65" została wydana dla komputerów marki [[Atari (amerykańskie przedsiębiorstwo)|Atari]] bazujących na procesorze [[MOS Technology 6502|MOS 6502]]. Przez pewien czas Maclisp i InterLisp były w równie szerokim użyciu.
* [[Franz Lisp]] – początkowo projekt [[University of California, Berkeley|Berkeley]], później zaimplementowany przez [[Franz Inc]]. Nazwa jest żartobliwą deformacją imienia "[[Ferenc Liszt|Franz Liszt]]". Nazwa "Franz Lisp" nie odnosi się do [[Allegro Common Lisp]], odmiany Common Lispu sprzedawanej przez Franz Inc. w ostatnim czasie.
* [[ZetaLisp]] – używany na [[maszyna Lispowa|maszynach Lispowych]], bezpośredni następca Maclispu.
* [[Emacs Lisp]] - używany jako język rozszerzeń edytora [[Emacs]].
Linia 62:
* [[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).
* [[Common Lisp|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 [[konsensuskonsens]]uusu 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.
 
=== Powiązania ze sztuczną inteligencją ===
Od swoich początków Lisp był blisko powiązany ze społecznością badającą i rozwijającą [[sztuczna inteligencja|sztuczną inteligencję]], szczególnie na [[PDP-10]]<ref>36-[[bit]]owy rozmiar słowa na [[PDP-6]]/[[PDP-10]] został wprowadzony ze względu na użyteczność trzymania dwóch 18-bitowych Lispowych wskaźników w jednym słowie. "The PDP-6 project started in early 1963, as a 24-bit machine. It grew to 36 bits for LISP, a design goal." ("Projekt PDP-6 został rozpoczęty w 1963 jako maszyna 24-bitowa. Urosła do 36 bitów dla LISPu, celu projektowego.") [http://groups.google.com/group/alt.folklore.computers/browse_thread/thread/6e5602ce733d0ec/17597705ae289112]</ref>. Lisp został użyty w implementacji języka programowania [[Micro Planner]], który był podstawą znanego systemu SI [[SHRDLU]]. W [[Lata 70. XX wieku|latach 70.]], gdy badania nad AI rozwinęły się również po stronie komercyjnej, wydajność istniejących systemów Lispu stawała się coraz ważniejszym problemem.
 
Lisp był trudny do implementacji na zwykłych kompilatorach i sprzęcie dostępnym w 1970. [[Odśmiecanie pamięci|Garbage collection]], stworzone przez [[Daniel Edwards|Daniela Edwardsa]], wpłynęło na użyteczność Lispu na sprzęcie obliczeniowym ogólnego przeznaczenia, ale wydajność wciąż była problemem. Doprowadziło to do stworzenia [[maszyna lispowa|maszyn lispowych]]: dedykowanego sprzętu do uruchamiania środowisk i programów w Lispie. Postęp w dziedzinie sprzętu komputerowego, jak również w kompilatorach wkrótce sprawił, że maszyny lispowe stały się przestarzałe, co zaszkodziło rynkowi Lispu.
 
W latach [[lata 80. XX wieku|80.]] i [[lata 90. XX wieku|90.]] włożono duży wysiłek w zunifikowanie wielu dialektów Lispu (szczególnie dialektów [[InterLisp]], [[Maclisp]], [[ZetaLisp]], i [[Franz Lisp]]) w pojedynczy język. Nowy język, [[Common Lisp]] był istotnie kompatybilnym podzbiorem dialektów, które zastępował. W [[1994]], [[American National Standards Institute|ANSI]] opublikowało specyfikację Common Lispu, "ANSI X3.226-1994 Information Technology Programming Language Common Lisp". W tamtym czasie światowy rynek Lispu był dużo mniejszy niż obecnie.
 
=== Od 2000 ===
Po spadku popularności w latach 90. wywołanym m.in. upowszechnieniem się C++ i silnym marketingiem Javy, jak również brakiem dobrych i [[wolneWolne oprogramowanieOprogramowanie|wolnych]] implementacji Lispu, Lisp doświadcza wzrostu zainteresowania od roku [[2000]]. Większość aktywności skupia się wokół stworzenia [[Otwarte oprogramowanie|open source]]'owych implementacji Common Lispu i zawiera rozwój nowych przenośnych bibliotek i aplikacji. Zainteresowanie to można częściowo zmierzyć przez sprzedaż papierowej wersji książki ''[[Practical Common Lisp]]'' autorstwa [[Peter Seibel|Petera Seibela]], wstępu do CL dla nowych programistów Lispu, opublikowanej w [[2004]] roku<ref>[http://gigamonkeys.com/blog/2007/05/26/pcl-third-printing.html Informacja o trzecim wydaniu PCL]</ref>. Była ona drugą co do popularności książką o programowaniu na [[Amazon.com|Amazon]]. Aktualnie dostępna jest za darmo w [[internet|internecie]]<ref>[http://gigamonkeys.com/book/ Practical Common Lisp]</ref>. Można również zauważyć zwiększoną frekwencję na związanych z Lispem konferencjach<ref>[http://www.regdeveloper.co.uk/2007/04/02/international_lisp_conference_2007/ Keeping Lisp alive and practical | Reg Developer]</ref> i aktywność na powiązanych [[grupa dyskusyjna|grupach]]<ref>[http://www.complang.tuwien.ac.at/anton/comp.lang-statistics/ Programming language popularity]</ref>.
 
Wielu nowych programistów Lispu zostało zainspirowanych przez wypowiedzi takich postaci jak [[Paul Graham]] czy [[Eric Raymond|Eric S. Raymond]] by spopularyzować język uznawany za przestarzały. Nowi programiści zwykle opisują język jako dający nowe spojrzenie na programowanie i twierdzą, że dzięki temu stali się dużo bardziej wydajni niż w innych językach<ref>{{cytuj stronę
|tytuł=The Road To Lisp Survey |url=http://wiki.alu.org/The_Road_To_Lisp_Survey |data dostępu=2006-10-13}}</ref>. Wpływ na odzyskiwanie popularności przez Lisp mógł mieć również komentarz [[Peter Norvig|Petera Norviga]]<ref>[http://norvig.com/Lisp-retro.html A Retrospective on PAIP]</ref>, autora książek ''[[Paradigms of AI Programming: Case Studies in Common Lisp]]'' i ''[[Artificial Intelligence: A Modern Approach]]'' lub [[Phillip Greenspun]], który odniósł sukces biznesowy używając Lispu.
 
Linia 82:
'''Common Lisp''', bazujący głównie na [[Maclisp]]ie, [[InterLisp]] i dialektach z maszyn lispowych, jest poszerzonym nadzbiorem wcześniejszych dialektów, z szeroką specyfikacją, obejmującą wiele wbudowanych typów danych i form syntaktycznych, jak również system obiektowy.
 
'''Scheme''' reprezentuje podejście minimalistyczne, ze znacznie mniejszym zbiorem standardowych funkcji, ale za to z określonymi cechami implementacyjnymi (jak na przykład optymalizacja [[rekursjaRekurencja ogonowa|rekursji ogonowej]] czy pełne [[kontynuacjaInstrukcja kontynuacji|kontynuacje]]), które niekoniecznie mogą być dostępne w Common Lispie. CL zapożyczył również pewne cechy ze Scheme jak na przykład [[leksykalny zasięg]] czy leksykalne [[domknięcie (programowanie)|domknięcie]].
 
Poza tym, dialekty Lispu są używane jako [[język skryptowy|'''języki skryptowe''']] w aplikacjach, z czego najbardziej znanymi są:
Linia 98:
Lisp był pierwszym językiem, w którym kod źródłowy był również strukturą danych używaną przez język – w tym przypadku listą. Umożliwiło to wprowadzenie makr (których nie należy mylić z prostymi makrami podstawieniowymi znanymi na przykład z preprocesora C), których zadaniem jest tworzenie kodu źródłowego podczas interpretowania (lub kompilacji) programu – makra to zatem programy piszące programy. Pozwalają one na pisanie eleganckiego kodu na wyższym poziomie abstrakcji i zredukowanie jego ilości.
 
Konstrukcja ''if-then-else'', współcześnie uznawana za konieczny element każdego języka programowania, została wymyślona przez McCarthy'ego dla Lispu w bardziej ogólnej formie (jako konstrukcja cond). Pomysł został skopiowany i spopularyzowany przez [[Algol (język programowania)|Algola]]. Lisp wprowadził również koncepcję [[dynamiczneTypowanie typowaniedynamiczne|dynamicznego typowania]] i mechanizm [[Odśmiecanie pamięci|garbage collection]].
 
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.
Linia 124:
Bazowanie na wyrażeniach daje językowi dużą elastyczność. Ponieważ [[funkcja|funkcje]] w Lispie są zapisywane jako listy, mogą być manipulowane jak zwykłe dane. Umożliwia to łatwe pisanie programów, które operują na innych programach ([[metaprogramowanie]]). Wiele dialektów wykorzystuje tę cechę przez użycie systemu makr, które pozwalają na niemal nieograniczone poszerzanie języka.
 
Lista w Lispie jest zapisywana jako elementy rozdzielone [[biały znak|białymi znakami]] i otoczone [[nawias]]ami. Na przykład, <code>(1 2 foo)</code> to lista, której elementami są trzy atomy, wartości <code>1</code>, <code>2</code>, i <code>[[Zmienna metasyntaktyczna|foo]]</code>. Te wartości są domyślnie typowane (ich typy nie muszą być deklarowane): są to odpowiednio dwie liczby całkowite i specyficzny dla Lispu typ symboliczny,
 
Wyrażenia są zapisywane jako listy z wykorzystaniem [[notacja polska|notacji polskiej]]. Pierwszym elementem listy jest nazwa formy, czyli funkcji, makra lub specjalnego operatora. Pozostałe elementy listy są argumentami. Na przykład, funkcja <code>list</code> zwraca listę zbudowaną ze swoich argumentów, więc ewaluacja wyrażenia
Linia 166:
Podstawową różnicą pomiędzy atomami i listami był fakt, iż atomy były niezmienne i unikalne. Dwa atomy, które pojawiły się w różnych miejscach w kodzie źródłowym, ale były zapisane w dokładnie ten sam sposób, reprezentowały ten sam obiekt, podczas gdy każda lista była oddzielnym obiektem, mogła być modyfikowana niezależnie od innych list i odróżniana od nich za pomocą funkcji porównujących.
 
Gdy w późniejszych dialektach Lispu wprowadzono więcej typów danych, a styl programowania się zmienił, pojęcie atomu straciło swoją ważność. Wiele dialektów wciąż utrzymywało predykat ''atom'' dla [[wstecznaKompatybilność kompatybilnośćwsteczna|wstecznej kompatybilności]], definiując go jako prawdę dla wszystkiego, co nie było komórką [[cons]] (np. listy lub częściowej listy).
 
=== Komórki cons i listy ===
Linia 233:
Każde wyrażenie może zostać zacytowane by zapobiec ewaluacji (jest to konieczne przy wprowadzaniu symboli i list). Tę rolę pełni specjalny operator <code>quote</code>, lub jego skrót <code>'</code> (pojedynczy znak [[apostrof]]u). Na przykład, zwykle jeżeli wprowadzisz symbol <code>foo</code>, dostaniesz z powrotem wartość odpowiadającej zmiennej (lub błąd, jeżeli takowa zmienna nie istnieje). Jeżeli jednak chcesz odwoływać się nie do zmiennej a do samego symbolu, musisz użyć <code>(quote foo)</code> lub, co znacznie popularniejsze, <code>'foo</code>.
 
Zarówno Common Lisp jak i Scheme obsługują również operator ''[[gravisGrawis|backquote]]'' (zwykle zwany ''quasiquote'' przez użytkowników Scheme) wprowadzany jako znak <code>`</code>. Jedyną różnicą ze zwykłym quote jest fakt, iż backquote pozwala na ewaluację i wstawienie wyniku wyrażenia do cytowanej listy za pomocą operatorów ''comma'' i ''comma-at''. Jeżeli zmienna <code>snue</code> ma wartość <code>(bar baz)</code>, to <code>`(foo ,snue)</code> jest ewaluowane do <code>(foo (bar baz))</code>, podczas gdy <code>`(foo ,@snue)</code> ewaluuje się do <code>(foo bar baz)</code>. Backquote jest najczęściej używany przy definiowaniu makr.
 
Formy ewaluujące się do samych siebie i formy cytowane są odpowiednikiem [[literał]]ów, znanych z innych języków. Możliwa jest jednak modyfikacja literałów wewnątrz kodu źródłowego. Na przykład, jeżeli funkcja zwraca formę cytowaną, a kod wywołujący funkcje modyfikuje ją, wpłynie to na wynik zwracany przez kolejny wywołania danej funkcji.
Linia 306:
Makra Lispu operują na tych strukturach. Ponieważ kod w Lispie ma taką samą strukturę jak lista, makra mogą być tworzone za pomocą wszystkich funkcji przetwarzających listy dostępnych w języku. W skrócie, wszystko, co Lisp może zrobić ze strukturą danych, makra Lispu mogą zrobić z kodem. W przeciwieństwie do tego, wynik parsowania w większości języków jest wyłącznie do użytku przez implementację i niedostępny dla programisty. Makra w [[C (język programowania)|C]] na przykład działają na poziomie [[preprocesor]]a, zanim parser jest uruchamiany, i nie mogą restrukturyzować kodu programu tak jak makra Lispu.
 
W prostych implementacjach Lispu, ta struktura jest bezpośrednio interpretowana podczas uruchamiania programu; funkcja to dosłownie pewna lista, przez którą interpreter przechodzi podczas uruchamiania danej funkcji. Większość systemów Lispu do poważnych zastosowań zawiera jednak również [[kompilator]]. Kompilator tłumaczy listę do [[kodJęzyk maszynowy|kodu maszynowego]] lub [[Kod bajtowy|kodu bajtowego]] przed wywołaniem.
 
=== Ewaluacja i REPL ===
W wielu dialektach Lispu dostępna jest interaktywna [[wiersz poleceń|linia poleceń]], która może zostać włączona do [[zintegrowane środowisko programistyczne|IDE]]. Użytkownik wpisuje [[wyrażenie (informatyka)|wyrażenia]] do linii poleceń, lub sprawia, by IDE wysyłało je do systemu Lispu. Lisp czyta (ang. ''read'') wprowadzone wyrażenie, ewaluuje je (ang. ''evaluate'') i wypisuje (ang. ''print'') wynik. Z tego powodu linia poleceń Lispu jest nazywana "read-eval-print loop" (''pętla wczytaj-ewaluuj-wypisz''), lub w skrócie REPL.
 
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.
Linia 319:
Zadaniem funkcji <code>print</code> jest reprezentacja wartości wynikowej w sposób czytelny dla użytkownika. Dla prostych wartości takich jak <code>3</code>, to zadanie jest trywialne. Dla list <code>print</code> musi przetworzyć całą strukturę i wypisać ją jako S-wyrażenie.
 
By zaimplementować lispowy REPL, wystarczy zaimplementować te trzy funkcje i funkcję nieskończonej [[pętlaPętla (informatyka)|pętli]] (oczywiście, implementacja funkcji <code>eval</code> może być nieco skomplikowana, gdyż wymaga implementacji wszystkich specjalnych operatorów takich jak <code>if</code>). Gdy to zostanie wykonane, podstawowy REPL może być wprowadzony za pomocą tylko jednej linii kodu: <code>(loop (print (eval (read))))</code>.
 
Kod w Lispie jest [[wartościowanie zachłanne|wartościowany zachłannie]]. W [[Common Lisp]]ie argumenty są wartościowane w kolejności od lewej do prawej, podczas gdy specyfikacja Scheme tego nie definiuje, pozostawiając kompilatorom możliwość optymalizacji.
Linia 326:
Lisp początkowo miał niewiele struktur kontrolnych, wiele zostało dodanych w czasie, gdy język ewoluował. Pierwotny operator warunkowy Lispu, <code>cond</code>, jest prekursorem późniejszej konstrukcji <code>if-then-else</code>.
 
Programiści [[Scheme]] zwykle wyrażają pętle za pomocą [[rekursjaRekurencja ogonowa|rekursji ogonowej]]. Powszechność Scheme w nauczaniu akademickim sprawiła, że wielu uczniów zaczęło myśleć, że rekursja jest jedyną (lub najpopularniejszą) metodą opisywania iteracji w Lispie, co jest nieprawdą. Wszystkie często spotykane dialekty Lispu mają imperatywne konstrukcje pętli, począwszy od znanej ze Scheme pętli <code>do</code> po złożoną konstrukcję <code>loop</code> z Common Lispu. Przyczyną tak wielkiej popularności rekursji ogonowej w Scheme jest wsparcie tego w specyfikacji – daje ona określone zasady, jak traktować wywołania ogonowe, dzięki czemu programiści mogą mieć pewność, że zostaną one zamienione na pętlę. W przeciwieństwie do tego [[Common Lisp|ANSI Common Lisp]] nie daje<ref>[http://www.lispworks.com/documentation/HyperSpec/Body/03_bbc.htm 3.2.2.3 Semantic Constraints] in [http://www.lispworks.com/documentation/HyperSpec/Front/index.htm ''Common Lisp HyperSpec'']</ref> określonych wskazówek odnośnie rekursji ogonowej, co sprawia, że część implementacji traktuje wywołania ogonowe jak zwykłe. W związku z tym fakt, iż używanie rekursji ogonowej jako zamiennika pętli jest w Common Lispie niezalecane<ref>4.3. Control Abstraction (Recursion vs. Iteration) w [http://www.cs.umd.edu/~nau/cmsc421/norvig-lisp-style.pdf Tutorial on Good Lisp Programming Style] autorstwa [[Kent Pitman|Kenta Pitmana]] i [[Peter Norvig|Petera Norvig]], sierpień 1993.</ref> nie jest jedynie kwestią stylistyczną, ale również wpływ na to ma wydajność (ponieważ nawet oczywiste wywołanie ogonowe niekoniecznie może być zamienione na pojedynczy skok) i poprawność (ponieważ wiele wywołań ogonowych niezamienionych na skok może grozić [[przepełnienie stosu|przepełnieniem stosu]]).
 
Część wyrażeń w Lispie to ''specjalne operatory'', odpowiadające znanym z innych języków słowom kluczowym. Wyrażenia te wyglądają z zewnątrz tak samo, jak wywołania funkcji, różnią się jednak tym, że argumenty nie zawsze są wartościowane – lub, w przypadku pętli, mogą być wartościowane więcej niż raz.
Linia 360:
(* n (factorial (- n 1)))))
</source>
Alternatywna implementacja, zwykle szybsza, jeżeli dana implementacja Lispu stosuje optymalizację [[rekursjaRekurencja ogonowa|rekursji ogonowej]]:
<source lang="lisp">
(defun factorial (n &optional (acc 1))
Linia 439:
 
== 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 C (język programowania)|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">
Linia 557:
* [http://www.gigamonkeys.com/book/ Książka "Practical Common Lisp"] {{lang|en}}
* [http://psg.com/~dlamkins/sl/contents.html Książka "Successfull Lisp"] {{lang|en}}
* [http://www.se-radio.net/2008/01/episode-84-dick-gabriel-on-lisp/ Wywiad] {{lang|en}} z [[Richard P. Gabriel|Richarem Gabrielem]] ([[Podcasting|podcast]])
* [http://common-lisp.net/project/lispbox/ Lisp in a Box] {{lang|en}}, użyteczna paczka dla początkujących w Lispie – dla [[Microsoft Windows|Windowsa]] lub [[POSIX|Uniksa]].
 
Linia 567:
[[an:Lisp]]
[[bn:লিস্প (প্রোগ্রামিং ভাষা)]]
[[bg:Lisp]]
[[bs:Lisp programski jezik]]
[[bg:Lisp]]
[[ca:Lisp]]
[[cs:Lisp]]