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
?
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
?
Odpowiedzi:
Wszystkie makra osiągalne przez kompilator bajtów są rozszerzane podczas kompilacji. „Osiągalny” oznacza w zasadzie brak cytowania.
Treść defun
s, defmacro
s, lambda
s 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 lambda
s w środki i, w rzeczywistości, dlatego należy nigdy zacytować swoje lambda
s .
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.
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 .