Jak daleko mogą zajść makra w Lispie? [zamknięte]

Czytałem wiele, że LISP może redefiniować składnię w locie, prawdopodobnie za pomocą makr. Jestem ciekaw, jak daleko to się posuwa? Czy można przedefiniować strukturę języka tak bardzo, że staje się kompilatorem dla innego języka? Na przykład, czy mógłbyś zmienić funkcjonalny charakter Lispu na bardziej obiektową składnię i semantykę, może powiedzmy, że składnia jest bliższa coś takiego jak Ruby?

Szczególnie, czy możliwe jest pozbycie się piekła nawiasów za pomocą makra? Nauczyłem się wystarczająco dużo (Emacs -) Lispu, aby dostosować Emacsa do własnych mikro-funkcji, ale jestem bardzo ciekawy, jak daleko makra mogą zajść w dostosowywaniu języka.

 43
Author: Mike Stone, 2008-08-05

14 answers

To naprawdę dobre pytanie.

Myślę, że jest niuansowy, ale zdecydowanie odpowiada:

Makra nie są blokowane w wyrażeniach s. Zobacz makro pętli dla bardzo złożonego języka napisanego za pomocą słów kluczowych (symboli). Tak więc, podczas gdy możesz rozpocząć i zakończyć pętlę nawiasami, wewnątrz niej ma swoją własną składnię.

Przykład:

(loop for x from 0 below 100
      when (even x)
      collect x)

Biorąc to pod uwagę, większość prostych makr używa tylko s-wyrażeń. A Ty byś" utknął " używając ich.

Ale s-wyrażenia, jak Sergio ma odpowiedz, Poczuj się dobrze. Składnia zniknie z drogi i zaczniesz kodować w drzewie składni.

Co do makr czytnika, tak, można by napisać coś takiego:

#R{
      ruby.code.goes.here
  }

Ale musisz napisać własny parser składni Ruby.

Możesz również naśladować niektóre konstrukcje Ruby, jak bloki, za pomocą makr, które kompilują się do istniejących konstrukcji Lispa.

#B(some lisp (code goes here))

Przetłumaczy na

(lambda () (some lisp (code goes here)))

Zobacz ta strona aby dowiedzieć się, jak to zrobić.

 33
Author: Eric Normand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-15 15:07:21

Tak, możesz przedefiniować składnię tak, aby Lisp stał się kompilatorem. Robisz to za pomocą "makr Reader", które różnią się od zwykłych "makr kompilatorów", o których prawdopodobnie myślisz.

Common Lisp ma wbudowany mechanizm definiowania nowej składni dla programu reader i makr programu reader do przetwarzania tej składni. Przetwarzanie to odbywa się w czasie odczytu (który następuje przed czasem kompilacji lub ewaluacji). Aby dowiedzieć się więcej o definiowaniu makr programu reader w Common Lispie, zobacz Common Lisp Hyperspec -- będziesz chciał przeczytać Ch. 2, "składnia" i Ch. 23, "czytelnik" . (Wydaje mi się, że Scheme ma ten sam mechanizm, ale nie jestem z nim tak dobrze zaznajomiony -- Zobacz Scheme sources dla Arc programming language).

Jako prosty przykład, załóżmy, że chcesz, aby Lisp używał nawiasów klamrowych zamiast nawiasów. Wymaga to czegoś w rodzaju następujących definicji czytelnika:

;; { and } become list delimiters, along with ( and ).
(set-syntax-from-char #\{ #\( )
(defun lcurly-brace-reader (stream inchar) ; this was way too easy to do.
  (declare (ignore inchar))
  (read-delimited-list #\} stream t))
(set-macro-character #\{ #'lcurly-brace-reader)

(set-macro-character #\} (get-macro-character #\) ))
(set-syntax-from-char #\} #\) )

;; un-lisp -- make parens meaningless
(set-syntax-from-char #\) #\] ) ; ( and ) become normal braces
(set-syntax-from-char #\( #\[ )

Mówisz Lispowi, że { jest jak a (i że } jest jak a ). Wtedy tworzysz funkcję (lcurly-brace-reader), którą czytnik będzie wywoływał, gdy zobaczy {, i używasz set-macro-character, aby przypisać tę funkcję do {. Następnie mówisz Lispowi, że ( and) są jak [and ] (czyli nie znacząca składnia).

Inne rzeczy, które możesz zrobić, to na przykład tworzenie nowej składni ciągu znaków lub użycie [ and] do załączenia notacji in-fix i przetworzenia jej na s-wyrażenia.

Możesz również wyjść daleko poza to, redefiniując całą składnię za pomocą własnych znaków makro to uruchomi działania w czytniku, więc niebo naprawdę jest granicą. Jest to tylko jeden z powodów, dla których Paul Graham i inni mówią, że Lisp jest dobrym językiem do pisania kompilatora.

 20
Author: Sean Harrison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 19:36:43

Nie jestem ekspertem w Lispie, heck nie jestem nawet programistą Lispu, ale po kilku eksperymentach z językiem doszedłem do wniosku, że po chwili nawias zaczyna być 'niewidoczny' i zaczynasz widzieć kod taki, jaki chcesz. Zaczynasz zwracać większą uwagę na konstrukcje składniowe, które tworzysz za pomocą S-expr i makr, a mniej na formę leksykalną tekstu list i nawiasów.

Jest to szczególnie prawdziwe, jeśli skorzystasz z dobrego edytora, który pomaga przy kolorowaniu wcięć i składni (spróbuj ustawić nawias na kolor bardzo podobny do tła).

Możesz nie być w stanie całkowicie zastąpić języka i uzyskać składnię 'Ruby', ale nie potrzebujesz jej. Dzięki elastyczności języka możesz zakończyć posiadanie dialektu, który sprawia wrażenie, jakbyś podążał za "stylem programowania Ruby", jeśli chcesz, cokolwiek by to dla Ciebie znaczyło.

Wiem, że to tylko obserwacja empiryczna, ale myślę, że miałem jedną z te momenty oświecenia w Lispie, kiedy zdałem sobie z tego sprawę.

 16
Author: Sergio Acosta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-26 09:49:02

W kółko, Nowi użytkownicy Lispu chcą "pozbyć się wszystkich nawiasów."Trwa kilka tygodni. Żaden projekt budowy poważnej składni programowania ogólnego przeznaczenia na zwykłym parserze s-expression nigdy nie dotrze nigdzie, ponieważ programiści niezmiennie wolą to, co obecnie postrzegasz jako "piekło nawiasów"."Trochę trzeba się przyzwyczaić, ale niewiele! Kiedy już się przyzwyczaisz i naprawdę docenisz plastyczność domyślnej składni, idąc wracając do języków, w których istnieje tylko jeden sposób wyrażania konkretnej konstrukcji programistycznej, jest naprawdę krata.

To powiedziawszy, Lisp jest doskonałym substratem do budowania języków specyficznych dla domeny. Tak samo dobry jak, jeśli nie lepszy niż XML.

Powodzenia!

 15
Author: jfm3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 19:29:54

Najlepsze wyjaśnienie makr Lispu jakie kiedykolwiek widziałem to

Https://www.youtube.com/watch?v=4NO83wZVT0A

Począwszy od około 55 minut. Jest to film z wykładu Petera Seibela, autora "Practical Common Lisp" , który jest najlepszym podręcznikiem do Lispu.

Motywacja dla makr Lispu jest zwykle trudna do wyjaśnienia, ponieważ naprawdę pojawiają się one w sytuacjach, które są zbyt długie, aby przedstawić je w prostym samouczku. Peter comes up with a great example; you can capture it completely, and it makra makra makra Lisp makra.

Zapytałeś: "czy mógłbyś zmienić funkcjonalny charakter Lispu na bardziej obiektową składnię i semantykę". Odpowiedź brzmi: tak. W rzeczywistości Lisp pierwotnie nie miał żadnego programowania obiektowego, nic dziwnego, ponieważ Lisp istniał już na długo przed programowaniem obiektowym! Ale kiedy po raz pierwszy dowiedzieliśmy się o OOP w 1978 roku, byliśmy w stanie łatwo dodać go do Lispu, używając, między innymi makra. W końcu powstał Common Lisp Object System (CLOS), bardzo potężny obiektowy system programowania, który elegancko pasuje do Lispu. Całość można załadować jako rozszerzenie-nic nie jest wbudowane! Wszystko odbywa się za pomocą makr.

Lisp ma zupełnie inną funkcję, zwaną "makrami czytnika", która może być używana do rozszerzania powierzchniowej składni języka. Korzystając z makr programu reader, możesz tworzyć podjęzyki, które mają składnię podobną do C lub Ruby. Przekształcają tekst w Lisp, wewnętrznie. Nie są one powszechnie używane przez większość prawdziwych programistów Lispu, głównie dlatego, że trudno jest rozszerzyć interaktywne środowisko programistyczne, aby zrozumieć nową składnię. Na przykład, polecenia wcięć Emacsa będą mylone przez nową składnię. Jeśli jednak jesteś energiczny, Emacs jest również rozszerzalny i możesz go nauczyć o swojej nowej składni leksykalnej.

 12
Author: Dan Weinreb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-08 08:39:32

Zwykłe makra działają na listach obiektów. Najczęściej są to inne listy (tworzące drzewa) i symbole, ale mogą to być inne obiekty, takie jak łańcuchy znaków, Hashtable, obiekty zdefiniowane przez użytkownika itp. Struktury te nazywane są s-EXP .

Tak więc, gdy załadujesz plik źródłowy, kompilator Lispu przetworzy tekst i wytworzy s-EXP. Działają na nich makra. To działa świetnie i jest to wspaniały sposób, aby rozszerzyć język w duchu s-EXP.

DODATKOWO wspomniany proces parsowania może być rozszerzony przez "makra programu reader", które pozwalają dostosować sposób, w jaki kompilator zamienia tekst w s-EXP. Sugeruję jednak, abyś przyjął składnię Lispu zamiast naginać ją do czegoś innego.

Brzmisz trochę zdezorientowany, gdy wspomnisz o "funkcjonalnej naturze" Lispa I O "obiektowej składni Rubiego". Nie jestem pewien, co to ma być "obiektowa składnia", ale Lisp jest językiem multi-paradygmat i to obsługuje programowanie obiektowe extremelly dobrze.

BTW, Kiedy mówię Lisp, mam na myśli Common Lisp .

Proponuję odłożyć swoje uprzedzenia i dać Lispowi uczciwe podejście .

 11
Author: Luís Oliveira,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-26 14:02:24

To, o co pytasz, jest trochę jak pytanie, jak stać się ekspertem w dziedzinie czekolady, aby można było usunąć wszystkie te piekielne brązowe rzeczy ze swojego ulubionego ciasta czekoladowego.

 9
Author: user15700,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-17 12:14:53

Nawias piekło? Nie widzę więcej nawiasów w:

(function toto)

Niż w:

function(toto);

I w

(if tata (toto)
  (titi)
  (tutu))

Nie więcej niż w:

if (tata)
  toto();
else
{
  titi();
  tutu();
}

Widzę jednak mniej nawiasów i';'.

 9
Author: Jerry Cornelius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-20 11:11:23

Tak, możesz zasadniczo zmienić składnię, a nawet uciec od "piekła nawiasów". W tym celu należy zdefiniować nową składnię czytnika. Zajrzyj do makr programu reader.

Podejrzewam jednak, że aby osiągnąć poziom ekspertyzy Lispu do programowania takich makr, będziesz musiał zanurzyć się w języku do tego stopnia, że nie będziesz już rozważał "piekła". To znaczy. do czasu, gdy wiesz, jak ich uniknąć, będziesz musiał zaakceptować je jako dobrą rzecz.

 6
Author: HD.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-15 12:07:06

Jeśli chcesz, aby lisp wyglądał jak Ruby użyj Ruby.

Możliwe jest używanie Rubiego (i Pythona) w sposób bardzo podobny do Lispu, co jest jednym z głównych powodów, dla których tak szybko zyskali akceptację.

 2
Author: sparkes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-05 07:40:26

Zobacz przykład, jak makra Reader mogą rozszerzać czytnik Lispu o złożone zadania, takie jak szablony XML:

Http://common-lisp.net/project/cl-quasi-quote/present-class.html

Ta biblioteka użytkownika kompiluje statyczne części XML do kodowanych w UTF-8 literalnych tablic bajtów w czasie kompilacji, które są gotowe do sekwencji zapisu do strumienia sieciowego. i są użyteczne w normalnych makrach Lispu, są ortogonalne... umieszczenie znaku przecinka wpływa na to, które części są stałe i które powinny być oceniane podczas pracy.

Więcej szczegółów na stronie: http://common-lisp.net/project/cl-quasi-quote/

Kolejny projekt, który dla rozszerzeń składni Common Lispu: http://common-lisp.net/project/cl-syntax-sugar/

 2
Author: Attila Lendvai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-17 00:30:43

@ sparkes

Czasami LISP jest oczywistym wyborem języka, a mianowicie rozszerzeniami Emacsa. Jestem pewien, że mógłbym użyć Rubiego do rozszerzenia Emacsa, gdybym chciał, ale Emacs został zaprojektowany do rozszerzenia z LISPEM, więc wydaje się sensowne użycie go w tej sytuacji.

 1
Author: Mike Stone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-05 07:45:14

To podchwytliwe pytanie. Ponieważ lisp jest już strukturalnie tak blisko drzewa parsującego, różnica między dużą liczbą makr a implementacją własnego mini-języka w generatorze parserów nie jest zbyt jasna. Ale, z wyjątkiem paren otwierającego i zamykającego, możesz bardzo łatwo skończyć z czymś, co nie wygląda jak lisp.

 1
Author: John with waffle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-06 12:14:12

Jednym z zastosowań makr, które mnie rozwaliło, była weryfikacja zapytań SQL w czasie kompilacji względem DB.

Gdy uświadomisz sobie, że masz pełny język pod ręką w czasie kompilacji, otwiera to interesujące nowe perspektywy. Co oznacza również, że możesz strzelić sobie w stopę w ciekawy nowy sposób(jak renderowanie kompilacji nie odtwarzalne, które może bardzo łatwo przekształcić się w koszmar debugowania).

 1
Author: Nowhere man,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-19 10:43:32