Здравствуйте, WolfHound, Вы писали:
WH>В .НЕТ GetHeshCode виртуальный метод.
Ну так в изначальной задаче же этого не требовалось. Но даже и с этим требованием не вижу вообще никаких проблем — просто добавляется ещё предок (этот самый интерфейс) к тому mixin классу.
WH>Это я тебе просто показал что как только задача чуть меняется так С++ окончательно ласты склеивает.
Ты ничего не показал, т.к. совершенно непонятно с чего это от ITest наследуется Foo, а не ITestImpl.
Здравствуйте, alex_public, Вы писали:
_>Кстати, это я ещё не упомянул самого стандартного для C++ метода для решения подобных вещей — использования макроса. При использование такого способа добавление новой функций-члена будет выглядеть в стиле D: дополнительная строчка в классе (раскрываемая в метод). _>В общем варианты на все вкусы, причём код получается покрасивее чем на конкурентах. Единственный минус, как я уже говорил, в реализации интроспекции.
Как я понял, Nemerle'шные макросы это по сути плагин к компилятору, который и подключается к нему как динамическая библиотека, со всеми вытекающими из этого ограничениями.
Сделать plugin к Clang'у или tool на его же базе, обойти AST, сгенерировать всё что потребуется (в зависимости хоть от кусков AST, хоть от фазы луны) — не проблема (1, 2).
Вот только опять же, просто так внутрь класса никто не добавлял бы метод hash, а по возможности бы это была non-member функция
Здравствуйте, alex_public, Вы писали:
_>Нуу ты озвучь конкретную задачку и посмотрим как реализовать. )
Начнём с чего попроще. Реализуй немерловый Record.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
_>>Нуу ты озвучь конкретную задачку и посмотрим как реализовать. ) WH>Начнём с чего попроще. Реализуй немерловый Record.
Это мне ни о чём не говорит. ) Нужен пример кода и пояснение его работы на русском (или английском) языке.
Здравствуйте, WolfHound, Вы писали:
EP>>Даже если бы была простая возможность добавить в класс метод hash — то всё равно на C++ идиомой бы осталась non-member функция hash_value. Точно также как и ты говоришь, что требование использовать шаблоны на Nemerle не соответствует его идиомам WH>GetHeshCode виртуальный. Как ты его собрался делать внешней функцией?
Здравствуйте, alex_public, Вы писали:
_>Это мне ни о чём не говорит. ) Нужен пример кода и пояснение его работы на русском (или английском) языке. https://github.com/rsdn/nemerle/wiki/Record-macro
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>>>Про это ничего не было в изначальной задаче WH>>Влад просто забыл это написать. EP>
WH>>Поражает привычка людей решать задачу, которую не просили, и делать далеко идущие выводы.
EP>
Это очевидно для всех кто хоть чуть-чуть знаком с .NET
EP>А в решении на D override'а не было Зато в обоих примерах реализовывалось не то что требовалось в задаче
В решение на D override добавляется тривиально. А в твое не добавляется от слова совсем.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
EP>>>>Про это ничего не было в изначальной задаче WH>>>Влад просто забыл это написать. EP>>
WH>>>Поражает привычка людей решать задачу, которую не просили, и делать далеко идущие выводы.
EP>> WH>Это очевидно для всех кто хоть чуть-чуть знаком с .NET
А для всех кто знаком с C++ очевидно что non-member function — это default, от которого нужно отходить только при необходимости.
Да и потом — по названию GetHeshCode не так уж и 100% очевидно что должен быть override
WH>В решение на D override добавляется тривиально. А в твое не добавляется от слова совсем.
Допустим. Но что ты этим пытаешься доказать?
Ты ветку-то почитай на которую ссылаешься:
VD>>"Например" не катит. Давай или признаем, что в области метапрограммирования С++ существенно уступает D,
EP>Слушай, я тебе вчера, точнее даже сегодня писал
:
EP>"
VD>>>Что до метапограммирования, то очевидно, что на D мета-код выглядит проще, работает существенно быстрее и выдает внятную диагностику.
EP>>Вот тут я как раз и не спорю — на данном этапе у него больше возможностей для метапограммирования.
EP>>Что, кстати, немного странно: казалась бы, в языке с лучшей поддержкой compile-time вычислений, compile-time dispatch, метапограммирования — должна быть супер эффективная, гибкая, стандартная библиотека — так ведь нет, STL явно выигрывает
EP>"
EP>Или тебе больше не о чём поспорить?
VD>>Я и не спорю.
EP>А вот это к чему было:
EP>"
VD>>Давай или признаем, что в области метапрограммирования С++ существенно уступает D, или вы продемонстрируете аналог генерации функции GetHashCode и мы сравним код.
EP>""?
EP>Ты не читаешь ответы на свои сообщения? Я тебе явно сказал, что у D метапрограммирование лучше.
EP>Или если закрыть эту тему — то холивара не получится?
EP>Кто-то считает что в языке который он не использует есть хорошие фичи — внезапно, да?
А задача та совершенно по-дурацки поставлена — и непонятно что пытающаяся доказать.
И решается на C++ действительно красивее чем на D или Nemerle (придирки на счёт реализации в классе совершенно не к месту) — полный код с примером выглядит выглядит чище чем тем обрезки с Nemerle.
Что собственно и порвало template:
Не зачет. Это хрень а не решение. Попробуй всунуть это в имеющуюся программу. Да и говнокод полнейший.
Ведь сначала были попытки взять "на слабо"
На С++ аналог кто нить с бацает? Или времени хватает только на его расхваливание?
[...]
"Например" не катит. Давай или признаем, что в области метапрограммирования С++ существенно уступает D, или вы продемонстрируете аналог генерации функции GetHashCode и мы сравним код.
Хотя совершенно непонятно зачем — на счёт широких возможностей метапрограммирования в D/Nemerle никто и не спорил
Здравствуйте, WolfHound, Вы писали:
_>>Это мне ни о чём не говорит. ) Нужен пример кода и пояснение его работы на русском (или английском) языке. WH>https://github.com/rsdn/nemerle/wiki/Record-macro
Ха, ну так это же и так есть в самом C/C++:
struct Person{
string name;
int age;
bool sex;
};
Person person{"name", 1, true};//компилируется нормально
Однако я конечно же понял задачу — сделать тоже самое, только средствами МП. Тоже легко делается, но естественно только при наличие в языке нормальной интроспекции, как я уже неоднократно отмечал. Ну предположим что она уже есть (или же мы прибегли к извращению со скобочками из boost'a)... Тогда всё делается без проблем:
struct Animal{
string name;
};
struct Cat: public Animal{
int fur;
declare_ctor(Cat);//добавляется одна коротенькая строка, как и в Немерле
};
Cat cat{"name", 1};
cout<<cat.name<<' '<<cat.fur<<endl;//выводит "name 1"
где реализация данной функциональности выглядит так (по простому, даже без всяких удобностей из boost.fusion):
Ну и для тестирования работоспособности примера мы можем использовать такую эмуляцию интроспекции (подразумевается что в нормальном случае её реализует компилятор или в худшем случае генерируют какие-то макросы, но мне лень возиться с этим):
template<int N, typename S>auto& field_at(S& s);
template<> auto& field_at<0, Cat>(Cat& c) {return c.name;}
template<> auto& field_at<1, Cat>(Cat& c) {return c.fur;}
В общем ничего сложного в данной задаче не вижу. Да, здесь не реализована фильтрации (exclude список), как в Record, но очевидно что это тоже легко добавляется — просто при итерации пропускаем (вызовем _ctor<N+1>(s, value, args...) вместо _ctor<N+1>(s, args...)) соответствующие поля. Так что можно углублять настройки насколько угодно далеко.
P.S. Хочу заметить, что лично я не считаю МП в C++ особо сильным — в том же D намного сильнее и красивее. Но как-то так получается, что эти твои типа модные примеры на самом деле реализуются даже на простеньком МП из C++...
P.P.S. А если говорить о сложном МП... Могу ли я сейчас реализовать на Немерле аналог этого http://vibed.org/features#diet-templates решения? ) Ну т.е. чтобы можно было создавать отдельные файлы, целиком написанные на некотором DSL (не имеющем нечего общего с C# или Немерле, но возможно имеющем вкрапления из них), а потом писать где-то create_page("dsl file name") и в этой точке компилятор вставлял (причём с полной последующей оптимизацией) сгенерированный по тому файлу код. Ну и естественно это всё должно быть реализовано просто как библиотека на Немерле, а не какой-то внешний инструмент препросессинга.
Здравствуйте, alex_public, Вы писали:
_>P.P.S. А если говорить о сложном МП... Могу ли я сейчас реализовать на Немерле аналог этого http://vibed.org/features#diet-templates решения? ) Ну т.е. чтобы можно было создавать отдельные файлы, целиком написанные на некотором DSL (не имеющем нечего общего с C# или Немерле, но возможно имеющем вкрапления из них), а потом писать где-то create_page("dsl file name") и в этой точке компилятор вставлял (причём с полной последующей оптимизацией) сгенерированный по тому файлу код. Ну и естественно это всё должно быть реализовано просто как библиотека на Немерле, а не какой-то внешний инструмент препросессинга.
.
Насколько я понял, макросы компилируются в отдельную динамическую библиотеку, которая подцепляется компилятором во время обработки "остального" кода. Такая библиотека, по сути, и является внешним инструментом. Например, предполагаю что макрос не может ссылаться на какой-либо элемент сборки использующий этот макрос, так как во время "запуска библиотеки с макросом" ещё нет той самой сборки, использующей его.
Думаю что можно подобрать некий синтетический пример показывающий ограничения такого подхода по сравнению с "не внешним" инструментом. Например, что-то типа:
P.S. В Nemerle, также, есть и другая интересная возможность: при использовании внутри кода программы некоторой compile-time-строки-DSL, IDE может подсвечивать ошибки внутри этой DSL строки, например ошибку в XML.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Насколько я понял, макросы компилируются в отдельную динамическую библиотеку, которая подцепляется компилятором во время обработки "остального" кода. Такая библиотека, по сути, и является внешним инструментом. Например, предполагаю что макрос не может ссылаться на какой-либо элемент сборки использующий этот макрос, так как во время "запуска библиотеки с макросом" ещё нет той самой сборки, использующей его.
Хм, при таком подходе действительно можно творить всё что угодно. Кстати, в C++ мире тоже некоторое время назад началась работа по разным интеграциям с компилятором. Однако там это явно отдельный инструмент получается, т.к. в самом языке ничего подобного нет.
EP>Думаю что можно подобрать некий синтетический пример показывающий ограничения такого подхода по сравнению с "не внешним" инструментом. Например, что-то типа: EP>... EP>Сходу чего-то более реального не придумал.
Ого, как ты ты накрутил. )
EP>P.S. В Nemerle, также, есть и другая интересная возможность: при использовании внутри кода программы некоторой compile-time-строки-DSL, IDE может подсвечивать ошибки внутри этой DSL строки, например ошибку в XML.
Да, это могло бы быть киллер-фичей, но что-то пока не видно никаких реальных удобных на практике реализаций.
Здравствуйте, alex_public, Вы писали:
EP>>Думаю что можно подобрать некий синтетический пример показывающий ограничения такого подхода по сравнению с "не внешним" инструментом. Например, что-то типа: EP>>... EP>>Сходу чего-то более реального не придумал. _>Ого, как ты ты накрутил. )
Да, но идея простая — метапрограмма и код использующий её результат зависят друг от друга. Это особая, уличная магиямета рекурсия
EP>>P.S. В Nemerle, также, есть и другая интересная возможность: при использовании внутри кода программы некоторой compile-time-строки-DSL, IDE может подсвечивать ошибки внутри этой DSL строки, например ошибку в XML. _>Да, это могло бы быть киллер-фичей, но что-то пока не видно никаких реальных удобных на практике реализаций.
Так оно вроде как уже реализовано, правда не знаю насколько полно.
Здравствуйте, Patalog, Вы писали:
P>Здравствуйте, Kernighan, Вы писали:
K>>А нельзя ли что-нибудь сказать про то, как буст помогает вести разработку алгоритмов?
P>Тем что, к примеру, позволяет не писать очередной super-duper-smart pointer а юзать готовый.
Ну, это очередной контейнер данных.
Конечно, это помогает. Но вряд ли это составляет хотя бы 20% работы программиста.
Здравствуйте, alex_public, Вы писали:
_>Ха, ну так это же и так есть в самом C/C++:
А вот так уже не компилируется.
struct Person{
private:
std::string name;
int age;
bool sex;
};
_>Однако я конечно же понял задачу — сделать тоже самое, только средствами МП. Тоже легко делается, но естественно только при наличие в языке нормальной интроспекции, как я уже неоднократно отмечал. Ну предположим что она уже есть (или же мы прибегли к извращению со скобочками из boost'a)... Тогда всё делается без проблем:
Вызывать нужно конструкторы базового класса. Их может быть много.
_>P.S. Хочу заметить, что лично я не считаю МП в C++ особо сильным — в том же D намного сильнее и красивее. Но как-то так получается, что эти твои типа модные примеры на самом деле реализуются даже на простеньком МП из C++...
Да вот оказывается, не реализуются.
_>P.P.S. А если говорить о сложном МП... Могу ли я сейчас реализовать на Немерле аналог этого http://vibed.org/features#diet-templates решения? ) Ну т.е. чтобы можно было создавать отдельные файлы, целиком написанные на некотором DSL (не имеющем нечего общего с C# или Немерле, но возможно имеющем вкрапления из них), а потом писать где-то create_page("dsl file name") и в этой точке компилятор вставлял (причём с полной последующей оптимизацией) сгенерированный по тому файлу код. Ну и естественно это всё должно быть реализовано просто как библиотека на Немерле, а не какой-то внешний инструмент препросессинга.
C# и Nitra так и компилируются.
Можно даже разные части partial class'а на разных языках писать.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
PM>Гм, да, про wxWidgets забыл. И не только один я Сходил на сайт, судя по новостям, wxWidgets даже обновляются. Но вот растут они тоже из начала 90-х и архитектурно от MFC мало отличаются.
Внутри — ничего общего с MFC. Ну только если MFC изменился, хз, давно в него не заглядывал.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, WolfHound, Вы писали:
_>>Однако я конечно же понял задачу — сделать тоже самое, только средствами МП. Тоже легко делается, но естественно только при наличие в языке нормальной интроспекции, как я уже неоднократно отмечал. Ну предположим что она уже есть (или же мы прибегли к извращению со скобочками из boost'a)... Тогда всё делается без проблем: WH>Вызывать нужно конструкторы базового класса. Их может быть много.
А какой в этом смысле? Для тривиальных ("record" в "record") конструкторов логичнее сделать плоскую реализацию (т.е. просто инициализацию всех подряд полей, и своих и предков) — будет и проще и быстрее. А для нетривиальных конструкторов вообще вся эта автогенерация не подходит.
WH>Да вот оказывается, не реализуются.
Где оказывается то? )
WH>C# и Nitra так и компилируются. WH>Можно даже разные части partial class'а на разных языках писать.
Вот это уже другой разговор. Действительно серьёзные вещи, недоступные на C++. Кстати, интересно как-нибудь сравнить плюсы и минусы вашей реализации, реализации D, ну может ещё Rust'a. Хотя конечно последние два скорее из одного мира (нативного, позволяющего решать любые задачи), а ваше из другого (из ограниченного мира .net), но в смысле метапрограммирования это наверное не особо принципиально.
EP>Тут даже не нужно знать Boost.Spirit, чтобы понять что происходит
А потом туда добавляются всякие правила для комментариев, потом ещё что то. И всё превращается в тяжело поддерживаемую простыню. У меня доходило до того, что компилятор падал на этапе компиляции.
Здравствуйте, TimurSPB, Вы писали:
EP>>Тут даже не нужно знать Boost.Spirit, чтобы понять что происходит TSP>А потом туда добавляются всякие правила для комментариев, потом ещё что то. И всё превращается в тяжело поддерживаемую простыню. У меня доходило до того, что компилятор падал на этапе компиляции.
Да, если юзать спирит, нужно вставить побольше RAM в compile-сервер