Jakie są typowe zastosowania makr Lisp?

19

Próbuję nauczyć się trochę LISP i dużo czytałem o znaczeniu makr LISP, więc chciałbym zdobyć trochę doświadczenia w pracy z nimi.

Czy możesz zasugerować praktyczny obszar zastosowania, który pozwoliłby mi użyć makr do rozwiązania rzeczywistego problemu i zrozumienia przydatności tego konstruktu programistycznego?

UWAGA

To nie jest ogólny projekt, który powinienem zrobić w następnym pytaniu. Chciałbym zrozumieć, jakie problemy zazwyczaj rozwiązuje się za pomocą makr LISP. Np. Czy są dobre do implementacji abstrakcyjnych typów danych? Dlaczego ten konstrukt został dodany do języka? Jakie problemy rozwiązuje, których nie można rozwiązać za pomocą prostych funkcji?

Giorgio
źródło

Odpowiedzi:

9

Makra Lisp łączą kilka różnych właściwości:

  1. Makra definiują nową składnię ↔ używają kodu źródłowego jako danych wejściowych
  2. Makra zwykle są uruchamiane podczas kompilacji
  3. Makra generują kod źródłowy

Najlepsze aplikacje wykorzystują wszystkie te aspekty. Prawdopodobnie najbardziej znanym przykładem jest (pętla…) w Common Lisp, nie byłby w ogóle bliski swojej przydatności bez jednej z tych funkcji. Bez źródła jako wejścia trudno byłoby zdefiniować działania wewnątrz pętli; bez rozszerzenia czasu kompilacji byłoby to zbyt wolne; i bez generowania kodu nie byłby wykonywalny.

Innym dobrym przykładem jest rozdział o serializacji binarnej w Practical Common Lisp , Practical: Parsing Binary Files .

Makro zapytania, które implementuje coś podobnego do LINQ, może być kolejną dobrą aplikacją. Ale brakowałoby automatycznego uzupełniania, które sprawia, że ​​LINQ jest tak przyjemny, jak jest. Niemal wszystko, co dziś rozwiązują generatory kodu specjalnego przeznaczenia z wejściami XML (np. XAML), można również zaimplementować przy użyciu makr Lisp.

Patrick
źródło
Właśnie kupiłem książkę „Practical Common Lisp”, przyjrzę się przykładowi, który zasugerowałeś.
Giorgio
2

Lubię myśleć o makrach we wspólnym lisp, ponieważ są to funkcje zwracające kod do oceny, ale „nie” oceniają swoich argumentów przed zwróceniem tego kodu. Funkcje też coś zwracają, ale oceniają każdy argument przed oszacowaniem jego ciała. Makra nie.

Paul Graham w „On Lisp” dostarcza (IMHO) jeden z najlepszych opisów różnic między makrami i funkcjami oraz omawia ich nakładanie się i wyjątkowość. Wiele bitów kodu można zapisać jako funkcję lub makro, ale w niektórych przypadkach działa tylko makro. Kiedy już to obejmiesz, myślę, że masz sedno makr w lisp.

Jako przykład makra, w którym funkcja nie będzie działać, sprawdź „aif” (anaforyczny jeśli). To tylko kilka linii kodu i moje zalecenie, od czego zacząć.

I odwołaj się do anaforycznej wersji Common Lisp, jeśli korzysta ona z celowego przechwytywania zmiennych. Automatycznie higieniczna wersja programu nie jest IMO „prawdziwą okazją”. Przechwytywanie zmiennych jest ważną częścią makrologii lisp, a niektóre z bardziej wydajnych i użytecznych makr na pewno z niej korzystają.

Clayton Stanley
źródło