Dlaczego Lisp?

Wielokrotnie byłem pytany, dlaczego interesuję się Lispem, co mnie skłoniło do jego nauki i "co w nim jest takiego fajnego". W tym tekście chcę odpowiedzieć na te pytania i wyjaśnić, czego szukam w tym języku i jak jego nauka wpłynęła na mnie do tej pory. Historia zaczęła się rok temu, gdy aktywnie prokrastynując celem ucieczki od projektu, który został mi "na wrzesień", trafiłem na interesujący post na devBlogach - "Niebezpieczne Java-Szkoły". Sam artykuł, którego lekturę gorąco polecam, wspomina o Lispie w kilku miejscach, ale jedna wzmianka okazała się decydująca. "Beating the Averages" Paula Grahama. Tak, słyszałem wcześniej o Lispie. To ten język, w którym nawiasy tworzą większość kodu. Wygląda jak mleko z powrzucanymi obciętymi paznokciami. To najdziwniejszy język, w jakim można pisać kod, zaraz po BF i Whitespace. Tego typu opinie. A tu nagle pewien człowiek twierdzi w porywającym eseju, że Lisp jest najpotężniejszym językiem programowania dostępnym obecnie. I przedstawia argumenty. To przykuwa uwagę. Blub programmer Jedną z najważniejszych myśli eseju Paula Grahama jest to, że języki programowania różnią się w mocy. Myślę, że intuicyjnie zdawałem sobie z tego sprawę od jakiegoś czasu, ale nigdy nie myślałem o tym świadomie. Właściwie, muszę się do czegoś przyznać. Do tego momentu, zgodnie z terminologią eseju, byłem typowym "Blub programmerem" (jeżeli Czytelniku jeszcze nie przeczytałeś tego eseju, to gorąco zachęcam do lektury). Mój ulubiony język programowania (tak się złożyło, że był nim C++) jest najlepszy. Wszystko co jest na niższym poziomie to niepotrzebne męczenie się. Wszystko, co jest na wyższym poziomie (zwłaszcza Java, za którą nie przepadałem) i tak można zaimplementować w C++. Właściwie cały mój świat programistyczny skupiał się wokół C++, Javy (która jak dla mnie jest bloatware'm), C# i PHP. Programowanie funkcyjne? Nie słyszałem nigdy o czymś takim. Wielkie obietnice
Lisp is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a better programmer for the rest of your days, even if you never actually use Lisp itself a lot.
Powyższy cytat, przytoczony przez Paula a pochodzący z "How To Become A Hacker" Erica Stevena Raymonda, był intrygujący. Przeczytałem więc inne eseje - w tym "Revenge of the Nerds", "What Made Lisp Different". Na innej stronie znalazłem też "The Nature of Lisp". Wszystko to przyswojone "na raz" robi mętlik w głowie, ale pewne trendy zaczynały stawać się widoczne. Widziałem trochę kłótni, dysput i artykułów na temat wyższości jednych języków nad drugimi (C++ vs. Delphi i C++ vs. Java były moimi ulubionymi sporami). Zwykle fani danego języka twierdzą, że jest on lepszy od języka przeciwników. Ale nigdy wcześniej nie widziałem, żeby ktoś twierdził, że ich język jest najlepszy, najpotężniejszy, że Bóg stworzył za jego pomocą wszechświat. Tylko Lisp odważył się zająć miejsce ponad wszystkimi. Zwykła arogancja? A może uzasadniona*? W dużym skrócie, najważniejsze argumenty stawiane przez zwolenników Lispu to:
  • Język ten jest unikatowy w swojej możliwości wyrażania myśli przez programistę. Dzięki umiejętności przepisywania własnego kodu źródłowego w czasie kompilacji można zmieniać sam język w taki sposób, żeby dopasowywał się do rozwiązywanego problemu. Programując w Lispie człowiek używa najpotężniejszego języka programowania dostępnego obecnie.
  • Sam proces poznawania i zrozumienia Lispu czyni człowieka lepszym programistą, niezależnie od języka jakiego przyjdzie mu później używać (ten argument zdaje się też pasować do teoretycznych, matematycznych stron informatyki; biorąc pod uwagę pochodzenie Lispu, może to nie jest zbieg okoliczności).
  • Kolejne języki programowania powstające obecnie stopniowo zdążają do Lispu, implementując różne cechy, które w tym ostatnim były dostępne od wielu lat. Nauka Lispu jest więc strategicznie najlepszą opcją, bo język ten zawiera wszystkie ważne elementy semantyczne innych języków, a wciąż ma cechy, których nikt inny nie powielił (np. makra).
To wszystko brzmiało dla mnie bardzo intrygująco - zwłaszcza, że nie chciałem (i dalej nie chcę) skończyć jako klepacz biznesowego kodu w Javie. Bardzo zaciekawiony postanowiłem więc nauczyć się Lispu i sprawdzić doświadczalnie, czy te wszystkie zapewnienia jego zwolenników są uzasadnione. Eksperyment Przez ostatni rok uczyłem się Lispu w wolnych chwilach (czasem nawet spychając 'przyziemne sprawy uczelni' na dalszy plan). Chociaż póki co zdążyłem napisać w nim jedynie małą grę i kilka drobnych narzędzi, to mogę dziś powiedzieć, że odniosłem wiele korzyści, często nie związanych stricte z naturą języka Lisp.
  • Odkryłem, że tam daleko, poza C++, Javą i C# jest cały wielki świat programowania. Że programowanie zorientowane obiektowo nie jest receptą na wszystko (świadomie bądź nie, ale wcześniej w to wierzyłem); są inne paradygmaty programowania, które w wielu miejscach są bardziej odpowiednie.
  • Poznałem programowanie funkcyjne. Chociaż Lisp nie jest językiem funkcyjnym (jest wieloparadygmatowy), to wiele wzorców pisania kodu - związanych z pracą na listach i drzewach oraz funkcjach wyższego rzędu i wyrażeniach lambda - stanowi podstawę funkcyjnego tworzenia oprogramowania (która to jest tematem na zupełnie osobny wpis). Gdyby nie Lisp, najprawdopodobniej w ogóle nie zainteresowałbym się Erlangiem, i nie pisałbym w nim dziś oprogramowania.
  • Zrozumiałem, że C++ w programowaniu zorientowanym obiektowo nie mówi ostatniego słowa. Common Lisp tak na prawdę pokazał mi, że model obiektowy może być zrobiony wokół zupełnie innych założeń, być większy i bogatszy.
  • Nabrałem wstrętu do pisania rzeczy, które powinien pisać za mnie komputer. Jak powiedział Olin Shivers, "I object to doing things that computers can do." Przykładowo, wśród programistów C/C++ (a także innych języków, np. Erlanga) znana jest niechęć do używania makr preprocesora. W wielu przypadkach jest ona uzasadniona, jednak dzięki "Lispowemu sposobowi myślenia" zacząłem traktować preprocesor jako przydatne narzędzie generowania kodu w czasie kompilacji.
Nauka Lispu miała też potężny efekt uboczny:
  • Zacząłem dostrzegać wpływy Lispu wszędzie. Tak, wiem - niektórych to denerwuje. Odruchowe zwracanie uwagi, że "XYZ zgapiło to z Lispu!". Te skojarzenia nie są jednak nieuzasadnione. Dobrze oddaje to "10-ta zasada programowania Greenspuna":
    Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.
    Na to, jak ten sposób myślenia udziela się programistom Lispu, samokrytycznie zwrócił uwagę Slobodan Blazeski w artykule o Haskelu:
    (...) The reasons vary but it probably has something with lispers' being spoiled brats. They're damn hard to impress. You show them the cool feature that your favourite language has and they either already have it, have something better or they've already seen it and decided it's not such a good idea as you might think.
A droga długa jest; nie wiadomo, czy ma kres... W dalszym ciągu intrygują mnie możliwości Lispu, których jeszcze w ogóle nie poznałem. W szczególności makra i metaprogramowanie. Chciałbym też dokładniej sprawdzić, czy Lisp jest faktycznie tak wygodnym narzędziem do pisania eksperymentalnych aplikacji jak pisał Paul Graham**. Przede mną jeszcze daleka droga. W dalszym ciągu nie umiem używać makr ani rewelacyjnego systemu wyjątków w Common Lisp. W szczególności, jeżeli chodzi o lekturę, to chciałbym skończyć SICP, a następnie przeczytać "On Lisp", "Let Over Lambda" i "Art of Metaobject Protocol". Do dnia dzisiejszego Lisp dał mi jednak bardzo dużo, i nie żałuję, że zacząłem się go uczyć. Dzięki niemu wyszedłem z "zastoju" informatycznego i odkryłem wiele nowych dziedzin i rozwiązań, o których wcześniej nawet mi się nie śniło. (przypisy) * - Podobnie do mnie czuł się pewien człowiek, którego Paul Graham cytuje na swojej stronie
"I have heard more than one LISP advocate state such subjective comments as, "LISP is the most powerful and elegant programming language in the world" and expect such comments to be taken as objective truth. I have never heard a Java, C++, C, Perl, or Python advocate make the same claim about their own language of choice." - A guy on Slashdot. What theory fits this data?
** - W czasach, gdy Paul pisał swój esej, języki takie jak Python, Perl czy Ruby nie były powszechnie używane w taki sposób jak dzisiaj; obecna ilość i rozmiar projektów powstających w językach dynamicznie typowanych wysokiego poziomu, posiadających REPL jest argumentem za tym, że miał rację.