Можно ли жить без препроцессор директив условной компиляции (вроде #if)?
Предположим, что язык о котором идет речь снабжен мощной микросистемой работающей на синтаксическом уровне (т.е. макросами Немерла, или если хотите Лиспа).
Другими словами в языке возможна условная компиляция на основе применения атрибутов и специальных макросов.
Разница с перпроцессорными аналогами заключается только в том, что макросы не могут "рвать" синтаксис. Например, мы не сможем сделать нечто вроде:
#if XXX
class
#else
struct
#endif
MyType
{
}
Но сможет сделать нечто вроде:
[if(XXX)]
class MyType
{
}
[if(!XXX)]
struct MyType
{
}
Откровенно говоря мне всегда не нравился препроцессор. Вот думаю реально ли отказаться от него полностью?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
N>>В Java нет препроцессора, так что, видимо, можно
VD>К сожалению я Яву практически (для реальной работы) не использовал. Интересно не вызывает ли это негативных эмоций у программистов?
Про массовые возмущения не слышал. В Scala его тоже нет, хотя она разрабатывалась с учётом опыта Java.
Мое личное мнение: препроцессор — это зло, даже в такой ограниченной форме, как в C#. Он способствует тому, чтобы смешивались разные уровни абстракции. Кому это очень надо, пусть прикручивает специализированные текстовые препроцессоры/шаблонизаторы поверх компилятора на свой страх и риск. Правила языка ради этого усложнять не стоит.
Здравствуйте, VladD2, Вы писали:
VD>Можно ли жить без препроцессор директив условной компиляции (вроде #if)?
Если макросами (а, например, как? — можешь показать?) можно будет реализовать функционал ConditionalAttribute (или предложить достойную или даже лучшую альтернативу), то жить ещё как можно будет.
Иногда, конечно, хочется воспользоваться (и иногда пользуется), но это всё от лукавого и было бы лучше капельку подумать и переписать без #if-ов, так что писать код будет лучше.
Самое полезное, что есть в таких дериктивах — #if 0, но это тоже так или иначе решаемо.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, VladD2, Вы писали:
VD>К сожалению я Яву практически (для реальной работы) не использовал. Интересно не вызывает ли это негативных эмоций у программистов?
Лично у меня отсутствие препроцессора вызывает только положительные эмоции. Так как стимулирует иметь нормальную архитектуру, а не городить костыли. Прекрасно препроцессор заменяет выделение абстрактного универсального слоя, а реализация уже под конкретные нужды. В том числе и на этапе сборки, когда в билд попадает только заточенный под конкретные нужды код.
На деле, условную компиляцию можно эмулировать, кстати. Обычными условиями, в качестве условия — какой то параметр (константа или значение конфига). Вот только плохая это практика.
Здравствуйте, elmal, Вы писали:
E>Лично у меня отсутствие препроцессора вызывает только положительные эмоции. Так как стимулирует иметь нормальную архитектуру, а не городить костыли.
Согласен. Потому тему и создал. Просто я уже сто раз сталкивался с решениями которые мне нравятся и кажутся очевидными, но не принимаются большинством сообщества. А языки ведь они не для себя лично проектируются (точнее не только для себя).
E>На деле, условную компиляцию можно эмулировать, кстати. Обычными условиями, в качестве условия — какой то параметр (константа или значение конфига). Вот только плохая это практика.
Ага. Но есть одно "но". Все это возможно только при условии, что условия не разрывают синтаксис (как я привел в примере с классом и структурой).
Вот, собственно, и интересно. Насколько народ считает необходимым такие вот разрывающие синтаксис условия? Потому как если они не нужны, то от чистого препроцессора можно легко отказаться.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, _FRED_, Вы писали:
_FR>Если макросами (а, например, как? — можешь показать?) можно будет реализовать функционал ConditionalAttribute (или предложить достойную или даже лучшую альтернативу), то жить ещё как можно будет.
ConditionalAttribute само собой разуется. Но можно и большее сделать. Скажем если сделать синтаксический макрос вида:
macro CompileIf(condition, expression, elseExpression = <[ () ]>) // по умолчанию возвращаем void-литерал, т.е. "ничего"
{
if (EvalEnvVar(condition))
expression
else
elseExpression
}
Тогда в коде мы можем писать нечто вроде:
CompileIf(DEBUG, DebugStaff());
или
CompileIf(DEBUG, DebugStaff(), ReleaseStaff());
Естественно, что этому делу можно будет даже синтаксис приделать (даже такой: #if ... #else ... #endif).
_FR>Иногда, конечно, хочется воспользоваться (и иногда пользуется), но это всё от лукавого и было бы лучше капельку подумать и переписать без #if-ов, так что писать код будет лучше.
_FR>Самое полезное, что есть в таких дериктивах — #if 0, но это тоже так или иначе решаемо.
Вот-вот. Потому я и думаю не было бы разумнее отказаться от тестуальных #if в пользу синтаксических?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
_FR>>Если макросами (а, например, как? — можешь показать?) можно будет реализовать функционал ConditionalAttribute (или предложить достойную или даже лучшую альтернативу), то жить ещё как можно будет.
VD>ConditionalAttribute само собой разуется. Но можно и большее сделать. Скажем если сделать синтаксический макрос вида:
… VD>Тогда в коде мы можем писать нечто вроде:
VD>CompileIf(DEBUG, DebugStaff());
А "DEBUG" Можно будет брать из настроек проекта (то есть параметров компилятора)? Собсно это и интересовало: возможность из макроса узнать, с какими параметрами был запущен компилятор, в частности, был ли указал символ DEBUG.
_FR>>Иногда, конечно, хочется воспользоваться (и иногда пользуется), но это всё от лукавого и было бы лучше капельку подумать и переписать без #if-ов, так что писать код будет лучше. _FR>>Самое полезное, что есть в таких дериктивах — #if 0, но это тоже так или иначе решаемо.
VD>Вот-вот. Потому я и думаю не было бы разумнее отказаться от тестуальных #if в пользу синтаксических?
Было бы. Если не страшит то, что у некоторых программистов может случиться "ломка" из-за отсутствия #if Но это я шучу: конечно, если в самом языке нет ничего такого, для чего был бы необходим #if то от него надо избавляться.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>А "DEBUG" Можно будет брать из настроек проекта (то есть параметров компилятора)? Собсно это и интересовало: возможность из макроса узнать, с какими параметрами был запущен компилятор, в частности, был ли указал символ DEBUG.
Естественно. Доступны все опции компиляции. Например, так можно узнать объявлен ли символ DEBUG:
when (typer.Manager.Options.IsConstantDefined("DEBUG"))
...
Так же можно добавить свои символы или удалить имеющиеся.
_FR>Было бы. Если не страшит то, что у некоторых программистов может случиться "ломка" из-за отсутствия #if Но это я шучу: конечно, если в самом языке нет ничего такого, для чего был бы необходим #if то от него надо избавляться.
Вот мне и интересно насколько народу дорги текстуальные макросы.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Можно ли жить без препроцессор директив условной компиляции (вроде #if)?
Если мне не изменяет склероз, макросы в C/C++ применяются для двух вещей:
1. Платформозависимый код.
2. Рефлекшн (ASSERT/VERIFY: __FILE__, __LINE__, __ЖОПА__)
Соответственно, если у нас бейсик — платформонезависимый и со встроенным рефлекшн — то макросы нам как бы нафиг не нужны.