типобезопаснось на этапе кодогенерации одно из основных отличий шаблонов С++ от макросов С

Preprocessor macros are textual, not lexical or syntactic, which means that small changes in a macro may result in the entire file needing to be reanalyzed.
https://people.eecs.berkeley.edu/~harmonia/harmonia/help-wanted.html#preproc
1) код работающий с моделью текста
2) код работающий с лексемами
3) код работающий с синтаксическим деревом
4) код работающий с объектной моделью программы (семантическая модель, как в .net с языковыми сервисами)
5) код работающий с выходным кодом (типа Reflection.Emit)

Две фазы - препроцессирование и компиляция мешают правильно раскрашивать синтаксис в редакторе? Получается надо делать ещё одну грамматику специально для раскрашивания.

Хотелось бы понимать, как работает лисповый препроцессор.
what a macro is. It is a transformation perfomed on code by code. That is, a piece of code, read by the interpreter (or compiler), which takes in code as an argument, manipulates and the returns the result, which is then run in place.
You have a mechanism, or a paintbrush, if you like. You can have any syntax you could possibly want. Like Python or C#'s with syntax. Or .NET's LINQ syntax. In end, this is what attracts people to Lisp - ultimate flexibility.
http://stackoverflow.com/questions/2678 … so-special
http://stackoverflow.com/questions/1104 … ns-for-net

https://www.linux.org.ru/forum/development/2968062
Лисповское метапрограммирование не только со списками работает, его и просто к строкам можно применять.
В лиспе МП имеет полный доступ ко всей инфраструктуре. Т.е., во время компиляции можно делать ровно всё то же, что и во время выполнения программы (т.к. компиляция - это тоже выполнение программы). Ограничения имеются на результат вычисления и на доступную информацию о компилируемой программе, но не на само вычисление. В частности, я могу запросить пользователя во время компиляции, вызвать внешнюю программу, обратиться к любым структурам данных, описывающим конфигурацию.
"Огромная польза лиспа - это &key, &optional, &body (негигиеничные макросы)."

Лисп как минимум знают все образованные программисты. Пользуются им тоже многие, причем чем выше квалификация, тем выше вероятность, что человек будет Лиспом пользоваться. Поставишь элитистский фильтр выбором языка - и как минимум за качество участников проекта можешь быть спокоен.

кто-то (Бог, Сатана, просто Боги во множественном числе, масоны, мировое правительство, жречество, халдеи, вампиры) специально делает так, чтобы не было единого полноценного языка программирования, а взамен этого было много ущербных. Тогда каждый программист, исходя из своих склонностей, будет чем-то жертвовать ради чего-то и выбирать свой язык. И будет гарантированно сохраняться видовое разнообразие языков, изоморфное многообразию складов ума.

у лиспа как промежуточного представления для "платформы", есть самостоятельная ценность.

христианская модель из всех известных моделей почему-то имеет наибольшую предсказательную силу (число зверя/большой брат).

https://www.linux.org.ru/forum/development/3089666

лисповые макры имеют по сути две операции: квотинга, откладывания вычислений на момент исполнения и форсирования вычисления во время компиляции, то есть во время работы макры.
Синтаксиса фактически нет, есть правило: 1) корректная лисп-форма, то есть первый элемент списка -- символ 2) макрами можно поменять порядок вычислений, сохраняя структуру.
За счёт того, что список имеет однородную структуру, макра применима к любому элементу списка. Если список -- это вектор или тьюпл из разных типов, то операция "вычислить элемент списка во время компиляции = время исполнения макры" может быть не применима к этому типу.
В целом нужен какой-то интерфейс, обрабатываемый во время компиляции, какая-то алгебра типов (в смысле, замкнутое кольцо) и обработка AST.
И синтаксис не помешает (если в конечном итоге всё равно однородно обрабатывается). Лисп не имея операций для обработки структур имеет простую "алгебру" вида car/cdr/cons , когда нужно что-то уровнем выше, вроде регэкспов и паттерн матчинга. Можно реализовать на самом лиспе.
https://www.linux.org.ru/forum/developm … id=3109013

http://metalua.luaforge.net/

Десять причин избегать метапрограммирования
   http://eax.me/avoid-metaprogramming/
1) трудно представить или даже специально придумать задачу, которую невозможно решить без макросов.
3) никто не отменял обычную кодогенерацию. Возможно, просто у вас фиговая система сборки или IDE.
4) интеграция в отладчик. Допустим, код, полученный с помощью шаблонов или макросов, бросит исключение. Какие номера строк вы увидите в стэктрейсе? Сможете ли вы легко разобраться в проблеме и исправить ее, особенно, если проблемный код написан кем-то другим?
5) сложности с раскраской. IDE нужно иметь встроенный интерпретатор вашего языка программирования
6) дублированный код почти всегда можно вынести в отдельные методы. Или параметризовать различающиеся части, передав лямбду.

Генераторы имеют те же проблемы и несколько своих. :)
2. Код для генератора пишется на каком-то другом языке (типа M4) - не всегда тривиальном и очевидном. Который не знают или не до конца понимают большинство ваших коллег.

парсинг например. Для С++ есть http://boost-spirit.com/home/ Повзоляет описать парсер непосредственно в коде, с помощью expression templates. Абсолютно обыденная вещь для любого квалифицированного С++ программиста (например property_tree использует spirit для парсинга json-ов всяких). Генерирует очень быстрые парсеры, так как оптимизатор инлайнит все что только возможно.

6. Макросы не призваны решать только и не столько проблему DRY. Это естественная адаптация минималистичного core-языка под задачу.
Макросы - это всего-лишь DSL времени компиляции.

в ЯП, строящих синтаксис на макросах (Clojure, например), макросы - first class citizens, и естественны. В языках, где макросы сложны, неестественны (например, работают на уровне препроцессора или байткода) и инородны - макросов лучше избегать.

В твоем языке есть макросы, но
1) Нет строковой интерполяции - у тебя есть строковая интерполяция благодаря макросам
2) Нет try-with-resources/using - у тебя есть using благодаря макросам
3) Нет yield return - у тебя есть yield return благодаря макросам
4) Нет нормального async/await, но есть дурацкие коллбеки - у тебя есть async/await благодаря макросам.
5) Нет возможности определить тип по твоему специфичному шаблону (и наследование не решает проблему) - у тебя есть такая возможность благодаря макросам.
6) Нет паттерн матчинга - есть паттерн матчинг благодаря макросам.
7) В языке нет статической проверки типов? Можно скрутить себя в ежа и сделать поддержку статической проверки типов с крутым автовыводом.
8) Ты хочешь описывать решения своих задач максимально выразительно? Да здравствуют макросы.

За исключение пункта 7, вышеперечисленное выполняется с помощью лености и функций высших порядков.
Функции высших порядков это мило, но это есть оверхед в рантайме.
и это не лечится оптимизирующим компилятором, как можно снизить асимптотику алгоритма, но не заиметь проблемы интеграции с отладчиком?

Помимо моды к коду может предъявлять ещё ряд требований. Например читабельность для экспертов, производительность, документированность..
Всё можно сделать на ассемблере вопрос в цене.

https://bitbucket.org/brianritchie/wiki/wiki/.NET Languages
LISP
    clisp (Microsoft) - http://weblogs.asp.net/jtobler/archive/ … 30000.aspx
    DotLisp (Rich Hickey) - http://www.richhickey.com/dotlisp.htm
    L# (L Sharp .NET) (Rob Blackwell) LISP-based script language - http://www.lsharp.org/
    FOIL (Rich Hickey and Eric Thorsen) - http://foil.sourceforge.net/
    RDNZL (Edi Weitz) .NET Layer for Common Lisp - http://www.weitz.de/rdnzl/

Отредактировано Лис (2017-05-08 12:30:04)