Пожалуй, надо все-таки написать свои впечатления от книжки, пока не забыл еще =)
Итак, книженция о макросах
Let Over Lambda от Doug Hoyte.
Кто вообще такой этот Hoyte и чем знаменит? Ну, это тот мужик, который напрограммировал
Antiweb. Собственно, больше я про него не знаю, но antiweb доказывает, что лисп он знает, как минимум, очень хорошо :)
По моему мнению, книжка получилась скорее пропагандистская, нежели информационная :) На каждую единицу технической информации и пример, идет достаточно обширный абзац в стиле: "Ох ну нихера себе, да вы только посмотрите насколько крут CL!!". Что самое интересное, в итоге он меня в этом убедил =)
Основные тезисы в Let Over Lambda, которые автор норовит донести до читателя, можно обобщить так:
1. Не бойтесь использовать язык в полную силу.
2. Не цепляйтесь за т.н. "code conventions", они бесконечно ограничивают мощь CL.
3. Duality of syntax (одинаково написаный код может делать совершенно разные вещи) -- это не зло, а потрясающее удобство.
4. Anaphoric macros (макры, которые инжектят новые переменные в код) -- это не зло, а совершенно чудовищная в своей полезности штука.
5. "Only use macros when a function won't do" -- фатальное заблуждение. Макры -- это основополагающая вещь.
В общем, текст достаточно серьезно бьет по мировоззрению :) Боюсь, если читать его будет действующий джава-программист со стажем, то смысла особого не выйдет.
Вообще, в книжке, в основном, несколько слабые демонстрационные примеры. Я успел прочитать уже добрую половину, прежде чем въехал, что именно пытается донести автор. Я как-то всегда рассматривал макросы с точки зрения экономии строчек кода, code reuse там и пр. Видимо, это у меня засело в башке еще со времен Си и #define. Тоесть, паттерн такой: чтобы не писать что-то большое руками, напиши макро, который сделает за тебя большую часть работы.
Но я как-то даже не представлял, насколько могущественна связка макро с тем самым древовидным лисповым синтаксисом =) По-сути, у нас в полном подчинении находится компилятор. И если в Си я как-то привык всегда чувствовать корреляцию между тем, что я пишу в коде и тем, какой получится ассемблерный листинг (с точностью до оптимизаций вроде инлайна, tail-call и пр.), то в красиво написанном коде на лиспе такой корреляции провести уже совсем нельзя: между кодом "высокого уровня" и получившимся ассемблером могут быть десятки macroexpansion'ов, которые могут, напрмер, вообще превратить код в NOP.
Очень хороший пример был приведен с CL-PPCRE. И в самом деле, одна и та же регулярка в си будет работать в два с половиной раза медленней, чем в CL-PPCRE. За счет чего, казалось бы -- язык си намного более низкоуровневый, чем CL? Дело в том, что си будет интерпретировать регулярку в рантайме, а CL-PPCRE в процессе компиляции напишет эквивалентный регулярке лисповый код, и уже его скомпилирует в ассемблер.
B этом, я считаю, CL уходит в бесконечность от всех mainstream-языков. И действительно, в любом большом приложении всегда можно найти сотни и тысячи интерпретаций каких-то статических данных в рантайме. Все эти lookup-таблицы, километровые swich-case'ы по enum'ам, фабрики классов, исследования битов в масках -- все это можно и нужно заменить грамотными макросами, которые в требуемых местах раскроются в точное количество необходимого кода.
Ну да ладно. Из интересного еще стоит отметить главу про reader macros (я узнал много нового) и главу про оптимизацию перфоманса. Хотя его макра, которой он больше всего гордится (sortf) ничего особенного не представляет, я так тоже могу:
http://swizard.livejournal.com/82912.html =)
Кроме того, веселят постоянные попытки холивора, особенно в конце (Appendices) =) И по схеме прошелся, и даже емакс(!) опустил. Ну да пусть это останется на его совести.
В общем, must read.
PS: да, из минусов -- отвратительный формат самой книги в позорной мягкой обложке