Czy makra są rozwijane podczas kompilacji pliku?

13

Mam makro, które należy rozszerzyć przy każdym wystąpieniu jego kompilacji w czasie kompilacji. Czy istnieje sposób, aby to określić, bez konieczności przeglądania bazy kodów i ostrożnego zamykania każdego połączenia eval-when-compile?

Sean Allred
źródło

Odpowiedzi:

13

Wszystkie makra osiągalne przez kompilator bajtów są rozszerzane podczas kompilacji. „Osiągalny” oznacza w zasadzie brak cytowania.

Treść defuns, defmacros, lambdas są kompilowane bajtowo, gdy plik źródłowy, który je zawiera, jest kompilowany bajtowo. Tak więc, każde makro wewnątrz nich zostanie rozwinięte, o ile nie będzie w cudzysłowie ( '). Bardzo częstym błędem jest okład lambdas w środki i, w rzeczywistości, dlatego należy nigdy zacytować swoje lambdas .

Jest to jedna z wielkich zalet makr, o ile są one dobrze napisane, nie mają wpływu na wydajność środowiska wykonawczego. Inną zaletą jest oczywiście ich moc i wszechstronność. Wadą jest to, że manipulujesz składnią, a nie obiektami, więc jest dużo miejsca na problemy, niektóre nieoczekiwane, a inne nieuniknione.

Malabarba
źródło
7

Jak już wyjaśnił Malabarba, makra są rozwijane podczas kompilacji bajtów. Jeśli plik nie zostanie skompilowany, makra są rozwijane po załadowaniu pliku (chętne rozwijanie makr).

Ale nie polegaj na tym. To bardzo zły styl. Zasadniczo nie można oczekiwać, że kod, który korzysta z makra, jest w rzeczywistości kompilowany, i podczas kompilacji należy generalnie uruchamiać jak najmniej kodu . W szczególności rzadko używaj makr i tylko wtedy, gdy nie ma innej możliwości. Z reguły makra należy używać tylko do składni , a nigdy do semantyki (lub funkcjonalności).

Makra to nieszczelna abstrakcja. Ich rozszerzenie jest na stałe zakodowane w kodzie docelowym w czasie kompilacji i nie można go zmienić retrospektywnie. Kod cel następnie zależy na realizacji konkretnego makra w czasie rozprężania. W szczególności zależy to od wszystkich wewnętrznych API używanych w treści makra.

W związku z tym nie można zmienić żadnego z tych interfejsów API ani czegokolwiek, na czym polega rozwinięcie makra, bez zerwania kodu skompilowanego z makrem.

Liberalne wykorzystanie makr dla funkcjonalności toruje drogę do piekła zależności .

księżycowy
źródło
Bardzo dobre uwagi, o których należy pamiętać podczas pisania lub używania makr.
Sean Allred,
„Liberalne wykorzystanie makr dla funkcjonalności toruje drogę do piekła zależności”. Jeszcze tydzień temu pakiet.el miał błąd, który całkowicie zepsuł instalację pakietu w całkowicie uzasadnionych sytuacjach zależności makro.
Malabarba
@Malabarba Chcesz podać szczegóły?
lunaryorn,
@lunaryorn Proszę bardzo . Paskudny mały problem.
Malabarba
1
@lunaryorn Zgadzam się, że makra są niebezpieczne (nawet zmienię swoją odpowiedź, aby brzmiała mniej pochwalnie :), ale nie sądzę, że błąd był konkretnym tego przykładem. Ten błąd miał inne (mniej obciążające) przejawy, które w ogóle nie dotyczą makr. Powodowało to również problemy z zależnościami funkcji.
Malabarba,