Jak daleko można pójść makra LISP?

głosy
43

Czytałem dużo, że LISP może zdefiniowania składni w locie, przypuszczalnie z makrami. Jestem ciekaw ile to właściwie iść? Można zmienić strukturę językową tyle że granica staje się kompilator innym języku? Na przykład, można zmienić funkcjonalnego charakteru LISP do bardziej obiektowego składni i semantyki, może powiedzieć, mający składnię bliżej coś jak Ruby?

Szczególnie, jest to możliwe, aby pozbyć się z piekła nawiasie przy użyciu makr? Nauczyłem się wystarczająco dużo (Emacs-) LISP dostosować Emacsa własne mikro funkcji, ale jestem bardzo ciekawy, jak daleko może iść makr w dostosowywaniu się języka.

Utwórz 05/08/2008 o 08:32
źródło użytkownik
W innych językach...                            


14 odpowiedzi

głosy
33

To bardzo dobre pytanie.

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

Makra nie tkwią w S-wyrażeń. Zobacz makro pętla dla bardzo skomplikowanym językiem napisany przy użyciu słów kluczowych (symbole). Tak więc, choć można rozpocząć i zakończyć pętlę z nawiasami, wewnątrz posiada własną składnię.

Przykład:

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

Powiedział, że jest najbardziej prostych makr wystarczy użyć s-wyrażeń. I ty chcesz być „zatrzymany” ich używania.

Ale S-wyrażeń, jak Sergio odpowiedział, zaczynają czuć się dobrze. Składnia wychodzi z drogi i zacząć pisać w drzewie składni.

Jak dla makr czytelnika, tak, mogłaby napisać coś takiego:

#R{
      ruby.code.goes.here
  }

Ale trzeba by napisać własny analizator składni Ruby.

Można również naśladować niektóre z Ruby konstruuje, jak klocki, z makr kompilacji istniejących Lisp konstruktów.

#B(some lisp (code goes here))

przełoży się

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

Zobacz tę stronę dla jak to zrobić.

Odpowiedział 15/09/2008 o 16:07
źródło użytkownik

głosy
20

Tak, można przedefiniować składni, dzięki czemu staje się Lisp kompilator. Można to zrobić za pomocą makra „Reader”, które różnią się od normalnych „Compiler makra”, że jesteś prawdopodobnie myśli o.

Common Lisp ma wbudowaną w obiekcie, aby zdefiniować nową składnię makra i czytnik Reader, aby przetworzyć tę składnię. To przetwarzanie odbywa się w czasie odczytu (co jest przed kompilacji lub eval czas). Aby dowiedzieć się więcej na temat definiowania makr czytelnika w Common Lisp, zobacz Common Lisp Hyperspec - będziemy chcieli odczytać Ch. 2 „Składnia” i Ch. 23, "Lektor" . (Wierzę Schemat ten sam obiekt, ale nie wiem jak z nim zapoznać - patrz źródła Schemat dla języka programowania Arc ).

Jako prosty przykład, załóżmy, że chcesz Lisp używać nawiasów klamrowych zamiast nawiasów. Wymaga to coś jak następujące definicje 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 Lisp, że {jest jak (i że} jest jak). Następnie należy utworzyć funkcję ( lcurly-brace-reader), że czytelnik będzie dzwonić, gdy tylko widzi {i użyć set-macro-character, aby przypisać tę funkcję do {. Wtedy powiedzieć Lisp, że (i) są jak [i] (czyli nie ma sensu składnia).

Inne rzeczy można zrobić to, na przykład, tworząc nową składnię ciąg lub używając [i], aby załączyć notacji in-fix i przetworzyć go na S-wyrażeń.

Można również udać się daleko poza to, redefinicji całą składnię z własnych znaków makro, które będzie powodować działania w czytniku, a więc niebo naprawdę jest dopuszczalne. To tylko jeden z powodów, dlaczego Paul Graham i inni powtarzają, że Lisp jest dobrym językiem, w którym napisać kompilatora.

Odpowiedział 16/09/2008 o 20:28
źródło użytkownik

głosy
16

Nie jestem ekspertem Lisp, cholery nie jestem nawet Lisp programista, ale po trochę eksperymentować z językiem doszedłem do wniosku, że po jakimś czasie zaczynają nawias stają się „niewidzialne” i zaczniesz widzieć jako kod chcesz go mieć. Zaczynasz zwracają większą uwagę na konstrukcji składniowych tworzonych przez S-exprs i makr, a mniej do formy leksykalnej tekstu list i nawiasu.

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

Może nie być w stanie zastąpić język całkowicie i uzyskać składnię „Ruby”, ale nie jest to potrzebne. Dzięki elastyczności językowej może skończyć o gwarę, że czujesz się jak po „styl Ruby programowania”, jeśli chcesz, co oznaczałoby to dla ciebie.

Wiem, że jest to tylko obserwacja empiryczna, ale myślę, że mieliśmy jeden z tych momentów Lisp oświecenia, kiedy uświadomiłem sobie to.

Odpowiedział 26/08/2008 o 10:49
źródło użytkownik

głosy
15

Kółko, nowicjusze Lisp chce „pozbyć się wszystkich nawiasie”. To trwa kilka tygodni. No projekt budowy poważne składni programowania ogólnego przeznaczenia na górze zwykłego parsera S-wyrażenie kiedykolwiek dostaje nigdzie, ponieważ programiści zawsze skończyć preferowanie co obecnie postrzegamy jako „nawiasie piekła.” To zajmuje trochę przyzwyczaić, ale nie za dużo! Gdy ma się do tego przyzwyczaić, a można naprawdę docenić plastyczność składni domyślnej, wracając do języków, gdzie istnieje tylko jeden sposób, aby wyrazić żadnego programowania konstruktu jest naprawdę kraty.

Mając na uwadze powyższe, Lisp jest doskonałym podłożem do budowania Domain Specific Languages. Tak samo dobre jak, jeśli nie lepsze niż, XML.

Powodzenia!

Odpowiedział 16/09/2008 o 20:29
źródło użytkownik

głosy
12

Najlepszym wyjaśnieniem Lisp makr, jakie kiedykolwiek widziałem jest

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

poczynając od około 55 minut. Jest to film z wykładu wygłoszonego przez Petera Seibel, autora „Practical Common Lisp”, który jest najlepszy podręcznik Lisp istnieje.

Motywacją dla Lisp makr jest zazwyczaj trudne do wytłumaczenia, bo naprawdę coś dla siebie w sytuacjach, które są zbyt długie, aby przedstawić w prosty samouczek. Piotr podchodzi z wielkim przykład; można uchwycić go całkowicie, a to sprawia, że ​​dobre, właściwe wykorzystanie Lisp makra.

Zapytałeś: „można zmienić funkcjonalnego charakteru LISP do bardziej obiektowego składni i semantyce”. Odpowiedź brzmi tak. W rzeczywistości, Lisp pierwotnie nie miał żadnego programowania obiektowego w ogóle nie dziwi, ponieważ Lisp istnieje od drogi przed programowania obiektowego! Ale kiedy po raz pierwszy dowiedział się o OOP w 1978 roku, byliśmy w stanie dodać je łatwo LISP, wykorzystując między innymi, makra. Ostatecznie Common Lisp Object System (CLOS) został opracowany, bardzo mocny system programowania obiektowego, który pasuje do Lisp elegancko. Całość może być załadowany jako przedłużenie - nic nie jest wbudowane w! To wszystko odbywa się z makrami.

Lisp ma zupełnie inną funkcję, zwany „makra Reader”, który może być stosowany w celu rozszerzenia składni powierzchni języka. Używanie makr czytnika, można dokonać podjęzyków które mają podobną składnię C lub Ruby-podobnego. przekształcić je w tekst Lisp, wewnętrznie. Te nie są powszechnie używane przez większość prawdziwych Lisp programistów, głównie dlatego, że trudno jest wydłużyć interaktywne środowisko programistyczne do zrozumienia nowej składni. Na przykład, polecenia wcięć Emacs będzie zdezorientowany nowej składni. Jeśli jesteś energiczny, choć Emacs jest rozszerzalny zbyt, i można nauczyć je o swojej nowej składni leksykalnej.

Odpowiedział 05/10/2008 o 16:03
źródło użytkownik

głosy
11

Regularne makra działają na listach obiektów. Najczęściej te przedmioty są inne listy (drzew), tworząc w ten sposób i symbole, ale mogą być też inne obiekty, takie jak struny, hashtables, obiekty zdefiniowane przez użytkownika, itd Struktury te są nazywane S-EXPS .

Więc, kiedy załadować plik źródłowy, twój Lisp kompilator będzie analizować tekst i produkować s-EXPS. Makra działają na nich. To działa świetnie i jest to wspaniały sposób na rozszerzenie języka w duchu S-EXPS.

Dodatkowo, wspomniany proces analizowania może zostać przedłużony przez „Reader” makr, które pozwalają dostosować sposób kompilator zamienia tekst na s-EXPS. Proponuję jednak, że uścisk składni Lisp, zamiast wyginając go w coś innego.

Mówisz trochę zdezorientowany kiedy wspomina „charakter funkcjonalny” i „LISP obiektowego składni” Ruby. Nie jestem pewien, co „obiektowego składnia” ma być, ale Lisp jest językiem multi-paradygmat i obsługuje programowanie obiektowe wybitnie dobrze.

BTW, kiedy mówię, Lisp, to znaczy Common Lisp .

Proponuję umieścić swoje uprzedzenia z dala i dać Lisp uczciwą odejść .

Odpowiedział 26/08/2008 o 10:36
źródło użytkownik

głosy
9

Co prosicie to trochę jak pytanie, jak stać się ekspertem Chocolatier, dzięki czemu można usunąć cały ten piekielny brązowy rzeczy ze swojego ulubionego czekoladowego ciasta.

Odpowiedział 17/09/2008 o 13:14
źródło użytkownik

głosy
9

Nawias cholery? Nie widzę więcej w nawias:

(function toto)

niż w:

function(toto);

I w

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

nie więcej niż:

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

Widzę mniej wsporników i „;” chociaż.

Odpowiedział 16/09/2008 o 17:23
źródło użytkownik

głosy
6

Tak, można zasadniczo zmienić składnię, a nawet uciec „nawiasów piekło”. Do tego trzeba będzie zdefiniować nową składnię czytnika. Spójrz w makr czytnika.

I podejrzewam jednak, że aby osiągnąć poziom wiedzy Lisp zaprogramować takie makra trzeba będzie zanurzyć się w język w takim stopniu, że nie będzie już rozważenia Parenthese „piekło”. Czyli do czasu, wiesz, jak ich uniknąć, trzeba będzie się przyjmować je jako coś dobrego.

Odpowiedział 15/09/2008 o 13:07
źródło użytkownik

głosy
2

zobaczyć ten przykład jak makra czytelnik może przedłużyć Lisp czytelnikowi złożonych zadań, takich jak XML szablonów:

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

Ta biblioteka użytkownik kompiluje statycznych elementów XML na kodowanie UTF-8 tablic bajtowych dosłowny w czasie kompilacji, które są gotowe do zapisu sequence'd do strumienia sieciowego. i są wykorzystywane w normalnych Lisp makra są prostopadłe ... umieszczanie znaków wpływów przecinkami, które elementy są stałe, a które powinny być oceniane w czasie wykonywania.

Więcej informacji dostępnych pod adresem: http://common-lisp.net/project/cl-quasi-quote/

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

Odpowiedział 17/09/2008 o 01:30
źródło użytkownik

głosy
2

Jeśli chcesz wyglądać jak LISP Ruby użyciu Ruby.

Jest to możliwe do wykorzystania (Ruby i Python) w bardzo podobny sposób lisp który jest jednym z głównych powodów, zyskali akceptację tak szybko.

Odpowiedział 05/08/2008 o 08:40
źródło użytkownik

głosy
1

Jednym z zastosowań makr trąbiącymi mój umysł był weryfikacja kompilacji zapytań SQL na DB.

Po sobie sprawę masz pełną języka pod ręką w czasie kompilacji, otwiera interesujące nowe perspektywy. Co oznacza również można strzelać sobie w stopę w ciekawych nowych sposobów (takich jak rendering kompilację nie powtarzalne, które można bardzo łatwo zamienić się w koszmar debugowania).

Odpowiedział 19/09/2008 o 11:43
źródło użytkownik

głosy
1

Jest to trudne pytanie. Od LISP jest już konstrukcyjnie tak blisko drzewa przeanalizować różnicę między dużą liczbą makr i realizacji własnego mini-język w parser generator nie jest bardzo jasne. Ale, z wyjątkiem otwierających i zamykających paren, można bardzo łatwo skończyć z czymś, co nie przypomina Lisp.

Odpowiedział 06/08/2008 o 13:14
źródło użytkownik

głosy
1

@sparkes

Czasami LISP jest oczywistym wyborem języka, mianowicie rozszerzenia Emacsa. Jestem pewien, że mogę używać Ruby przedłużyć Emacs gdybym chciał, ale Emacs został zaprojektowany, aby być rozszerzony o LISP, więc wydaje się, aby sensu używać go w takiej sytuacji.

Odpowiedział 05/08/2008 o 08:45
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more