Чи розширюються макроси, коли файл компілюється?


13

У мене є макрос, який потрібно розширювати в кожному окремому екземплярі часу його використання. Чи є спосіб, який я можу вказати, щоб це було так, не переходячи до кодової бази та обережно завершуючи кожен виклик eval-when-compile?

Відповіді:


13

Усі макроси, доступні компілятором байтів, розгортаються під час компіляції. "Доступний" по суті означає, що його не котирують.

Тіло defuns, defmacros, lambdas - всі байтові компільовані, коли вихідний файл, який їх містить, компілюється в байті. Так, так, будь-який макрос всередині них буде розширений, якщо вони не знаходяться всередині цитати ( '). Дуже поширеною помилкою є загортання lambdas у цитату, і насправді саме тому ви ніколи неlambda повинні цитувати своїх s .

Це одна з головних переваг макросів, якщо вони добре написані, вони не впливають на продуктивність виконання. Інша перевага - це, звичайно, їх потужність і універсальність. Недоліком є ​​те, що ви маніпулюєте синтаксисом, а не предметами, тому є багато місця для проблем, деякі несподівані, інші неминучі.


7

Як уже пояснила Малабарба, макроси розгортаються під час збирання байтів. Якщо файл не компілюється, макроси розгортаються при завантаженні файлу (охоче розширення макросу).

Але не покладайтеся на це. Це дуже поганий стиль. Як правило, ви не можете очікувати, що код, який використовує ваш макрос, насправді компілюється, і вам слід, як правило, запустити якомога менше коду під час компіляції. Зокрема, використовуйте макроси мало, і лише якщо іншого способу немає. Як правило, використовуйте макроси лише для синтаксису та ніколи для семантики (або функціональності).

Макроси - це герметична абстракція. Їх розширення жорстко закодирується в цільовий код під час компіляції і не може бути змінено заднім числом. Цільовий код згодом залежить від конкретної реалізації макросу під час розширення. Конкретно, це залежить від усіх внутрішніх API, що використовуються в тілі макросів.

Отже, ви не можете змінити будь-який з цього API чи будь-що, на що покладається розширення макросу, не порушуючи жодного коду, який був складений проти вашого макросу.

Ліберальне використання макросів для функціональності прокладає шлях до пекла залежності .


Дуже хороші моменти, які слід пам’ятати під час написання чи використання макросів.
Шон Алред

"Ліберальне використання макросів для функціональності прокладає шлях до пекла залежності". До тижня тому пакет.el мав помилку, яка повністю порушила встановлення пакета в цілком законних ситуаціях з макрозалежністю.
Малабарба

@Malabarba Care для надання деталей?
місячник

@lunaryorn Ось ви йдете . Неприємне маленьке питання.
Малабарба

1
@lunaryorn Я погоджуюсь, що макроси небезпечні (я навіть відредагую свою відповідь, щоб звучати менш похвально :), але я не думаю, що ця помилка була її специфічним примірником. Цей помилок мав інші (менш обтяжуючі) прояви, які взагалі не стосуються макросів. Це також спричинило проблеми з функціональними залежностями.
Малабарба
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.