LINUX.ORG.RU

m4 как препроцессор для С?


0

0

Добрый день!

Кто-нибудь использовал m4 в качестве препроцессора для программ, написанных на С/C++? Я сам пользовался и мне понравилось, но, поскольку работа была в команде, остальные товарищи меня не поняли и пришлось от этой идеи отказаться.

Если сами не использовали, может быть, видели, где используется.

Да, я знаю, что он используется где-то в сборке или конфигурации, но меня интересует использование m4 для препроцессирования именно кода, вместо #define и плюсовых шаблонов. И не в целях конфигурирования, а в целях сокращения объёма кода и улучшения читабельности, т.е., как в лиспе.

Хочется узнать, насколько такой подход популярен, т.к. предстоит кое-кого убеждать в целесообразности применения m4.

Особенно интересны примеры применения m4 совместно с GObject. Сам я в GObject покуда не разбирался, мне сказали, что для наследования там нужно изрядно поработать текстовым редактором. Надеюсь устранить эту неприятность с помощью m4. Наверняка я не первый, кто это придумал.

Может быть, m4 уже не в моде и есть для этой цели что-то покруче.

Короче, комментарии приветствуются. Прошу только одного - не предлагайте мне С++

★★★★★

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

generatorglukoff ★★
()

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

imp ★★
()

> m4 в качестве препроцессора для программ, написанных на С/C++? Я сам пользовался

> вместо #define и плюсовых шаблонов.

> не предлагайте мне С++

Что-то здесь не стыкуется %)

Генератор прав, но вот шаблоны Си++ препроцессором не заменить.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>шаблоны Си++ препроцессором не заменить

почему ? если рассматривать их применение для метапрограммирования, т.е. по сути кодогенерации - в чём существенная разница ?

jtootf ★★★★★
()

ммм... а можно конкретный пример с описанием того, как это используется? а то как то больно размыто получается.

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от jtootf

>> шаблоны Си++ препроцессором не заменить

> почему ?

Потому что m4 вообще не учитывает типов, не говоря уже о concept'ах нового стандарта Си++.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> Потому что m4 вообще не учитывает типов, не говоря уже о concept'ах нового стандарта Си++

А с какого бодуна (любая) замена шаблонов C++ должна учитывать типы, или тем более соотвествовать новому стандарту C++?..

anonymous
()
Ответ на: комментарий от anonymous

>> Потому что m4 вообще не учитывает типов, не говоря уже о concept'ах нового стандарта Си++

> А с какого бодуна (любая) замена шаблонов C++ должна учитывать типы

Это столько слов для выражения простой мысли "А меня m4 устраивает"? Устраивает - пользуйся.

Специально для тебя - _любая_ замена шаблонов Си++ ничего никоиу не должна.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Да нет, шаблоны С++ неудобны и ограничены. Особенно раздражает то, что их выдают за средство языка, хотя это типичный препроцессор, и люди пытаются засунуть это в разделяемые библиотеки и ломают ноги. Плюс еще раз говорю, возможностей шаблонов сильно не хватает.

anonymous
()
Ответ на: комментарий от tailgunner

Да... Опять пошёл спор вокруг С++. Ну, раз уж вопрос 
поставлен, то шаблоны в С++ - это частный случай макроподстановки. 

Например, 

template<T> class vector { T element; ... }; 
и дальнейшее применение

void foo() { 
  vector<int> s; 
}

можно заменить примерно такими двумя макросами

#define VECTOR(T) template_vector_ ## T
#define IMPLEMENT_VECTOR(T) class VECTOR(T) { T element; ... }; 

и далее

IMPLEMENT_VECTOR(int)
void foo() {
  VECTOR(int) s; 
}

Т.е., основной функционал шаблонов вполне можно реализовать даже в 
рамках С-шного препроцессора. Если код С++ с каким-то 
неподходящим типом не скомпилируется, то и код данного 
макрорасширения тоже не скомпилируется. Возможно, в С++ чуть больше
проверок, но мне они не нужны. 

С другой стороны, есть очень простой макрос, который 
невозможно заменить ни функцией, ни классом, ни шаблоном. Его можно 
сделать только макросом. 

Допустим, есть несколько 
функций API и каждая из них возвращает 0 в случае успеха и 
код ошибки в случае ошибки. 

Тогда имеет смысл макрос (обычный С макрос)

#define call_checked(call,message) \
  errorCode=call; if (errorCode) { \
    printf("error %s, code %d\n", message,errorCode); \
    return errorCode; \
  }

Вот это, кстати, и пример для klalafuda. Шаблоны тут, очевидно, 
ничем не помогут. m4 может ещё намного больше. 

Ну так как насчёт моего вопросика? Кто-нибудь что-нибудь напишет аль нет? 

den73 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

> Да нет, шаблоны С++ неудобны и ограничены.

А m4 - удобен и неограничен?

> Особенно раздражает то, что их выдают за средство языка, хотя это типичный препроцессор

Словесные игры.

> Плюс еще раз говорю, возможностей шаблонов сильно не хватает.

Верю. Если бы ты привел пример, поверил бы еще больше %)

tailgunner ★★★★★
()
Ответ на: комментарий от den73

> Да... Опять пошёл спор вокруг С++

Причем начался он с твоего поста.

> Ну, раз уж вопрос поставлен, то шаблоны в С++ - это частный случай макроподстановки.

Хм, это ответ на какой вопрос? И почему макроподстановки, а не какого-нибудь лямбда-исчисления или машины Тьюринга?

> Ну так как насчёт моего вопросика? Кто-нибудь что-нибудь напишет аль нет?

Вряд ли. Мысль приходила в голову многим, но, я так думаю, обычно отбрасывалась как химера.

tailgunner ★★★★★
()
Ответ на: комментарий от den73

Идея хорошая, только будь осторожен ;)

Some people find m4 to be fairly addictive. They first use m4 for simple problems, then take bigger and bigger challenges, learning how to write complex sets of m4 macros along the way. Once really addicted, users pursue writing of sophisticated m4 applications even to solve simple problems, devoting more time debugging their m4 scripts than doing real work. Beware that m4 may be dangerous for the health of compulsive programmers.

anonymous
()
Ответ на: комментарий от anonymous

Анонимус, можно заиграться чем угодно. Я понимаю, о чём идёт речь, в принципе, подвержен этому недугу. По правде говоря, я не считаю m4 идеальным средством. Убогенькое оно, на самом деле и с масштабированием у него действительно есть проблемы. Потому и вопрос возник - кто применяет, где, и есть ли что-нибудь лучше. На самом деле, я сам видел ещё один макропроцессор, но он мне показался хуже m4.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

>я сам видел ещё один макропроцессор, но он мне показался хуже m4.

Конечно, ведь m4 написали Ъ Керниган и Ритчи.

anonymous
()
Ответ на: комментарий от tailgunner

>> Плюс еще раз говорю, возможностей шаблонов сильно не хватает.

>Верю. Если бы ты привел пример, поверил бы еще больше %)

1) Раздельное компилирование 2) ABI

Эти два фактора отправляют C++ шаблоны в топку моментально и безусловно.

Absurd ★★★
()
Ответ на: комментарий от tailgunner

Ну как, смотри топик. Для упрощения создания GTK классов шаблоны не помогут.

anonymous
()
Ответ на: комментарий от den73

>#define call_checked(call,message) \
>  errorCode=call; if (errorCode) { \
>    printf("error %s, code %d\n", message,errorCode); \
>    return errorCode; \
>  }

Именно для этого в C++ придумали exception'ы.

Я как-то пытался использовать m4 в одном из своих проектов на C++, но
впоследствии та задача, для которой я его применял, оказалась не нужна,
поэтому я его выкинул. В целом было довольно неудобно, потому что
редактировать надо было один файл, а компилятор выдавал ошибки с
номерами строк в другом файле.

Jini ★★
()

Каждый программист в своей жизни хотя бы раз придумал свой никому больше не понятный язык. Ты на верном пути ;-)

alexsaa
()

Вот пример: m4 используется в autoconf для генерации shell-скриптов (которые "configure"). Писать autoconf-скрипты геморно, опыт применения m4 скорее неудачный.

anonymous
()
Ответ на: комментарий от alexsaa

> В целом было довольно неудобно, потому что редактировать надо было один файл, а компилятор выдавал ошибки с номерами строк в другом файле.

Вопрос с номерами строк решается, хотя я не скажу, что он решается совсем красиво. В m4 и С для этого есть средства. В частности, у меня был переключатель, который мог по выбору показывать номера строк от исходного файла (до m4) или от обработанного файла (после m4). Не сказать, что это снимает проблему полностью, но сильно её облегчает. Сейчас не полезу за примерами, они где-то в архиве на CD-ROM. Но если действительно интересно, могу слазить завтра.

> Именно для этого в C++ придумали exception'ы. Это был всего лишь один пример. И даже тут возражение не вполне убедительно. Например, в Symbian исключения не поддерживаются. Сейчас не могу слёту придумать ситуацию, когда нужен не return, а что-то другое, хотя такие ситуации тоже бывают.

Но вот ещё пример из другой области

RegisterFunction(myProc,"myProc");

Каждый, кто хоть раз пытался встроить интерпретатор, поймёт, что я написал.

И ясно, что даже #define заметно облегчает жизнь (а С++ курит в сторонке).

А вот и ещё один пример, убойный и для С++, и для #define

Инициализация полиморфных и структурно неоднородных контейнеров. В лиспе можно написать вот так: '(a "bc" (1 2)) что означает

list(intern("a"),"bc",list(1,2))

или, в конечном итоге,

cons(intern("a"),cons("bc",cons(cons(1,cons(2,NIL)),NIL)))

Возникает море проблем при попытке хоть как-то воспроизвести эту возможность средствами С/С++. Засада со всех сторон: и количество аргументов переменное, и типы их разные. То есть, "хоть как-то" лисповую запись воспроизвести можно, но как сделать хорошо - я до сих пор не знаю. С помощью m4 эту проблему, скорее всего, можно решить достаточно вкусным способом.

den73 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

anonymous, не связана ли эта геморность с тем, что это нужно делать редко и поэтому не нарабатывается сноровка? Лично я никогда их не писал, поэтому спрашиваю.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

> А вот и ещё один пример, убойный и для С++, и для #define 

 #include "lisp/lisp.hpp"
 #include "lisp/lsymbol.hpp"
 #include "lfun_std.hpp"

 LSymbol ISOMORPHIC("ISOMORPHIC");

 static LFunctionalSymbol<LFunctionDefun> DEFUN("DEFUN");
 static LFunctionalSymbol<LFunctionCond> COND("COND");
 static LFunctionalSymbol<LFunctionAtom> ATOM("ATOM");
 static LFunctionalSymbol<LFunctionAnd> AND("AND");
 static LFunctionalSymbol<LFunctionCar> CAR("CAR");
 static LFunctionalSymbol<LFunctionCdr> CDR("CDR");

 LListConstructor L;

 void LispInit_isomorphic() {
   static LSymbol TREE1("TREE1");
   static LSymbol TREE2("TREE2");
   ////////////////////////////////////////////////
   //
   (L|DEFUN, ISOMORPHIC, (L|TREE1, TREE2),
     (L|COND, 
       (L|(L|ATOM, TREE1), (L|ATOM, TREE2)),
       (L|(L|ATOM, TREE2), NIL),
       (L|T, (L|AND,
         (L|ISOMORPHIC, (L|CAR, TREE1), 
                        (L|CAR, TREE2)),
         (L|ISOMORPHIC, (L|CDR, TREE1), 
                        (L|CDR, TREE2))
   )))).Evaluate();
   //
   ////////////////////////////////////////////////
 } 
 //      end of file

Well, this code is a complete C++ module and it does compile pretty well.

intelib.org

Legioner ★★★★★
()

еще существует cog. Он чемто удобней но тяжелый и медленный.

вобщем каждой задаче свой инструмент.

\\wbr cvv

anonymous
()
Ответ на: комментарий от den73

> Вопрос с номерами строк решается, хотя я не скажу, что он решается совсем красиво. В m4 и С для этого есть средства. В частности, у меня был переключатель, который мог по выбору показывать номера строк от исходного файла (до m4) или от обработанного файла (после m4). Не сказать, что это снимает проблему полностью, но сильно её облегчает. Сейчас не полезу за примерами, они где-то в архиве на CD-ROM. Но если действительно интересно, могу слазить завтра.

Необязательно, мне достаточно информации о том, что это возможно. Беглый поиск по ману m4 указал на опцию -s, насколько я понимаю, танцевать надо от неё. Спасибо за указание, если мне ещё придётся интегрировать m4 в проект, я это опробую.

> Инициализация полиморфных и структурно неоднородных контейнеров.

В принципе, в C++ эта задача решается через boost::tuple или mpl::vector (в C++0x что-то из них будет в стандартной библиотеке). Конечно, до изящности синтаксиса лиспа далеко, но C++ --- статически типизируемый язык, и типы всё равно надо где-то указывать, так что с этой точки зрения всё не очень ужасно.

Jini ★★
()
Ответ на: комментарий от den73

про autoconf - отчасти так, геморно по двум причинам: 1. Неизбежно всплывают детали синтаксиса m4. Сноровку в обращении с m4 я даже даром не возьму, жалко свободные нейроны в голове. 2. Макросы принимают параметры, а системы типов нет (всё как текст). При этом значения параметров даже стандартных макросов "плавают" от одной версии autoconf/automake к другой. 3. Улавливается общая волна отношения к autoconf/automake как к геморному костылю.

Поэтому я пишу только самые простые autoconf-скрипты, и не пишу свои макросы. Нечасто, да. Где-то штук 50 написал за всё время. Отдача есть. В cygwin, например, без проблем всё собирается, даже не пришлось разбираться в особенностях сборки всяких .dll.

anonymous
()
Ответ на: комментарий от Jini

> C++ --- статически типизируемый язык, и типы всё равно надо где-то указывать

Jini, я не соглашусь. Есть тип константы и тип переменной. Вполне понятно, что такое 123, 'a', "asdfasdf" или любое x, если ранее оно объявлено как myClass x. Т.е., они уже известны и почему я обязан указывать их ещё раз? Хотя, похоже, что я всё же обязан - ибо отсутсвует аналог лиспового type-of. Есть type_info, но оно отсутствует в том же symbian. Т.е., пока я хочу слить всё в один вектор вариантов, мне по барабану тип. А когда я хочу учесть тип, происходит проблема.

Ну и ещё - в этом векторе есть органичение на число элементов в 50 элементов. Славный вектор! Типичный С++! На первый взгляд, вроде бы всё круто, но при ближайшем рассмотрении оказывается картонными декорациями.

Ничто не мешает сделать столько перегруженных функций, сколько есть типов констант. Это основа, а дальше m4 поможет сделать запись почти такой же, как в лиспе, т.е., list(intern("a"),"bc",list(1,2))

Кстати, а что же делать в этом случае в чистом С? Неужели засада?

Ну и есть ещё один пример, когда темплейты не помогут - это когда нужно встроить разный текст в несколько разных мест. Видимо, это - как раз случай GObject.

Legioner, чтение этого кода вызывает ощущения, похожие на икоту, но в целом принимается. Хотя где-то я это уже видел. Это не croco ли случайно придумал? А будет ли работать сделанный в том же стиле '(a 1)?

Анонимус насчёт autoconf, видите, треть проблемы - это Ваше априори негативное отношение к m4, треть - это проблемы самого autoconf, и только оставшаяся треть - собственно особенности m4.

Короче, я окончательно прихожу к выводу, что нужно делать то, что я изначально и хотел:

Лисп с семантикой С, или, что то же самое, С с синтаксисом лиспа. При этом, информация о типе времени компиляции, равно как и всё МП времени компиляции, является ответственностью лиспа.

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

den73 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

В качестве замены/дополнения макропроцессора С можно использовать любой интрепретируемый язык общего назначения причом удобней взять те которые орентированы на работу с строками например perl, php и даже bash. При чем на уровне этих языков можно реализовать библиотеки кодогенирации неуступающие/соответствующие/превосходящие возможности шаблоидов и ООП С++. При этом если вы страдаете пароноидальной типопобезопасностью (распространеная болезнь кодеров С++) то это можно учесть в ваших библиотеках. Что касается M4 то он давольно популярен среди кодеров С, но назвать его удобным нельзя, скорее это костыль который можно быстро подставить когда количество дериктив макропрацессора в исходном коде переваливает за определеный критический предел.

ACR
()
Ответ на: комментарий от ACR

ACR, спасибо, а можно какие-нибудь примеры использования подобного подхода в мире open source? Вообще-то я пробовал заниматься МП на подобных языках, там начинаешь спотыкаться об эскейп-символы, меня это довольно быстро утомило и я бросил. Хотя, возможно, что Perl будет и ничего, благодаря возможностям ограничивать строки разными способами. Хотя Perl вообще не конфета...

den73 ★★★★★
() автор топика

[Глобально][Надёжно] А почему бы нет?

В качестве препроцессора PHP куда удобнее M4.

anonymous
()
Ответ на: [Глобально][Надёжно] А почему бы нет? от anonymous

А лисп наверняка ещё в 100 раз удобнее чего бы то ни было. Проблемы у меня только в том, что второй потенциальный участник проекта - не лиспер и его лисп малость пугает.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Привожу пример ситуации, когда чисто текстовое МП столкнётся с затруднениями: 
#define printf_anything(ident) \ 
  switch (typeof(ident)) { \ 
    case int: printf("%d",ident); break; \ 
    case double: printf("%f",ident); break; \ 
    default: compiler_error("unknown type"); \
} 

void foo() { 
  int i=1; 
  double j=2; 
  printf_anything(i); 
  printf_anything(j); 
} 

и это должно в итоге (в статике) превратиться в следующий код: 

void foo() { 
  int i=1; 
  double j=2; 
  printf("%d",i); 
  printf("%f",j); 
} 

Загвоздка - только одна: не существует такого (переносимого)
 оператора typeof, работающего в статике. 

В лиспе его сделать легко (фактически, он уже есть, т.к. есть FFI). В
PHP или m4 как его сделать, учитывая typedef возможность 
задать один и тот же тип разными способами и прочая? 

den73 ★★★★★
() автор топика
Ответ на: [Глобально][Надёжно] А почему бы нет? от anonymous

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

ACR
()
Ответ на: комментарий от den73

> Есть тип константы и тип переменной. Вполне понятно, что такое 123, 'a', "asdfasdf" или любое x, если ранее оно объявлено как myClass x. Т.е., они уже известны и почему я обязан указывать их ещё раз?

На практике (на моей во всяком случае) редко приходится вбивать константы в исходный код, поэтому я считаю это возражение несущественным.

Тем не менее, в целом я согласен, что синтаксис очень неудобен.

> Ну и ещё - в этом векторе есть органичение на число элементов в 50 элементов.

Увы, тут мне нечего сказать. Это не было заложено в C++ и вообще появление подобных возможностей достигнуто необычайными извращениями. Я не утверждаю, что такие вещи сделаны в C++ хорошо, просто указываю, что они, в какой-то степени, есть, и что обычно их хватает. Это же относится и к предыдущей цитате.

> Кстати, а что же делать в этом случае в чистом С? Неужели засада?

Да, тут уже без m4 никак...

> Лисп с семантикой С, или, что то же самое, С с синтаксисом лиспа. При этом, информация о типе времени компиляции, равно как и всё МП времени компиляции, является ответственностью лиспа.

Можно поподробнее? Я совсем недавно начал изучать лисп, он мне очень понравился, но в связи со спецификой моей работы (вычисления), использование голого лиспа мне, скорее всего, не подойдёт. Я думал попробовать поиграться с комбинацией C|C++ + лисп, связывая их через swig и/или ffi в надежде научиться таким образом делать быстрые и гибкие программы. Вы планируете по-другому?

Jini ★★
()
Ответ на: комментарий от ACR

В приведеном тобой примере класичиская задача условной компиляции в зависимости от типа тесно связана с типобезапасностью и шаблонами С++ да это можно реализовать но потребуется реализация полного синтаксического анализатора С и что в итоге мы получим? а получим вариант С++ тоесть то от чего пытались уйти. Типобезапасность должна быть в голове а не в копиляторе.

ACR
()
Ответ на: комментарий от Jini

Ээээ. Наверное насчёт лиспа лучше обсудить в другой теме. Сейчас её заведу. Похоже, нужно открывать опен-соурс проект, но я этого никогда не делал, нужно как-то напрячься на эту тему.

den73 ★★★★★
() автор топика
Ответ на: комментарий от ACR

ACR, я не фанат статической типизации, мой любимый язык - это лисп. Но я знаю, что она часто (не всегда) позволяет делать программы намного более быстрыми.

В общем, меня убедили, что m4 - это костыль. У меня и у самого при работе с ним в какой-то момент начало нарастать ощущение, что при массированном использовании с ним будут проблемы. Поэтому переходим к лисповому решению вопроса, см. сюда.

http://www.linux.org.ru/view-message.jsp?msgid=2968062&lastmod=1216981137364

Всем спасибо за ответы!

den73 ★★★★★
() автор топика

> Кто-нибудь использовал m4 в качестве препроцессора для программ, написанных на С/C++?

Почти все его используют. Как минимум для хедеров. Hint: GNU Autotools.

anonymous
()
Ответ на: комментарий от jtootf

> почему ? если рассматривать их применение для метапрограммирования, т.е. по сути кодогенерации - в чём существенная разница ?

Разница в том, что на стадии препроцессора нет информации о типах, а при раскрутке шаблона она есть.

anonymous
()
Ответ на: комментарий от den73

<?php

function DefineStaticValue($ValueName, $ValueType)
{
 echo $ValueType.' '.$ValueName.";\n";
 return array(
 'ValueName'=>$ValueName,
 'ValueType'=>$ValueType
 );
}

function TypeSafePrintf($ValueInfo)
{
 $ValueType = $ValueInfo['ValueType'];
 $ValueName = $ValueInfo['ValueName'];

 switch ($ValueType)
 {
  case 'int':
   echo "printf(\"%i\",$ValueName);\n";
   break;
  case 'double':
   echo "printf(\"%f\",$ValueName);\n";
   break;
  default:
   echo '#error Hey you forget printf for ('.$ValueType.") but try to use it, so you stupid man, use da C++ it's for you!\n";
 }
}

?>


void foo()
{
  <?php $I = DefineStaticValue('i', 'int'); ?>
  <?php $J = DefineStaticValue('j', 'double'); ?>
  <?php $C = DefineStaticValue('c', 'void*'); ?>

  printf("Some values:\n");
  <?php TypeSafePrintf($I); ?>
  <?php TypeSafePrintf($J); ?>
  <?php TypeSafePrintf($C); ?>
}


результ кодогенирации:

void foo()
{
  int i;
  double j;
  void* c;

  printf("Some values:\n");
  printf("%i",i);
  printf("%f",j);
  #error Hey you forget printf for (void*) but try to use it, so you stupid man, use da C++ it's for you!
}

типобезапасно, кросплатфоменно

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

ACR
()
Ответ на: комментарий от ACR

Я очень уважаю лисп я им пользовался в институте на лабораторный по автокаду, помнится я такие вещи на нем делал что когда здавал лабораторные я слышал как у преподавателя скрипит мозг. Я полностью согласен что лисп незаменимое средство когда нужно поиздеватся над преподавателем, но не совсем понимаю как он может помочь в контексте данной темы, приведи пример если несложно использования лиспа для генирации кода С с динамической типобезапаснотью.

ACR
()
Ответ на: комментарий от ACR

Hint: генирировать ТИП нужно средствами выбраного нами интерпритируемого языка и приетом отказатся от прямого объвления переменых в стиле С, это так сказать первое симантическое правило, при этом можно получить такую типобезопастность что поклоники С++ просто будут нервно курить в сторонке мануалы по бусту.

ACR
()
Ответ на: комментарий от ACR

ACR, я посмотрел пример на PHP. Мне не нравится. Конечно, вопрос вкуса, но смотрите в новой теме, на к-рую я давал ссылку. Там всё происходит более естественно. Мы просто деклалируем тип переменной, как обычно. А дальше, за счёт "умного" компилятора, в котором есть понятие "тип переменной", добиваемся того, что нам нужно. Начиная с лиспа, подобный компилятор написать не так сложно. Конечно, в Вашем примере с PHP ничего особого писать не нужно, но зато код громоздкий. В лисповом же случае нужно написать транслятор (но такой транслятор написать легко), зато код сразу получается такой же компактный, как на родном С.

Сейчас мне надо идти, попозже я напишу вариант полиморфной печати для С на лиспе.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Хотя сама идея генерировать и тип тоже макросами - эта идея нова для меня и стоит обдумывания.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

День сисадмина Yo, мне тоже пора :)

Не теряйтесь, предлагаю организовать проект.

PS: приношу извенения любителям плюсов за резкие высказывания в адрес вобщемто любимого мною языка

ACR
()
Ответ на: комментарий от ACR

> Я очень уважаю лисп я им пользовался в институте на лабораторный по автокаду

То, чем ты пользовался, Лиспом не является. Автолисп - это жалкая, кривая пародия.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.