Откуда пошла эта мода на обмазывание шаблонами к месту и не к месту? Нет, я ничего не имею против шаблонов, если действительно надо — только приветствую.
Но в последние годы появился какой-то особенный класс С++ программистов, которые пихают шаблоны везде, делая код и ошибки компиляции нечитаемыми.
Такие люди пишут код, обмазанный шаблонами — и говорят "смотрите, как просто и красиво!". Да нихрена не просто и не красиво! Разбор такого кода вызывает у меня только головную боль.
Если все еще непонятно, о чем говорю — приведу пример — boost::spirit. Это просто экстремум шаблонофилии.
Ну или просто может я лох, а другие умные. Наболело, в общем.
Здравствуйте, kurchatov, Вы писали:
K>Откуда пошла эта мода на обмазывание шаблонами к месту и не к месту? Нет, я ничего не имею против шаблонов, если действительно надо — только приветствую. K>Но в последние годы появился какой-то особенный класс С++ программистов, которые пихают шаблоны везде, делая код и ошибки компиляции нечитаемыми. K>Такие люди пишут код, обмазанный шаблонами — и говорят "смотрите, как просто и красиво!". Да нихрена не просто и не красиво! Разбор такого кода вызывает у меня только головную боль.
ну... а у меня хобби — астрофизика, и это для меня дико сложно. но мне что, всех астрофизиков называть идиотами все усложняющими? посыл понятен?
(если не понятен, то — в своей тупости виноват только я, и мои генетические предки)
K>Если все еще непонятно, о чем говорю — приведу пример — boost::spirit. Это просто экстремум шаблонофилии.
спирит решает свой класс задач, и решает их очень эффективно, насколько это возможно в С++.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали:
X>ну... а у меня хобби — астрофизика, и это для меня дико сложно. но мне что, всех астрофизиков называть идиотами все усложняющими? посыл понятен? X>(если не понятен, то — в своей тупости виноват только я, и мои генетические предки)
Мой топик скорее о слесарях, использующих токарный станок там, где можно обойтись напильником.
K>>Если все еще непонятно, о чем говорю — приведу пример — boost::spirit. Это просто экстремум шаблонофилии. X>спирит решает свой класс задач, и решает их очень эффективно, насколько это возможно в С++.
Да. Не считая нечитаемых ошибок при компиляции. Я вообще молчу о времени, которое занимает сама компиляция!
Здравствуйте, kurchatov, Вы писали:
K>Да. Не считая нечитаемых ошибок при компиляции. Я вообще молчу о времени, которое занимает сама компиляция!
ну... это неотъемлемая часть с++
ну а ты что бы использовал? какую-нить pcre_библиотеку без возможности статического анализа выражений?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, kurchatov, Вы писали:
K>Причем тут pcre? Spirit — это грамматики, так что скорее бизон какой-нибудь.
да, напутал.
flex/bison — дико неудобно для С++. для С — да, выбора-то нет.
K>Вы тоже любите обмазываться шаблонами, да?
ну... я не знаю. со стороны виднее =)
а сообщения об ошибках неудобными будут до тех пор, пока компилятор не научится концептам, имхо.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
В целом, излишняя шаблонизация прикладного кода — действительно ни к чему.
Что же касается K>Если все еще непонятно, о чем говорю — приведу пример — boost::spirit. Это просто экстремум шаблонофилии.
Довольно таки странный пример. spirit — это либа, предоставляющая такие возможности (embedded EBNF), которые просто невозможно достичь иными способами. Если есть возможность (желание) использовать препроцессинг — никто не воспрешает, берите теплый ламповый bison.
Процитирую себя же =)
P>Довольно таки странный пример. spirit — это либа, предоставляющая такие возможности (embedded EBNF), которые просто невозможно достичь иными способами. Если есть возможность (желание) использовать препроцессинг — никто не воспрешает, берите теплый ламповый bison.
У spirit-a нет никаких преимуществ перед бизоном. Оба делают одно и то же, только первый — во время компиляции с нечитаемыми ошибками.
P>spirit — это либа, предоставляющая такие возможности (embedded EBNF), которые просто невозможно достичь иными способами.
Да вот только не EBNF она предоставляет, а нечитаемую пародию на него. На практике от использования спирита возникает больше проблем, чем решается. Самое оптимальное почти во всех случаях — сделать прототип на ANTLR и написать рабочий парсер вручную по мотивам сгенерированного кода.
Здравствуйте, kurchatov, Вы писали:
K>Если все еще непонятно, о чем говорю — приведу пример — boost::spirit. Это просто экстремум шаблонофилии.
На самом деле не экстремум. Экстремум можно поискать где-то в области пересечения boost.mpl, boost.proto, boost.fusion... )
Что касается boost.spirit, то пожалуй не соглашусь. Во всяком случае пока никто не продемонстрирует мне настолько же удобный и быстрый аналог, но без "шаблонофилии".
Т.е. вот допустим есть тривиальная задачка: прочитать большой текстовый файл в специфическом формате (например какая-нибудь вариация на тему csv). Какое вы предложите решение, чтобы оно было быстродействующим и при этом занимало пару строчек кода? )
Здравствуйте, alex_public, Вы писали:
_>Что касается boost.spirit, то пожалуй не соглашусь. Во всяком случае пока никто не продемонстрирует мне настолько же удобный и быстрый аналог, но без "шаблонофилии".
что значит быстрый? Что спирит, что бизон делают одно — генерируют конечный автомат для парсинга. Быстрее вы парсинг не сделаете.
Удобный? boost::spirit? Ну вы неординарная личность.
Здравствуйте, alex_public, Вы писали:
K>>Если все еще непонятно, о чем говорю — приведу пример — boost::spirit. Это просто экстремум шаблонофилии.
_>На самом деле не экстремум. Экстремум можно поискать где-то в области пересечения boost.mpl, boost.proto, boost.fusion... )
Для добавления экстремальности я бы еще добавил boost.preprocessor в эту компанию, хоть это и другой вид магии Вот пример: https://github.com/pmed/v8pp/blob/master/v8pp/call_from_v8.hpp — вызов С++ функции (или функции-члена) из JavaScript-движка V8. При вызове производится преобразование списка аргументов v8::Arguments из JavaScript к аргументам требуемой функции. Я не знаю как проще сделать это в С++03, только генерировать код руками/внешним скриптом.
Переписываю сейчас это на С++11 с variadic templates и радуюсь своему счастью
Автор использует boost.fusion потому что нет пока в языке compile-time reflection, а код генерировать надо. И генерация внешними инструментами им не подходит.
Шаблоны в С++ — один из эффективнейших инструментов. Так что не удивительно, что люди пытаются попробовать применить этот инструмент по-разному.
"Метапрограммисты надоели" — это только симптом. А реальная проблема — это отсутствие нормально поставленного процесса разработки, включающего обязательное наличие стандартов кодирования и ревью кода. Будет нормально поставлен процесс — таких проблем просто не будет возникать. А если и будет, то они будут решаться в оперативном порядке не мешая процессу.
Здравствуйте, alex_public, Вы писали:
_>Что касается boost.spirit, то пожалуй не соглашусь. Во всяком случае пока никто не продемонстрирует мне настолько же удобный и быстрый аналог, но без "шаблонофилии".
_>Т.е. вот допустим есть тривиальная задачка: прочитать большой текстовый файл в специфическом формате (например какая-нибудь вариация на тему csv). Какое вы предложите решение, чтобы оно было быстродействующим и при этом занимало пару строчек кода? )
А зачем обязательно "пару строчек кода"? Если там будет 20 строк, но они будут понятнее и проще в отладке — чем это хуже? Причем, в случае со спиритом, они еще и быстрее компилироваться будут
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, kurchatov, Вы писали:
K>что значит быстрый? Что спирит, что бизон делают одно — генерируют конечный автомат для парсинга. Быстрее вы парсинг не сделаете.
Т.е. как вариант решения предлагается бизон? И это на C++ (а не на C)?
K>Удобный? boost::spirit? Ну вы неординарная личность.
А что там неудобного то при использование? При написание spirit'a (или копание в его исходниках) действительно требуется знание МП на шаблонах. Но при обычном использование же ничего не нужно. Вот какие особые знания шаблонной магии требуются для написания скажем такого parse(file.data(), file.data()+file.size(), int_[([&](const int& n){sum+=n; count++;})] % ','); простейшего кода?
Здравствуйте, alex_public, Вы писали:
_>А что там неудобного то при использование? При написание spirit'a (или копание в его исходниках) действительно требуется знание МП на шаблонах. Но при обычном использование же ничего не нужно. Вот какие особые знания шаблонной магии требуются для написания скажем такого parse(file.data(), file.data()+file.size(), int_[([&](const int& n){sum+=n; count++;})] % ','); простейшего кода?
Пример тривиальный. И это мы с вами знаем, как оно работает. А придет новичок в вашу команду, и сколько времени ему потребуется врубиться в грамматику посложнее?
Здравствуйте, PM, Вы писали:
PM>Для добавления экстремальности я бы еще добавил boost.preprocessor в эту компанию, хоть это и другой вид магии Вот пример: https://github.com/pmed/v8pp/blob/master/v8pp/call_from_v8.hpp — вызов С++ функции (или функции-члена) из JavaScript-движка V8. При вызове производится преобразование списка аргументов v8::Arguments из JavaScript к аргументам требуемой функции. Я не знаю как проще сделать это в С++03, только генерировать код руками/внешним скриптом.
Да, да, есть такая штука. Я её использовал для автоматической генерации ORM (за неимением интроспекции времени компиляции в языке). Просто автор темки переживал именно за шаблоны. )
PM>Переписываю сейчас это на С++11 с variadic templates и радуюсь своему счастью
Автор использует boost.fusion потому что нет пока в языке compile-time reflection, а код генерировать надо. И генерация внешними инструментами им не подходит.
Да, это как мне кажется самый большой недостаток языка (ну про сложность мы упоминать не будем) в данный момент. Но в данном случае boost.fusion — это всё же на мой взгляд уж слишком костыльное решение.
C++ с годами становится все сложнее и сложнее. Особенно в последнее время, когда стандарты стали готовиться с невиданной скоростью (C++11, C++14, ...).
Отличный язык превращается в сложнейшего монстра. Группа гиков от программирования написала Boost, и я очень рад, что далеко не все компании (особенно топовые) решаются использовать его.
Это только удорожает и удлиняет разработку ПО. Скучаю по C++ 03.
Здравствуйте, Хон Гиль Дон, Вы писали:
ХГД>А зачем обязательно "пару строчек кода"? Если там будет 20 строк, но они будут понятнее и проще в отладке — чем это хуже? Причем, в случае со спиритом, они еще и быстрее компилироваться будут
А кто сказал, что они будут проще? ) Не следует путать внутренности спирита (действительно довольно нетривиальные) и использование его в качестве готовой библиотеки.
Здравствуйте, kurchatov, Вы писали:
K>Пример тривиальный. И это мы с вами знаем, как оно работает. А придет новичок в вашу команду, и сколько времени ему потребуется врубиться в грамматику посложнее?
Так альтернатива то какая? ) Чтобы работала не хуже и при этом новичку не пришлось ничего объяснять?
ХГД>>А зачем обязательно "пару строчек кода"? Если там будет 20 строк, но они будут понятнее и проще в отладке — чем это хуже? Причем, в случае со спиритом, они еще и быстрее компилироваться будут
_>А кто сказал, что они будут проще? ) Не следует путать внутренности спирита (действительно довольно нетривиальные) и использование его в качестве готовой библиотеки.
Я сказал Я сравнивал оба варианта и пришел к выводу, что без спирита в некоторых случаях написать парсер получается быстрее. Вернее, с минимальным применением спирита — примитивы для парсинга чисел в спирите вполне годные. Можно, наверное, натренироваться и со спиритом работать, но мне он нужен редко и каждый раз вспоминать его особенности и разбираться с ранее неизвестными уже изрядно надоело.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, PM, Вы писали:
PM>Для добавления экстремальности я бы еще добавил boost.preprocessor в эту компанию
замечательная либа позволяющая делать замечательные вещи
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, kurchatov, Вы писали:
K>Группа гиков от программирования написала Boost, и я очень рад, что далеко не все компании (особенно топовые) решаются использовать его.
ну хз, мне о таких компаниях неизвестно.
абсолютно каждая компания в_которой/с_которой мне приходилось работать — использовали boost. так что я хз, о чем ты...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали:
X>ну хз, мне о таких компаниях неизвестно. X>абсолютно каждая коспания в_которой/с_которой мне приходилось работать — использовали boost. так что я хз, о чем ты...
Здравствуйте, niXman, Вы писали:
PM>>Для добавления экстремальности я бы еще добавил boost.preprocessor в эту компанию X>замечательная либа позволяющая делать замечательные вещи
Наверно иногда да. Но на мой взгляд, препроцессор, как он сейчас есть в С/С++ довольно опасная вещь. И использовать его стоит только если вообще других средств никак не осталось.
Ты кстати не думал об boost.fusion, boost.proto в YARMI вместо препроцессора когда создавал ее?
Здравствуйте, PM, Вы писали:
PM>... препроцессор, как он сейчас есть в С/С++ довольно опасная вещь.
в мире С++ — все довольно опасно
PM>Ты кстати не думал об boost.fusion, boost.proto в YARMI вместо препроцессора когда создавал ее?
думал о boost.fusion, и даже был рабочий прототип с использованием ее. но помимо этого все равно приходилось генерить дополнительный код. в итоге, boost.fusion был выброшен, за ненадобностью.
по поводу boost.proto — я как-то не особо присматривался к этой либе, и толком не знаю, какие задачи она решает...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, kurchatov, Вы писали:
K>C++ с годами становится все сложнее и сложнее. Особенно в последнее время, когда стандарты стали готовиться с невиданной скоростью (C++11, C++14, ...).
Помнится лет 5-10 назад в моде были темы "ваш С++ устарел, не развивается. В нем нет лямбд/делегатов/... ухожу на С#/Nemerle" Теперь маятник качнулся в обратную сторону.
K>Отличный язык превращается в сложнейшего монстра. Группа гиков от программирования написала Boost, и я очень рад, что далеко не все компании (особенно топовые) решаются использовать его. K>Это только удорожает и удлиняет разработку ПО. Скучаю по C++ 03.
На мой взгляд, в компании могут не использовать Boost по таким причинам:
Используют С++11/14, хватает стандартной библиотеки. Кроссплатформенная поддержка сети, файловой системы, опций командной строки не нужны.
Используют другую мега-библиотеку (Qt или POCO например) в которой есть все необходимое.
Используют самописные велосипеды из прошлого века
И я бы согласился работать в 1-м типе компаний (не люблю Qt и тонны legacy кода ). Высказывания "не используем boost потому что он слишком сложный" для меня признак низкой квалификации ведущего разработчика. Работать в такой команде — профессионально деградировать.
Здравствуйте, PM, Вы писали:
PM>не люблю Qt
да, это ужасное творение. но для ГУЯ приходится использовать, увы
PM>Высказывания "не используем boost потому что он слишком сложный" для меня признак низкой квалификации ведущего разработчика. Работать в такой команде — профессионально деградировать.
угу.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, PM, Вы писали:
PM>И я бы согласился работать в 1-м типе компаний (не люблю Qt и тонны legacy кода ). Высказывания "не используем boost потому что он слишком сложный" для меня признак низкой квалификации ведущего разработчика. Работать в такой команде — профессионально деградировать.
о да. Лучше тратить драгоценное время на разработку с бустом, чем на оптимизацию дизайна и алгоритмов. Отличная позиция.
Здравствуйте, kurchatov, Вы писали:
K>о да. Лучше тратить драгоценное время на разработку с бустом, чем на оптимизацию дизайна и алгоритмов. Отличная позиция.
жир стекает. неряшливый тролль.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали:
X>Здравствуйте, kurchatov, Вы писали:
K>>о да. Лучше тратить драгоценное время на разработку с бустом, чем на оптимизацию дизайна и алгоритмов. Отличная позиция. X>жир стекает. неряшливый тролль.
Здравствуйте, niXman, Вы писали:
PM>>Ты кстати не думал об boost.fusion, boost.proto в YARMI вместо препроцессора когда создавал ее? X>думал о boost.fusion, и даже был рабочий прототип с использованием ее. но помимо этого все равно приходилось генерить дополнительный код. в итоге, boost.fusion был выброшен, за ненадобностью.
Понятно, спасибо
X>по поводу boost.proto — я как-то не особо присматривался к этой либе, и толком не знаю, какие задачи она решает...
Вроде как с ней можно нагородить DSL в С++ на шаблонах. Но реальных применений я не видел, потому и спросил
Здравствуйте, PM, Вы писали:
PM>Вроде как с ней можно нагородить DSL в С++ на шаблонах. Но реальных применений я не видел, потому и спросил
вот смотрю, и особо не понимаю, как "это" использовать =)
гляну позже, повнимательней...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, alex_public, Вы писали:
_>На самом деле не экстремум. Экстремум можно поискать где-то в области пересечения boost.mpl, boost.proto, boost.fusion... ) http://ldionne.github.io/hana/?
Здравствуйте, Kswapd, Вы писали:
P>>spirit — это либа, предоставляющая такие возможности (embedded EBNF), которые просто невозможно достичь иными способами.
K>Да вот только не EBNF она предоставляет, а нечитаемую пародию на него.
Дело скорее вкуса. Достаточно быстро адаптируешься, а для задач, под которые, как я считаю он более всего подходит (см. ниже) — большего и не надо.
K>На практике от использования спирита возникает больше проблем, чем решается.
Ниша спирита — небольшие встроенные парсеры, в местах где не хватает регекспов.
Если пытаться написать на нем парсер плюсов — проблемы несомненно будут =)
K>Самое оптимальное почти во всех случаях — сделать прототип на ANTLR и написать рабочий парсер вручную по мотивам сгенерированного кода.
Это ваш опыт. Возможно вам так удобнее. Мой опыт — либо полностью автогенереный код, куда смотреть вообще не нужно, либо достаточно спирита.
То что я видел "по мотивам сгенерированного кода" — нечитаемое говно, единственное "достоинство" которого — нет шаблонов =)
Здравствуйте, kurchatov, Вы писали:
K>Но в последние годы появился какой-то особенный класс С++ программистов, которые пихают шаблоны везде, делая код и ошибки компиляции нечитаемыми.
об этом предупреждали несколько лет назад, когда экстаз от буста поразил многих.
K>Ну или просто может я лох, а другие умные. Наболело, в общем.
годы идут, а плюсеры всё ещё меряются, кто знает буст больше, и кто более извращённо использует шаблоны с макросами.
хъ
K>о да. Лучше тратить драгоценное время на разработку с бустом, чем на оптимизацию дизайна и алгоритмов. Отличная позиция.
На практике получается, что нежелающие "тратить драгоценное время на разработку с бустом" — тратят его на написание каких-то своих убогих велосипедов, вместо "оптимизации дизайна и алгоритмов".
хъ
X>>по поводу boost.proto — я как-то не особо присматривался к этой либе, и толком не знаю, какие задачи она решает...
PM>Вроде как с ней можно нагородить DSL в С++ на шаблонах. Но реальных применений я не видел, потому и спросил
Дык спирит же! Или вот boost.simd, его нет в самом бусте, но товариши вроде собираются его продвинуть.
Здравствуйте, kurchatov, Вы писали:
K>Пример тривиальный. И это мы с вами знаем, как оно работает. А придет новичок в вашу команду, и сколько времени ему потребуется врубиться в грамматику посложнее?
Здравствуйте, kurchatov, Вы писали:
K>Откуда пошла эта мода на обмазывание шаблонами к месту и не к месту? Нет, я ничего не имею против шаблонов, если действительно надо — только приветствую.
Многие не приветствуют потому, что не понимают. K>Ну или просто может я лох, а другие умные. Наболело, в общем.
Просто ты не осилил. В шаблонной "магии" используются простые принципы языка. ты их не знаешь, отсюда и непонимание того как оно всё работает.
Здравствуйте, alex_public, Вы писали:
_>Да, это как мне кажется самый большой недостаток языка (ну про сложность мы упоминать не будем) в данный момент. Но в данном случае boost.fusion — это всё же на мой взгляд уж слишком костыльное решение.
Недостаток языка — это отсутствие compile-time reflection, Boost.Fusion для этого предлагает макросы BOOST_FUSION_DEFINE_STRUCT и подобные.
А вот те методы работы, которые предлагает Boost.Fusion с уже адаптированными структурами (то есть для которые есть необходимые гетерогенные итераторы) — вполне себе, ничего костыльного.
Даже как-то сравнивали в этом отношении Boost.Fusion vs Nemerle vs D (Fusion
Здравствуйте, Patalog, Вы писали:
P>Здравствуйте, kurchatov, Вы писали:
K>>о да. Лучше тратить драгоценное время на разработку с бустом, чем на оптимизацию дизайна и алгоритмов. Отличная позиция.
P>На практике получается, что нежелающие "тратить драгоценное время на разработку с бустом" — тратят его на написание каких-то своих убогих велосипедов, вместо "оптимизации дизайна и алгоритмов".
Ну, это лозунг.
А нельзя ли что-нибудь сказать про то, как буст помогает вести разработку алгоритмов?
Потому что на первый взгляд "алгоритм" — вообще вещь внеязыковая.
Здравствуйте, niXman, Вы писали:
K>>Откуда пошла эта мода на обмазывание шаблонами к месту и не к месту? Нет, я ничего не имею против шаблонов, если действительно надо — только приветствую. K>>Но в последние годы появился какой-то особенный класс С++ программистов, которые пихают шаблоны везде, делая код и ошибки компиляции нечитаемыми. K>>Такие люди пишут код, обмазанный шаблонами — и говорят "смотрите, как просто и красиво!". Да нихрена не просто и не красиво! Разбор такого кода вызывает у меня только головную боль. X>ну... а у меня хобби — астрофизика, и это для меня дико сложно. но мне что, всех астрофизиков называть идиотами все усложняющими? посыл понятен?
Я тоже не очень с этими шаблонами... вот прямо сейчас сижу разбираюсь. Просто раньше я как-то избегал излишнего метапрограммирования, а тут попался проект с достаточно глубоким уровнем применения матапрограммирования. Понемногу разбираюсь.
Но считаю что врага надо знать в лицо У меня тоже есть хобби — разработка своего языка программирования, не менее (и даже гораздо более) мощного чем С++, но без всей этой головной боли. И для того чтобы это сделать наилучшим образом, считаю что нужно знать и С++ в совершенстве, в особенности все подводные камни и грабли, связанные с шаблонами и метапрограммированием. Также очень интересны "библиотечные языковые расширения", которые предлагает Буст и подобные ему библиотеки... интересна мотивация программистов которые это придумывают.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Тут даже не нужно знать Boost.Spirit, чтобы понять что происходит
ну это лукавство
для режима
1) почитай и прикинь насколько сложный питон-код мы умеем парсить
2) удали к чертям
действительно знать spirit не надо
для режимов
1) добавь новую питон-фичу
2) пофикси парсинг вот на таком волосатом питон-скрипте
уже надо
1) манулы spirit шерстить
2) плясать с бубном / гуглить / спращивать на рсдн почему же эта гадость не компилируется ???
3) почему же волосатый питон-скрипт все равно не парсится ???
Здравствуйте, Kernan, Вы писали:
K>Здравствуйте, kurchatov, Вы писали:
K>>Откуда пошла эта мода на обмазывание шаблонами к месту и не к месту? Нет, я ничего не имею против шаблонов, если действительно надо — только приветствую. K>Многие не приветствуют потому, что не понимают. K>>Ну или просто может я лох, а другие умные. Наболело, в общем. K>Просто ты не осилил. В шаблонной "магии" используются простые принципы языка. ты их не знаешь, отсюда и непонимание того как оно всё работает.
Шаблоны изначально придумывались для предоставления статического полиморфизма (Object-то нет в С++). Здесь и прирост производительности, если можно юзать шаблон вместо иерархии классов.
Остальное — горе от ума.
Здравствуйте, Kernighan, Вы писали:
K>>>о да. Лучше тратить драгоценное время на разработку с бустом, чем на оптимизацию дизайна и алгоритмов. Отличная позиция. P>>На практике получается, что нежелающие "тратить драгоценное время на разработку с бустом" — тратят его на написание каких-то своих убогих велосипедов, вместо "оптимизации дизайна и алгоритмов". K>Ну, это лозунг. K>А нельзя ли что-нибудь сказать про то, как буст помогает вести разработку алгоритмов? K>Потому что на первый взгляд "алгоритм" — вообще вещь внеязыковая.
Не разработку алгоритмов в широком "теоретическом" смысле, а скорее реализацию. И не только алгоритмов, но и структур данных.
Примеры библиотек Boost'а непосредственно упрощающих реализацию алгоритмов и структур данных: Graph, Geometry, Polygon, GIL, Interval, Multiprecision, Math*, Odeint, Accumulators, Container, Intrusive, Heap, ICL, Coroutine и т.д., не говоря уже об таких вспомогательных библиотеках как Iterator, Operators, Range и т.п.
Здравствуйте, uzhas, Вы писали:
U>предвзятость налицо
В чём? В том что пишется шаблон функции работающий со всеми типами (адаптированными к Boost.Fusion), а не инлайнится код для каждой отдельной структуры?
Здравствуйте, uzhas, Вы писали:
EP>>Тут даже не нужно знать Boost.Spirit, чтобы понять что происходит U>ну это лукавство U>для режима U>1) почитай и прикинь насколько сложный питон-код мы умеем парсить U>[censored] U>действительно знать spirit не надо
Так вроде же о таком варианте и шла речь?
K>А придет новичок в вашу команду, и сколько времени ему потребуется врубиться в грамматику посложнее?
U>для режимов U>1) добавь новую питон-фичу U>2) пофикси парсинг вот на таком волосатом питон-скрипте U>уже надо U>1) манулы spirit шерстить U>2) плясать с бубном / гуглить / спращивать на рсдн почему же эта гадость не компилируется ??? U>3) почему же волосатый питон-скрипт все равно не парсится ???
Согласен, но это же также, в той или иной степени, относится к любому генератору парсеров
Здравствуйте, uzhas, Вы писали:
EP>>В чём? U>в typos
Так это к авторам-евангелистам фрагментов D и Nemerle, а не ко мне
Или ты имеешь в виду, что в этих языках есть нечто метафизическое, заставляющее делать typos?
Здравствуйте, Kernan, Вы писали:
K>Просто ты не осилил. В шаблонной "магии" используются простые принципы языка. ты их не знаешь, отсюда и непонимание того как оно всё работает.
Здравствуйте, kurchatov, Вы писали:
K>Откуда пошла эта мода на обмазывание шаблонами к месту и не к месту? Нет, я ничего не имею против шаблонов, если действительно надо — только приветствую. K>Но в последние годы появился какой-то особенный класс С++ программистов, которые пихают шаблоны везде, делая код и ошибки компиляции нечитаемыми.
Ну так выразительных средств в плюсах мало и новых не добавляется, вот и приходится обмазываться шаблонами.
Здравствуйте, Олег К., Вы писали:
ОК>Чувак, только потому что в языке есть фича еще не значит что ее надо пихать куда не попадя.
чел, ты про нечитаемые ошибки? так а кто-то разве сует в свой код нечитаемые ошибки? оО
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
P>>>spirit — это либа, предоставляющая такие возможности (embedded EBNF), которые просто невозможно достичь иными способами.
K>>Да вот только не EBNF она предоставляет, а нечитаемую пародию на него.
P>Дело скорее вкуса. Достаточно быстро адаптируешься, а для задач, под которые, как я считаю он более всего подходит (см. ниже) — большего и не надо.
Это не дело вкуса, а дело инженеринга. Мне довелось поддерживать проект в который такие любители запихали Спирит. Абсолютно нечитаемый и неподдерживаемый код был в тех местах. Ну и в первую очередь вообще в том проекте не нужно было придумывать файлы которые надо было парсить. Без них можно было обойтись.
K>>На практике от использования спирита возникает больше проблем, чем решается.
P>Ниша спирита — небольшие встроенные парсеры, в местах где не хватает регекспов. P>Если пытаться написать на нем парсер плюсов — проблемы несомненно будут =)
Чукча не читатель — чукча писатель? Все кто ратует за Спирит и есть вот такие чукчи.
K>>Самое оптимальное почти во всех случаях — сделать прототип на ANTLR и написать рабочий парсер вручную по мотивам сгенерированного кода.
P>Это ваш опыт. Возможно вам так удобнее. Мой опыт — либо полностью автогенереный код, куда смотреть вообще не нужно, либо достаточно спирита. P>То что я видел "по мотивам сгенерированного кода" — нечитаемое говно, единственное "достоинство" которого — нет шаблонов =)
А ты представь если бы в то гавно еще и шаблоны запихали! Было б вообще весело!
K>>Если все еще непонятно, о чем говорю — приведу пример — boost::spirit. Это просто экстремум шаблонофилии.
_>На самом деле не экстремум. Экстремум можно поискать где-то в области пересечения boost.mpl, boost.proto, boost.fusion... )
+1.
_>Что касается boost.spirit, то пожалуй не соглашусь. Во всяком случае пока никто не продемонстрирует мне настолько же удобный и быстрый аналог, но без "шаблонофилии".
Ты видимо никогда не поддерживал код в который такие любители запихали Спирит. Иначе бы быстро поменял мнение.
_>Т.е. вот допустим есть тривиальная задачка: прочитать большой текстовый файл в специфическом формате (например какая-нибудь вариация на тему csv). Какое вы предложите решение, чтобы оно было быстродействующим и при этом занимало пару строчек кода? )
Жесть какая-то. Чтобы прочитать цсв Спирит не нужен!
Здравствуйте, Олег К., Вы писали:
P>>Дело скорее вкуса. Достаточно быстро адаптируешься, а для задач, под которые, как я считаю он более всего подходит (см. ниже) — большего и не надо. ОК>Это не дело вкуса, а дело инженеринга. Мне довелось поддерживать проект в который такие любители запихали Спирит. Абсолютно нечитаемый и неподдерживаемый код был в тех местах.
"Это не дело вкуса, а дело инженеринга. Мне довелось поддерживать проект в который такие любители запихали [PLACEHOLDER]. Абсолютно нечитаемый и неподдерживаемый код был в тех местах."
Следует ли из этого это что использование [PLACEHOLDER], делает код абсолютно не читаемым и не поддерживаемым? Нет.
Например, goto в кривых руках превращает код в лапшу, а в прямых — это всего лишь инструмент с определённым предназначением
K>C++ с годами становится все сложнее и сложнее. Особенно в последнее время, когда стандарты стали готовиться с невиданной скоростью (C++11, C++14, ...).
K>Отличный язык превращается в сложнейшего монстра. Группа гиков от программирования написала Boost, и я очень рад, что далеко не все компании (особенно топовые) решаются использовать его. K>Это только удорожает и удлиняет разработку ПО. Скучаю по C++ 03.
Некоторые вещи в бусте полезны, но я большему счет согласен с тобой. Только это применимо не только к С++. Вообще вся разработка идет не в ту сторону. Все инженерные решения должны быть простыми. На деле же в ИТ попала куча (м|ч)удаков которых надо гнать бейсбольными битами. Настоящих инженеров мало. Зато много вот таких вот любителей навернуть сверх меры и надобности. В плюсах это шаблоны где не попадя. В Джаве малюсенькие классы с какими-то через чур абстрактными названиями, малюсенькие функции, паттерн на паттерне и гигантские колл стэки. И ведь не понимают же!
K>>Удачи! X>спасибо, но ты прочти еще раз мой первый пост в этом треде
Чувак, вряд ли к твоему мнению можно вообще прислушиваться. Ты там в ветке про Сайберакса ныл про плохой код который ты решил переписать. А теперь ответь, почему ты решил, что никто не прийдет и не скажет что твой говнокод нужно переписать?
Здравствуйте, Олег К., Вы писали:
ОК>Некоторые вещи в бусте полезны, но я большему счет согласен с тобой. Только это применимо не только к С++. Вообще вся разработка идет не в ту сторону. Все инженерные решения должны быть простыми. На деле же в ИТ попала куча (м|ч)удаков которых надо гнать бейсбольными битами. Настоящих инженеров мало. Зато много вот таких вот любителей навернуть сверх меры и надобности. В плюсах это шаблоны где не попадя. В Джаве малюсенькие классы с какими-то через чур абстрактными названиями, малюсенькие функции, паттерн на паттерне и гигантские колл стэки. И ведь не понимают же!
о, оракул, открой нам истину!
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
PM>>не люблю Qt X>да, это ужасное творение. но для ГУЯ приходится использовать, увы
Ну так запили свое гавно на темплейтах.
PM>>Высказывания "не используем boost потому что он слишком сложный" для меня признак низкой квалификации ведущего разработчика. Работать в такой команде — профессионально деградировать. X>угу.
Чувак, проблемы бизнеса надо решать а не дрочить на язык!
Здравствуйте, Олег К., Вы писали:
ОК>Чувак, вряд ли к твоему мнению можно вообще прислушиваться. Ты там в ветке про Сайберакса ныл про плохой код который ты решил переписать. А теперь ответь, почему ты решил, что никто не прийдет и не скажет что твой говнокод нужно переписать?
чел, ты читаешь только то, что тебе удобно, мы уже это поняли
про плохой код: я писал, что он плохой и по мнению самого Сайберакса. но тебе-то это не интересно, потому что неудобно
про мой код: наверняка кто-то таки скажет что мой код плохой, как и говорили уже ранее. но куда мне до тебя-то, о великий!
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
P>На практике получается, что нежелающие "тратить драгоценное время на разработку с бустом" — тратят его на написание каких-то своих убогих велосипедов, вместо "оптимизации дизайна и алгоритмов".
А желающие — тратят его на написание каких-то своих шикарных костылей к готовым бустовским байкам. По сути так на так и выходит. Плюсы при использовании буста — человеку со стороны, знающему конкретную примененную часть буста проще понять код (ну, ему еще надо будет разобраться в прилагающихся костылях, но это, допустим, мелочи). Минусы — любое обобщенное решение сложно, а значит потенциально ненадежно и потенциально неоптимально. Примеры — boost::optional (редкостный силос, ИМХО) и boost::asio (без слез и мата работать с ним невозможно). Или вот, скажем, boost::circular_buffer. Ну просится, просится сделать не буфер, а просто адаптер-итератор, гораздо полезнее, ИМХО, но итератор — это не по-пацански, на нем не показать, что ты умеешь аллокаторы и move-semantics, потому и целый, извините, буфер.
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Здравствуйте, slava_phirsov, Вы писали:
_>Примеры — boost::optional (редкостный силос, ИМХО) и boost::asio (без слез и мата работать с ним невозможно).
мдя... не хотелось верить, что вас больше двух...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
K>>Откуда пошла эта мода на обмазывание шаблонами к месту и не к месту? Нет, я ничего не имею против шаблонов, если действительно надо — только приветствую. K>Многие не приветствуют потому, что не понимают.
А есть кто-то кто понимает и наоборот не использует! Поскольку понимает что код надо будет еще и поддерживать.
K>>Ну или просто может я лох, а другие умные. Наболело, в общем. K>Просто ты не осилил. В шаблонной "магии" используются простые принципы языка. ты их не знаешь, отсюда и непонимание того как оно всё работает.
Я всегда говорил. Любителей шаблонов и паттернов нужно заставить поддерживать код написанный другими такими любителями шаблонов и паттернов. Чтоб неповадно было!
З.Ы. Вот сколько не смотрю, это только русские программисты считают себя профессионалами а как до дела доходит — "нет, не хочу, не буду я поддерживать говнокод!"
WTF?!! Программист должен уметь разбираться в чужом коде и рабоатать в его рамках а не считать что работа программиста это писать код по типу "я сейчас тут напишу со всеми новомодными фичами а после меня и трава не расти."
ОК>>Чувак, только потому что в языке есть фича еще не значит что ее надо пихать куда не попадя. X>чел, ты про нечитаемые ошибки? так а кто-то разве сует в свой код нечитаемые ошибки? оО
Я про нечитаемый код а не про нечитаемые ошибки компилятора.
Здравствуйте, Олег К., Вы писали:
ОК>Я про нечитаемый код а не про нечитаемые ошибки компилятора.
ну так читай, перед тем как цитировать. хоть раз уже...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, kurchatov, Вы писали:
K>Шаблоны изначально придумывались для предоставления статического полиморфизма (Object-то нет в С++). Здесь и прирост производительности, если можно юзать шаблон вместо иерархии классов.
Да, согласен. Но тем ни менее программисты по всему миру придумывают и используют библиотеки типа Буста. Раз придумывают и используют — значит есть потребность (и немаленькая, судя по всему). А как раз это и интересно.
Здравствуйте, NeoCode, Вы писали:
NC>Раз придумывают и используют — значит есть потребность
да ты чо?! алег сказал что только он в треде оракул! окстись!
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, Олег К., Вы писали:
ОК>Ты там в ветке про Сайберакса ныл про плохой код который ты решил переписать. А теперь ответь, почему ты решил, что никто не прийдет и не скажет что твой говнокод нужно переписать?
Не пойму в чём проблема если у кого-то код получится объективно лучше чем твой?
Или, например, ты разве ни разу не рефакторил свой код, потому нашёл лучший способ решения проблемы?
EP>"Это не дело вкуса, а дело инженеринга. Мне довелось поддерживать проект в который такие любители запихали [PLACEHOLDER]. Абсолютно нечитаемый и неподдерживаемый код был в тех местах."
Не тупи, а? Самое худшее что происходит в мире коммерческой разработки на плюсах это абьюзанье шаблонов.
EP>Следует ли из этого это что использование [PLACEHOLDER], делает код абсолютно не читаемым и не поддерживаемым? Нет. EP>Например, goto в кривых руках превращает код в лапшу, а в прямых — это всего лишь инструмент с определённым предназначением
Еще не видел ни одного любителя шаблонов с прямыми руками! Крикунов зато видел.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Не пойму в чём проблема
проблема в том, что он читает только то, что ему удобно читать, и отвечает только на то, на что ему удобно читать. вот и снова жир стекает...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Не пойму в чём проблема
проблема в том, что он читает только то, что ему удобно читать, и задает только те вопросы, которые ему удобно задать, и отвечает только на то, на что ему удобно отвечать. вот и снова жир стекает...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
ОК>>Чувак, вряд ли к твоему мнению можно вообще прислушиваться. Ты там в ветке про Сайберакса ныл про плохой код который ты решил переписать. А теперь ответь, почему ты решил, что никто не прийдет и не скажет что твой говнокод нужно переписать? X>чел, ты читаешь только то, что тебе удобно, мы уже это поняли
Я читаю то что я вижу!
X>про плохой код: я писал, что он плохой и по мнению самого Сайберакса. но тебе-то это не интересно, потому что неудобно
Ну разумеется! Я не сомневаюсь что Сайберакс осознает где у него хороший код а где плохой. Однако в тот код уже были вложены деньги. Поэтому нужно уметь работать с существующим кодом, чего у тебя нет.
X>про мой код: наверняка кто-то таки скажет что мой код плохой, как и говорили уже ранее. но куда мне до тебя-то, о великий!
Мой код поймет даже первокурсник. И да, я понимаю в чем разница между инженером и теми кто дрочит на язык.
Здравствуйте, Олег К., Вы писали:
EP>>"Это не дело вкуса, а дело инженеринга. Мне довелось поддерживать проект в который такие любители запихали [PLACEHOLDER]. Абсолютно нечитаемый и неподдерживаемый код был в тех местах." ОК>Не тупи, а?
Когда заканчиваются аргументы — переходишь на хамство?
ОК>Самое худшее что происходит в мире коммерческой разработки на плюсах это абьюзанье шаблонов.
Abuse шаблонов действительно имеет место быть. И особенно этим грешат те, кто только начинают использовать TMP техники, и не знают как их не использовать.
Но, такой же abuse происходит практически для каждой фичи. Например тот же "классический ООП" — раздуваются совершенно не нужные иерархии, да чего стоят только одни getters&setters в тех местах где достаточно обычной структуры.
Или, например, комментарии — казалось бы, ну что тут-то может быть? А всё туда же — неправильное использование, использование не к месту и т.п.
EP>>Следует ли из этого это что использование [PLACEHOLDER], делает код абсолютно не читаемым и не поддерживаемым? Нет. EP>>Например, goto в кривых руках превращает код в лапшу, а в прямых — это всего лишь инструмент с определённым предназначением ОК>Еще не видел ни одного любителя шаблонов с прямыми руками! Крикунов зато видел.
ОК>>Ты там в ветке про Сайберакса ныл про плохой код который ты решил переписать. А теперь ответь, почему ты решил, что никто не прийдет и не скажет что твой говнокод нужно переписать?
EP>Не пойму в чём проблема если у кого-то код получится объективно лучше чем твой?
Тут проблема вот в чем. На деле каждый считает что его код самый лучший, но ты представь что будет если каждый последущий программист будет приходить и орать "говнокод! надо переписать!"
EP>Или, например, ты разве ни разу не рефакторил свой код, потому нашёл лучший способ решения проблемы?
Постоянно это делаю. Разница только между мной и некоторыми это то что я знаю насколько тяжело бывает поддерживать боевой проект в зависимости от гениальности некоторых личностей. Ну и не дрочу на конструкции языка.
З.Ы. Абьюзанье шаблонов в мире С++ — наихудшее зло, и отрицать этот факт нельзя ну никак!
EP>Но, такой же abuse происходит практически для каждой фичи. Например тот же "классический ООП" — раздуваются совершенно не нужные иерархии, да чего стоят только одни getters&setters, в тех местах где достаточно обычной структуры.
здесь согласен. Особенно были любители паттернов, но вроде волна уже прошла (или они переключились на шаблоны? )
Здравствуйте, Олег К., Вы писали:
EP>>Не пойму в чём проблема если у кого-то код получится объективно лучше чем твой? ОК>На деле каждый считает что его код самый лучший,
Неверно.
ОК>но ты представь что будет если каждый последущий программист будет приходить и орать "говнокод! надо переписать!"
Бросаться с шашкой наголо переписывать каждый код без разбора, в котором есть какие-то проблемы — очевидно нерационально.
А вот, например, сделать заметку об объективных проблемах, рассказать автору о лучших вариантах решения (чтобы он не допускал ошибки впредь, или хотя бы знал об альтернативах) — почему бы и нет?
ОК>З.Ы. Абьюзанье шаблонов в мире С++ — наихудшее зло, и отрицать этот факт нельзя ну никак!
Это не может быть фактом хотя бы потому, что в большинстве существующего кода C++ нет никаких шаблонов, и уж тем более TMP, а проблем-то всё-равно куча
Бред какой то... шаблоны это часть языка, метапрограммирование это по большей части программирование в компайл тайм, это действитльно круто.
Что делать — нужно учиться готовить, совсем не сложно на самом деле.
То ли дело например.... оператор (или как оно в нём называется) @ в языке С# позволяющий в качестве ключевых слов объявлять переменные... вот это действительно идиотизм.
PM>>не люблю Qt X>да, это ужасное творение. но для ГУЯ приходится использовать, увы
Эм... и что в нём ужасного? Отличная библиотека, для GUI... так её и использую.
PM>>Высказывания "не используем boost потому что он слишком сложный" для меня признак низкой квалификации ведущего разработчика. Работать в такой команде — профессионально деградировать. X>угу.
Работал как то в такой, сказали что код должен быть расчитан на среднестатистического программиста и boost запретили использовать.
Но я там не долго работал.
ОК>>Самое худшее что происходит в мире коммерческой разработки на плюсах это абьюзанье шаблонов.
EP>Abuse шаблонов действительно имеет место быть. И особенно этим грешат те, кто только начинают использовать TMP техники, и не знают как их не использовать.
Нормальному инженеру вообще такое в голову не прийдет использовать!
Я, конечно же, допускаю что это может где-то понадобится но не на каждом шагу.
EP>Но, такой же abuse происходит практически для каждой фичи. Например тот же "классический ООП" — раздуваются совершенно не нужные иерархии, да чего стоят только одни getters&setters в тех местах где достаточно обычной структуры.
Нехорошо, конечно же, но жить можно. Главное чтобы код был понятен.
EP>Или, например, комментарии — казалось бы, ну что тут-то может быть? А всё туда же — неправильное использование, использование не к месту и т.п.
EP>>>Следует ли из этого это что использование [PLACEHOLDER], делает код абсолютно не читаемым и не поддерживаемым? Нет. EP>>>Например, goto в кривых руках превращает код в лапшу, а в прямых — это всего лишь инструмент с определённым предназначением ОК>>Еще не видел ни одного любителя шаблонов с прямыми руками! Крикунов зато видел.
EP>Выше по топику был пример использования Spirit
Это был малюсенький кусочек кода. Не знаю где ты его взял и кто автор, но ты бы лучше скопировал кусок кода линий так на 30-40 тысяч как минимум. И да, грамматики тоже надо дебагать.
Ну и вместо этой херни лучше уж написать небольшой парсер с рекурсивным спуском. Речь о небольших грамматиках. Для чего-то более сложного — лекс и бизон плюс что там еще нового есть.
Здравствуйте, slava_phirsov, Вы писали:
_>Примеры — boost::optional (редкостный силос, ИМХО)
Почему? По моему, весьма простая и понятная (особенно, в использовании) штука. Вон и в стандарт её затащить хотят.
Здравствуйте, DarkEld3r, Вы писали:
DE>Почему? По моему, весьма простая и понятная (особенно, в использовании) штука. Вон и в стандарт её затащить хотят.
уже затащили. и any затащили, и filesystem. и сегодня еще std::apply(F&&, std::tuple<Types...>&&) затащили.
но кому оно надо, кто посмел ослушаться оракула?! =)
зы
так как отписаться от темы?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали:
X>уже затащили.
Вроде, ещё в С++14 хотели, но отложили? Или я что-то путают? Если "затащили"в С++17, то это ещё не совсем окончательно.
все что я перечислил — находится в транке, т.е. выйдет в пятой версии GCC. это С++14.
там выше я ошибся насчет неймспейса, оно все в std::experimental.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, Олег К., Вы писали:
ОК>Нормальному инженеру вообще такое в голову не прийдет использовать! ОК>Я, конечно же, допускаю что это может где-то понадобится но не на каждом шагу.
И что делать в таком случае? Искать "ненормального инженера"?
EP>>Но, такой же abuse происходит практически для каждой фичи. Например тот же "классический ООП" — раздуваются совершенно не нужные иерархии, да чего стоят только одни getters&setters в тех местах где достаточно обычной структуры. ОК>Нехорошо, конечно же, но жить можно. Главное чтобы код был понятен.
Развесистые иерархии (которые не к месту) усложняют понимание и использование. Точно также как и abuse TMP.
EP>>Выше по топику был пример использования Spirit
. Покажи где там нечитаемый код. ОК>Это был малюсенький кусочек кода. Не знаю где ты его взял и кто автор, но ты бы лучше скопировал кусок кода линий так на 30-40 тысяч как минимум.
Там ссылка есть на полный код, автор я.
ОК>Ну и вместо этой херни лучше уж написать небольшой парсер с рекурсивным спуском. Речь о небольших грамматиках.
А можно вместо сотен строк написать десятки. Причём где и что лучше зависит от ситуации
А вот априорно заявлять что один вариант хуже другого для всех ситуаций, при том что у каждого есть свои уникальные объективные преимущества — мягко говоря не разумно
ОК>И да, грамматики тоже надо дебагать.
В Spirit'е есть уже готовый подробный дамп процесса парсинга — почему, где и что сматчилось, а где нет.
Здравствуйте, nen777w, Вы писали:
N>Работал как то в такой, сказали что код должен быть расчитан на среднестатистического программиста и boost запретили использовать.
Очень правильное решение. С точки зрения коммерческой разработки ПО, а не с точки зрения cpp-гика, которому некуда тратить свободное время.
сорри, обшибся.
filesystem пока не закоммитили. просто на прошлой неделе в списке рассылки Jonatan Wakely постил реализацию, ее обсуждали. чем закончилось — не знаю. но, раз уж таки не закомитили — значит отправили на доработку.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, kurchatov, Вы писали:
N>>Работал как то в такой, сказали что код должен быть расчитан на среднестатистического программиста и boost запретили использовать. K>Очень правильное решение. С точки зрения коммерческой разработки ПО, а не с точки зрения cpp-гика, которому некуда тратить свободное время.
Где-то действительно есть смысл запрещать библиотеки, а где-то даже некоторые конструкции языка.
Но, задачи-то бывают совершенно разные — не пойму зачем распространять какие-то рецепты подошедшие лично тебе, в конкретном случае, на всю коммерческую разработку ПО?
Маленький пример — в одной части проекта (коммерческого!) мне понадобилась Fibonacci Heap, я взял boost::heap::fibonacci_heap и использую без всяких проблем — простой и понятный интерфейс. Что тут такого ужасного с твоей сферически-коммерческой точки зрения?
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Маленький пример — в одной части проекта (коммерческого!) мне понадобилась Fibonacci Heap, я взял boost::heap::fibonacci_heap и использую без всяких проблем — простой и понятный интерфейс. Что тут такого ужасного с твоей сферически-коммерческой точки зрения?
да отлично! Я тоже люблю boost::lexical_cast
Spirit и прочий фьюжн — совершенно другой уровень и порог вхождения.
Здравствуйте, NeoCode, Вы писали:
NC>Я тоже не очень с этими шаблонами... вот прямо сейчас сижу разбираюсь. Просто раньше я как-то избегал излишнего метапрограммирования, а тут попался проект с достаточно глубоким уровнем применения матапрограммирования. Понемногу разбираюсь.
Главное понять, что шаблоны это функциональный язык.
Остальное просто.
NC>Но считаю что врага надо знать в лицо У меня тоже есть хобби — разработка своего языка программирования, не менее (и даже гораздо более) мощного чем С++, но без всей этой головной боли.
А можно подробнее?
Ибо у меня разработка языков не хобби.
NC>И для того чтобы это сделать наилучшим образом, считаю что нужно знать и С++ в совершенстве,
Лучше знать немерле.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, nen777w, Вы писали:
PM>>>не люблю Qt X>>да, это ужасное творение. но для ГУЯ приходится использовать, увы
N>Эм... и что в нём ужасного? Отличная библиотека, для GUI... так её и использую.
Для кросс-платформенного GUI других вариантов нет, так что с Qt приходится мириться. Мне Qt не нравится потому что:
Имеет достаточно давнюю историю и несет груз решений, принятых почти 20 лет назад из которых вытекают следующие пункты
Пытается быть мега-фреймворком со своими строками, сокетами, файлами и т.п.
Неоднозначная политика владения дочерними объектами
Жесткая связка модель-вид, где шаг влево или вправо от принятой концепции модели карается хаками в реализации views.
Я не слежу за развитием Qt Quick, так что может быть там все гораздо лучше. Но из моего скромного опыта использования, использовать Qt в С++ в 2014 году — это как MFC в начале 2000-х. Вроде бы и альтернатив нет, но уже устарело морально. Поэтому я предпочитаю проекты без GUI
PM>>>Высказывания "не используем boost потому что он слишком сложный" для меня признак низкой квалификации ведущего разработчика. Работать в такой команде — профессионально деградировать. X>>угу. N>Работал как то в такой, сказали что код должен быть расчитан на среднестатистического программиста и boost запретили использовать. N>Но я там не долго работал.
Я не зря упомянул ведущего. В команде могут быть новички, не очень опытные разработчики, которые не знают множества граблей С++, не дружат с Boost. Но если есть хоть один человек, для которого использовать Boost не проблема, и он умеет делиться своим знанием и помогать остальным (а это одна из основных ролей ведущего программиста), то он подтянет уровень остальных. Если такого человека нет, проект на С++ рано или поздно загнется. А неосилятор boost будет писать в интернете какой этот С++ сложный — от него сплошные утечки памяти и падения софта.
ps. Пока отвечал, тему уже в флейм снесли из-за одного тролля, который в разделе С++ особо и не отмечался
Здравствуйте, niXman, Вы писали:
X>Здравствуйте, DarkEld3r, Вы писали:
X>все что я перечислил — находится в транке, т.е. выйдет в пятой версии GCC. это С++14. X>там выше я ошибся насчет неймспейса, оно все в std::experimental.
Ну раз эксперементальное, то всё-таки не C++14. Впрочем, я не сомневаюсь, что рано или поздно в стандарт оно всё-таки попадёт.
Мне Qt тоже не кажется идеальным фреймворком, но отдельные пунты не могу не прокомментировать.
PM>Имеет достаточно давнюю историю и несет груз решений, принятых почти 20 лет назад из которых вытекают следующие пункты
Само по себе это не недостаток. Скорее наоборот — тем более, что ряд классов/функций выкидывались переписывались, то есть нельзя сказать, что они не внедряют улучшения и тащат за собой легаси.
PM>Пытается быть мега-фреймворком со своими строками, сокетами, файлами и т.п.
Так ли это плохо? Скажем, строки у них весьма удобны. Ничего подобного в стандарте или даже бусте нет. Файлы тоже удобнее стандартных.
А их контейнеры совместимы с стлевскими алгоритмами и наоборот.
PM>Неоднозначная политика владения дочерними объектами
Она вполне однозначная в рамках фреймворка. (: В том смысле, что ничего неожиданного не происходит. Опять же, местами удобно.
PM>Жесткая связка модель-вид, где шаг влево или вправо от принятой концепции модели карается хаками в реализации views.
Ну это да. Хотя возможно "по старинке" пользоваться контролами без связки с модель/вью.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Недостаток языка — это отсутствие compile-time reflection, Boost.Fusion для этого предлагает макросы BOOST_FUSION_DEFINE_STRUCT и подобные. EP>А вот те методы работы, которые предлагает Boost.Fusion с уже адаптированными структурами (то есть для которые есть необходимые гетерогенные итераторы) — вполне себе, ничего костыльного.
Нуу тут вопрос вот в чём — если бы у нас уже была интроспекция в языке, то стали бы мы использовать подобное? Соответственно все варианты где ответ "нет не стали бы, но пока приходится" являются сильно костыльным. На мой вкус конечно же...
EP>Даже как-то сравнивали в этом отношении Boost.Fusion vs Nemerle vs D (Fusion
Здравствуйте, Олег К., Вы писали:
ОК>Ты видимо никогда не поддерживал код в который такие любители запихали Спирит. Иначе бы быстро поменял мнение.
Ну так я что бы ты запихал на их месте? ) Опишу задачку и свой вариант решения...
ОК>Жесть какая-то. Чтобы прочитать цсв Спирит не нужен!
Нужен/ненужен — это не разговор в мире разработки. Формально можно вообще всё на ассемблере написать и сказать что остальное не нужно. Разговор у нас идёт о минимизации усилий по написанию кода. Желательно при этом с одновременной максимизацией надёжности и быстродействия.
Здравствуйте, slava_phirsov, Вы писали:
_>А желающие — тратят его на написание каких-то своих шикарных костылей к готовым бустовским байкам. По сути так на так и выходит. Плюсы при использовании буста — человеку со стороны, знающему конкретную примененную часть буста проще понять код (ну, ему еще надо будет разобраться в прилагающихся костылях, но это, допустим, мелочи). Минусы — любое обобщенное решение сложно, а значит потенциально ненадежно и потенциально неоптимально. Примеры — boost::optional (редкостный силос, ИМХО) и boost::asio (без слез и мата работать с ним невозможно). Или вот, скажем, boost::circular_buffer. Ну просится, просится сделать не буфер, а просто адаптер-итератор, гораздо полезнее, ИМХО, но итератор — это не по-пацански, на нем не показать, что ты умеешь аллокаторы и move-semantics, потому и целый, извините, буфер.
Хыхы, кстати optional — это считай уже не boost, а стандарт языка. )))
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, slava_phirsov, Вы писали:
_>>А желающие — тратят его на написание каких-то своих шикарных костылей к готовым бустовским байкам. По сути так на так и выходит. Плюсы при использовании буста — человеку со стороны, знающему конкретную примененную часть буста проще понять код (ну, ему еще надо будет разобраться в прилагающихся костылях, но это, допустим, мелочи). Минусы — любое обобщенное решение сложно, а значит потенциально ненадежно и потенциально неоптимально. Примеры — boost::optional (редкостный силос, ИМХО) и boost::asio (без слез и мата работать с ним невозможно). Или вот, скажем, boost::circular_buffer. Ну просится, просится сделать не буфер, а просто адаптер-итератор, гораздо полезнее, ИМХО, но итератор — это не по-пацански, на нем не показать, что ты умеешь аллокаторы и move-semantics, потому и целый, извините, буфер.
_>Хыхы, кстати optional — это считай уже не boost, а стандарт языка. )))
Здравствуйте, PM, Вы писали:
PM>Для кросс-платформенного GUI других вариантов нет, так что с Qt приходится мириться.
Да ладно... Если говорить о чём-то сравнимом, то как минимум wxWidgets имеет такую же мощь и при этом без сомнительного извращения языка. Если же смотреть не только на такие глобальные фреймворки и не требовать обязательно нативных контролов (кстати, насколько я помню в Qt они и не такие, но хотя бы притворяются), то возникает ещё целая куча вариантов (gtk+/gtkmm, fltk, juce и т.д. и т.п.).
Здравствуйте, alex_public, Вы писали:
_>Что-то там код слегка разный вроде. Ну да не принципиально, главное же идея обхода. ) Ну и да, на C++ тут самый симпатичный вариант.
Вот только он не решает поставленную задачу: http://rsdn.ru/forum/philosophy/5341291.1
Здравствуйте, kurchatov, Вы писали:
K>Откуда пошла эта мода на обмазывание шаблонами к месту и не к месту? Нет, я ничего не имею против шаблонов, если действительно надо — только приветствую. K>Но в последние годы появился какой-то особенный класс С++ программистов, которые пихают шаблоны везде, делая код и ошибки компиляции нечитаемыми. K>Такие люди пишут код, обмазанный шаблонами — и говорят "смотрите, как просто и красиво!". Да нихрена не просто и не красиво! Разбор такого кода вызывает у меня только головную боль.
Думаю, это началось с того момента когда Александреску отрыл тайны шаблонной магии. Получив чудесные знания многие просто не удерживаются от того, чтобы применить их на практике где нужно и где нет (что чаще всего). Со временем, конечно, желание баловаться с шаблонами отпадает. Но из-за того, что постоянно появляются молодые подаваны верующие в то, что путь джедая С++ лежит через шаблонный мазохизм, "мода на обмазывание шаблонами к месту и не к месту", скорее всего, умрет не раньше самого С++...
Здравствуйте, alex_public, Вы писали:
EP>>Недостаток языка — это отсутствие compile-time reflection, Boost.Fusion для этого предлагает макросы BOOST_FUSION_DEFINE_STRUCT и подобные. EP>>А вот те методы работы, которые предлагает Boost.Fusion с уже адаптированными структурами (то есть для которые есть необходимые гетерогенные итераторы) — вполне себе, ничего костыльного. _>Нуу тут вопрос вот в чём — если бы у нас уже была интроспекция в языке, то стали бы мы использовать подобное? Соответственно все варианты где ответ "нет не стали бы, но пока приходится" являются сильно костыльным. На мой вкус конечно же...
Не, так о том же и речь — compile-time reflection будет скорей всего в виде специализаций шаблонов для интроспектируемых типов.
Например, что-то типа:
То есть по сути задаётся гетерогенная последовательность. Обходить её "вручную", то есть какой-нибудь рекурсией по std::fields_count не удобно.
С другой стороны, в Boost.Fusion уже есть готовые высокоуровневые алгоритмы для работы с подобными гетерогенными последовательностями — for_each, fold, filter, transform, join, zip, etc. Для их использования достаточно написать адаптер для traits предоставленных compile-time reflection.
То есть даже когда появится compile-time reflection — Boost.Fusion будет удобным способом его использования (если конечно в стандарт не войдёт ещё и аналог Fusion).
Здравствуйте, kurchatov, Вы писали:
K>Откуда пошла эта мода на обмазывание шаблонами к месту и не к месту?
Это засилье в отрасли понтарезов и олимпиадников, которые не осилили разработку на функциональных ЯП,
но которым выпендренуться, по разным причинам, требуется. Они и уцепились за сущности aka "Метапрограммирование,
Boost.Fusion, Boost.Mpl...". Но выглянуть из песочницы у них кругозора не хватает.
В Lisp красиво, без того уродства, коим являются шаблоны C++, любая, и самая сложная, грамматика, парсится в несколько десятков строк.
Здравствуйте, smeeld, Вы писали:
S>В Lisp красиво, без того уродства, коим являются шаблоны C++, любая, и самая сложная, грамматика, парсится в несколько десятков строк.
Ну так в LISP уродливо всё остальное.
WH>В том треде Evgeny.Panasyuk накидал кучу гнилых отмазок и слился.
Нуу на самом деле не помню каких-то особых претензий там к нему. Основное, что он реализовал отдельную функцию, а не функцию-член. Ну так это в C++ это как раз не проблема поправить, благодаря множественному наследованию.
Проблема в том, что модность обсуждаемого кода идёт уже как бы поверх эмуляции интроспекции. И в этом смысле код действительно красив. Но если взглянуть на эту эмуляцию, то естественно ужас ужас ужас.
В общем моё мнение тут такое: как только в C++ появится нормальная интроспекция (естественно времени компиляции), то пример Евгения честно можно будет позиционировать как полноценное решение, причём оно возможно будет ещё и самым красивым. Ну а пока...
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>С другой стороны, в Boost.Fusion уже есть готовые высокоуровневые алгоритмы для работы с подобными гетерогенными последовательностями — for_each, fold, filter, transform, join, zip, etc. Для их использования достаточно написать адаптер для traits предоставленных compile-time reflection.
Да, удобные штуки. Кстати, в том же D я помнится так и не нашёл готового "static_foreach", так что для некоторых случаев приходилось писать ту самую рекурсию на шаблонах, в лучших традициях C++. )))
EP>То есть даже когда появится compile-time reflection — Boost.Fusion будет удобным способом его использования (если конечно в стандарт не войдёт ещё и аналог Fusion).
Да уж не важно как, хорошо бы только побыстрее. А то это уж очень заметный недостаток, причём для целых областей)
Здравствуйте, WolfHound, Вы писали:
_>>Что-то там код слегка разный вроде. Ну да не принципиально, главное же идея обхода. ) Ну и да, на C++ тут самый симпатичный вариант. WH>Вот только он не решает поставленную задачу: http://rsdn.ru/forum/philosophy/5341291.1
Эту "Помечаем его атрибутом/аннотацией [...] добавленную в класс"? Если дословно, то да — не решает.
Но конкретно в данном топике мы обсуждаем алгоритмы обхода гетерогенных последовательностей и Boost.Fusion в частности.
Если в Nemerle есть что-то готовое на эту тему, то можешь показать. Например, аналог чего-то вот такого:
auto println = [](auto... xs)
{
initializer_list<int>({(cout << xs << " ", 0)...});
cout << endl;
};
BOOST_FUSION_DEFINE_STRUCT
(
(), Foo,
(int, x)
(double, y)
)
BOOST_FUSION_DEFINE_STRUCT
(
(), Bar,
(complex<double>, u)
(string, v)
)
auto compose = [](auto f, auto g)
{
return [=](auto... xs)
{
return f(g(xs...));
};
};
auto apply = [](auto f, auto g, auto... xs)
{
auto z = zip(xs..., transform(xs, compose(g, g))...);
for_each(z, [=](auto x)
{
invoke(f, x);
});
};int main()
{
Foo a = {1, .1};
a.x *= 2;
Bar b = {{1, 2}, "a"};
b.v += 'b';
auto double_it = [](auto x) { return x + x; };
apply(println, double_it, a, b, make_vector(b.v + 'c', cos(b.u)));
}
Естественно без потери гибкости — например apply можно передать в стороннюю библиотеку, которая может вызывать его с разными наборами аргументов и т.п.
Где: zip — zip'ует несколько гетерогенных последовательностей в одну. transform, соответственно, трансформирует а-ля map. Причём трансформация может переводить в другой тип. for_each — обходит гетерогенную последовательность. invoke — вызывает "функцию" аргументами из гетерогенной последовательности, т.е. explode или распаковка.
Причём это всё работает со структурами (Foo, Bar), с кортежами/tuples (make_vector), да и вообще со всем что удовлетворяет необходимым концепциям (например "виртуальная" последовательность, не хранящая значений внутри).
WH>В том треде Evgeny.Panasyuk накидал кучу гнилых отмазок и слился.
Кстати, стандартное возражение, что IDE перестает работать на таких макросах, обходится довольно просто — у меня в команду, которая зовет ctags, добавлен простой перловый скрипт, который генерит правильные ссылки на структуры/поля, объявленные подобными макросами, так что все среды, которые основаны на работе с ctags (а это, в частности, vi и emacs, ну и мой любимый NEdit), видят эти макросы как обычные структуры с обычными полями.
(естественно, всякие автоматические рефакторинги для них не работают без дополнительного программирования. Но с подобными структурами вообще опасно какие-либо автоматические рефакторинги проводить, так как они предоставляют доступ "в обход" нормального через имена полей. Хотя, конечно, нет ничего невозможного.)
Здравствуйте, PM, Вы писали:
PM>>>Для добавления экстремальности я бы еще добавил boost.preprocessor в эту компанию X>>замечательная либа позволяющая делать замечательные вещи PM>Наверно иногда да. Но на мой взгляд, препроцессор, как он сейчас есть в С/С++ довольно опасная вещь.
Самая безобидная вещь в с++, можно легко получить результат препроцессинга и понять где ошибся. Очень мощный плюс, где вы ещё такой в с++ найдёте?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, alex_public, Вы писали:
_>Хыхы, кстати optional — это считай уже не boost, а стандарт языка. )))
Ну в стандарте много всякого было — и неоднократно проклятый vector<bool>, и спецификации исключений, и встроенные массивы для облегчения членовредительства ... Что касается optional, то вот (просто например) объясни, зачем в нем определены operator-> и operator* : optional — не указатель, и предназначен не для того совсем, а с ним используется синтаксис указателей. "Похожие вещи должны выглядеть похоже, а разные — по-разному". Это все равно, как если бы в vector были бы определены operator+ (для дублирования push_back) и оператор-- (для дублирования pop_back).
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Здравствуйте, Cyberax, Вы писали:
S>>В Lisp красиво, без того уродства, коим являются шаблоны C++, любая, и самая сложная, грамматика, парсится в несколько десятков строк. C>Ну так в LISP уродливо всё остальное.
Здравствуйте, alex_public, Вы писали:
_>Нужен/ненужен — это не разговор в мире разработки. Формально можно вообще всё на ассемблере написать и сказать что остальное не нужно. Разговор у нас идёт о минимизации усилий по написанию кода.
. Покажи где там нечитаемый код. F>но там же нет шаблонов.
Там есть шаблоны, но не в смысле TMP (хотя если учитывать внутренности Spirit'а, то и в TMP смысле в том числе).
А вообще, выше же по ветке было:
K>>>Да вот только не EBNF она предоставляет, а нечитаемую пародию на него.
P>>Дело скорее вкуса. Достаточно быстро адаптируешься, а для задач, под которые, как я считаю он более всего подходит (см. ниже) — большего и не надо.
ОК>Это не дело вкуса, а дело инженеринга. Мне довелось поддерживать проект в который такие любители запихали Спирит. Абсолютно нечитаемый и неподдерживаемый код был в тех местах.
Здравствуйте, kurchatov, Вы писали:
K>Такие люди пишут код, обмазанный шаблонами — и говорят "смотрите, как просто и красиво!". Да нихрена не просто и не красиво! Разбор такого кода вызывает у меня только головную боль.
K>Если все еще непонятно, о чем говорю — приведу пример — boost::spirit. Это просто экстремум шаблонофилии.
Проблема с метапрограммированием не в спирите. Спирит это пример относительно внятного применения шаблонов. Если знаешь про парсеры, то спирит достаточно понятный.
Мулька в том, что такие рафинированые случаи применения скорее исключения. Большей частью в мета-код приходится влазить по уши, потому что автор реализовал идейку одному ему понятную. Метакод, что характерно, затрудняет исследование целевого результата. То есть, конечный результат хуже просматривается.
С шаблонами навроде T4 еще куда ни шло, хотя бы структура видна. Более сильные техники равносильны практически обфускации.
Пример:
var sb = new StringBuilder();
GetSomeText(sb); // нативная функция
Код содержит большую дыру. Такие дыры хочется исключать всеми способами, скажем, очень эффективный — code review. Но вот фокус — этот код спрятан унутре макроса примерно так
body.NativeCall(GetSomeText);
Вопрос — каким образом ревьюеру надо догадываться про такие вот детали ?
Похожая проблема — слияние версией. При слиянии приходится выполнять двойную работу, т.к. корректное слияние макро-кода не гарантирует корректного выхлопа, который собтсвенно и не виден.
И вот на ровном месте появляются те самые паттерны, от которых, по идее, макры должы избавлять. То есть, годится не любой говнопарсинг, запиханый в макры, а только православный, с четкой формализацией, прозрачной моделью и тд и тд. Произвольная схема взаимодействия окажется скорее всего говном, а вот широко известный паттерн Property Changed вполне сгодится.
Прятать эвристики, разные детали, которые меняют важность в зависимости от рассматриваемого аспекта, практически преступление.
Здравствуйте, Vain, Вы писали:
PM>>Наверно иногда да. Но на мой взгляд, препроцессор, как он сейчас есть в С/С++ довольно опасная вещь. V>Самая безобидная вещь в с++, можно легко получить результат препроцессинга и понять где ошибся. Очень мощный плюс, где вы ещё такой в с++ найдёте?
Угу, промотав пару мегабайт включенных заголовков. Вам когда-нибудь приходилось вызывать функции типа Sleep, GetMessage из каких-нибудь сторонних библиотек? При компиляции под Windows на ровном месте вываливается ошибка о несоответствии типов аргументов. И по неопытности можно долго ломать голову, глядя на абсолютно корректный вызов, имея #define GetMessage GetMessageW где-то в неявно включенном windows.h
Здравствуйте, alex_public, Вы писали:
_>Нуу на самом деле не помню каких-то особых претензий там к нему. Основное, что он реализовал отдельную функцию, а не функцию-член. Ну так это в C++ это как раз не проблема поправить, благодаря множественному наследованию.
И как ты множественным наследованием собрался реализовать абстрактный метод?
error C2259: 'Foo' : cannot instantiate abstract class
_>В общем моё мнение тут такое: как только в C++ появится нормальная интроспекция (естественно времени компиляции), то пример Евгения честно можно будет позиционировать как полноценное решение, причём оно возможно будет ещё и самым красивым. Ну а пока...
Нельзя. Плюс я могу придумать ещё миллион задач которые на шаблонах С++ не решить.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Если в Nemerle есть что-то готовое на эту тему, то можешь показать. Например, аналог чего-то вот такого:
Готового нет. При желании можно сделать. Но никто это делать не будет, ибо макросы всё равно мощнее.
Но главная проблема этого примера в том, что он не решает осмысленную задачу.
Осмысленная задача звучит примерно так: Добавить во все методы классов находящихся в заданном пространстве имён логирование.
"?
Именно это ты и сделал.
EP>А вообще, градус озлобленности у евангелистов Nemerle поражает
Поражает привычка людей решать задачу, которую не просили, и делать далеко идущие выводы.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Abyx, Вы писали:
WH>>И как ты множественным наследованием собрался реализовать абстрактный метод? A>using ITestImpl::Test(); же
И так в каждом классе для десятка методов...
При том, что на немерле можно написать макрос, которому для реализации всего, что надо хватит одного факта наследования от ITest.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, alex_public, Вы писали:
PM>>Для кросс-платформенного GUI других вариантов нет, так что с Qt приходится мириться.
_>Да ладно... Если говорить о чём-то сравнимом, то как минимум wxWidgets имеет такую же мощь и при этом без сомнительного извращения языка. Если же смотреть не только на такие глобальные фреймворки и не требовать обязательно нативных контролов (кстати, насколько я помню в Qt они и не такие, но хотя бы притворяются), то возникает ещё целая куча вариантов (gtk+/gtkmm, fltk, juce и т.д. и т.п.).
Гм, да, про wxWidgets забыл. И не только один я Сходил на сайт, судя по новостям, wxWidgets даже обновляются. Но вот растут они тоже из начала 90-х и архитектурно от MFC мало отличаются.
Остальные библиотеки настолько экзотика, что даже лень про них искать что-то. Ну вообще, я к счастью уже пару лет как отошел от GUI, так что могу быть некомпетентен.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Abyx, Вы писали:
WH>>>И как ты множественным наследованием собрался реализовать абстрактный метод? A>>using ITestImpl::Test(); же WH>И так в каждом классе для десятка методов... WH>При том, что на немерле можно написать макрос, которому для реализации всего, что надо хватит одного факта наследования от ITest.
круто, только если взять количество людей пишущих на С++, и поделить на количество людей пишущих на Немерле, получится +Inf
Здравствуйте, WolfHound, Вы писали:
EP>>Если в Nemerle есть что-то готовое на эту тему, то можешь показать. Например, аналог чего-то вот такого: WH>Готового нет. При желании можно сделать. Но никто это делать не будет, ибо макросы всё равно мощнее.
Хотелось бы увидеть пример подобной функции apply. Допустим что библиотека реализована — как оно будет выглядеть?
WH>Но главная проблема этого примера в том, что он не решает осмысленную задачу. WH>Осмысленная задача звучит примерно так: Добавить во все методы классов находящихся в заданном пространстве имён логирование.
Это практически такой же сферический конь. Для меня реальная задача — это какой-нибудь прикладной алгоритм, а не сферическое вычисление чисел Фиббоначи через мемоизацию. Хотя для кого-то алгоритмы будут сферическими, а AOP — самый смак. Вопрос терминологический
WH>А вот опыта реального человека, который делал на немерле реальный проект: http://rsdn.ru/forum/nemerle/4812833.1
Уже читал, и как я уже писал — Nemerle реально впечатляет Особенно определение своего синтаксиса для макросов, а также кооперация IDE и строк-DSL'ей.
(Нужен будет .NET — обязательно посмотрю в сторону Nemerle (как минимум потому что C# слишком дубовый). На данный же момент мне важна скорость, кроссплатформенность и некоторые нативные библиотеки)
EP>>"Слился" это означает "оппонент ничего толком не ответил, и не показал хотя бы полный рабочий код
Полного рабочего кода на Nemerle не было, точно также как и ответа на сообщение по ссылке
WH>и делать далеко идущие выводы.
Какие именно? Ты же сам выше и подтвердил — что для гетерогенных последовательностей в Nemerle ничего готового нет, именно об этом и шла речь в топике.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Хотелось бы увидеть пример подобной функции apply. Допустим что библиотека реализована — как оно будет выглядеть?
Примерно так:
tempalte apply(f : auto, g : auto, xs : list[auto]) : auto
{
def z = zip(xs, transform(xs, compose(g, g)));
for_each(x in z)
{
f(x);
}
}
EP>Это практически такой же сферический конь.
В твоём примере вообще задачи нет. Те совсем. Никакой.
EP>Для меня реальная задача — это какой-нибудь прикладной алгоритм,
Для меня тоже. Только у меня всё на макросах.
Размер Nitra.Grammar и Nitra.Compiler можешь посмотреть сам.
EP>Уже читал, и как я уже писал — Nemerle реально впечатляет Особенно определение своего синтаксиса для макросов, а также кооперация IDE и строк-DSL'ей.
Ты плохо читал.
Вторая итерация была сильно позже (2009г) и умели мы гораздо больше, но понимали всё ещё столько же . Ну правильно, макросов же ещё не писали толком. А главное, пока было оплачиваемое время между первой и второй итерациями, — лепили фреймворк. И не то чтобы он оказался совсем не нужен, просто наше представление о программирование было всё ещё сильно искажено призмой C# и даже C++.
А теперь ДЗЕН вынесенный из этого проекта:
Ближе к концу мы уже не стремились лепить библиотечные навороты и расширять фреймворк, а скорее старались заменять макросами рукопашный код насовсем но локально. Т.е. гораздо проще разработать какую-то феньку нужную в 5 местах и без параметров, и какую-то очень похожую феньку (даже внешне точно такую-же) для 5 других мест, чем лепить универсальную, конфигурируемую через кучу параметров мега-фень, способную покрыть все эти 10 мест и ещё 20 гипотетических похожих.
Это ключевые моменты.
Остальное это просто пояснение, почему это именно так.
Ты тут просишь слепить фреймворк. А он не нужен.
Уж поверь практикам.
EP>Полного рабочего кода на Nemerle не было,
А это что? http://rsdn.ru/forum/philosophy/5342142.1
Здравствуйте, WolfHound, Вы писали:
EP>>Хотелось бы увидеть пример подобной функции apply. Допустим что библиотека реализована — как оно будет выглядеть? WH>Примерно так: WH>
WH>tempalte apply(f : auto, g : auto, xs : list[auto]) : auto
WH>{
WH> def z = zip(xs, transform(xs, compose(g, g)));
WH> for_each(x in z)
WH> {
WH> f(x);
WH> }
WH>}
WH>
Этот apply можно передать в стороннюю библиотеку (которая будет вызывать её с разными наборами параметров)?
EP>>Это практически такой же сферический конь. WH>В твоём примере вообще задачи нет. Те совсем. Никакой.
Работа с гетерогенными последовательностями — вполне себе задача, такая же как и работа с гомогенными
EP>>Уже читал, и как я уже писал — Nemerle реально впечатляет Особенно определение своего синтаксиса для макросов, а также кооперация IDE и строк-DSL'ей. WH>Ты плохо читал.
"Чепуху говорите, и возмутительнее всего то, что говорите ее безапелляционно и уверенно."
WH>
WH>А теперь ДЗЕН вынесенный из этого проекта:
WH>Ближе к концу мы уже не стремились лепить библиотечные навороты и расширять фреймворк, а скорее старались заменять макросами рукопашный код насовсем но локально. Т.е. гораздо проще разработать какую-то феньку нужную в 5 местах и без параметров, и какую-то очень похожую феньку (даже внешне точно такую-же) для 5 других мест, чем лепить универсальную, конфигурируемую через кучу параметров мега-фень, способную покрыть все эти 10 мест и ещё 20 гипотетических похожих.
С этим моментом я как раз и не согласен.
"универсальную, конфигурируемую через кучу параметров мега-фень" — всего лишь означает что не найдена правильная абстракция, либо найдена, но реализация которой не оправданна.
Множество немного отличающихся друг от друга макросов, также плохо как и повторяющийся с небольшими отличиями код.
То что в каком-то конкретном случае с этим boilerplate'ом смирились, не означает с ним нужно мириться всегда. Точно также кто-то мирится с дубликацией и в обычном коде.
WH>Ты тут просишь слепить фреймворк. А он не нужен. WH>Уж поверь практикам.
Framework я точно не просил. Между framework'ами и библиотеками огромная разница. Framework это скафандр ограничивающий движения, а библиотека это ручной инструмент.
EP>>Полного рабочего кода на Nemerle не было, WH>А это что? WH>http://rsdn.ru/forum/philosophy/5342142.1
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Этот apply можно передать в стороннюю библиотеку (которая будет вызывать её с разными наборами параметров)?
При условии, что это шаблонная библиотека.
Но в С++ то же самое ограничение.
EP>Работа с гетерогенными последовательностями — вполне себе задача, такая же как и работа с гомогенными
Это не задача. Это в лучшем случае решение.
Как звучит задача, я сказал.
EP>С этим моментом я как раз и не согласен.
В начале проекта hi_octane тоже был не согласен.
EP>"универсальную, конфигурируемую через кучу параметров мега-фень" — всего лишь означает что не найдена правильная абстракция, либо найдена, но реализация которой не оправданна.
Ох... hi_octane по граблям уже попрыгал. Но его ты слушать не хочешь. Ну, продолжай есть кактус.
EP>Framework я точно не просил. Между framework'ами и библиотеками огромная разница. Framework это скафандр ограничивающий движения, а библиотека это ручной инструмент.
Именно его ты и просишь.
Ты просишь шаблоны С++ но на немерле. Их сделать можно. Но это и есть фреймворк.
Например, написать код, который в случае если класс отнаследовн от определенного интерфейса реализовывал бы этот интерфейс, с помощью этого фреймворка ты не сможешь.
EP>>>Полного рабочего кода на Nemerle не было, WH>>А это что? WH>>http://rsdn.ru/forum/philosophy/5342142.1
EP>Обрезок с мясокомбината.
И чего же в нём не хватает?
EP>>>точно также как и ответа на сообщение по ссылке WH>>А на что там вообще отвечать то? EP>То есть "слился" = "не получил ответ, отвечать-то не на что"? M'kay
Слился = не представил решение задачи и развёл тонну демагогии.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
EP>>Этот apply можно передать в стороннюю библиотеку (которая будет вызывать её с разными наборами параметров)? WH>При условии, что это шаблонная библиотека.
И сколько вообще шаблонных библиотек на Nemerle?
EP>>Работа с гетерогенными последовательностями — вполне себе задача, такая же как и работа с гомогенными WH>Это не задача. Это в лучшем случае решение. WH>Как звучит задача, я сказал.
"Добавить во все методы классов находящихся в заданном пространстве имён логирование" — это точно такое же решение какой-то проблемы.
EP>>"универсальную, конфигурируемую через кучу параметров мега-фень" — всего лишь означает что не найдена правильная абстракция, либо найдена, но реализация которой не оправданна. WH>Ох... hi_octane по граблям уже попрыгал. Но его ты слушать не хочешь. Ну, продолжай есть кактус.
Со следующим тезисом согласен?
По возможности следует обобщать регулярно дублирующийся код/макро-генерацию в отдельные именованные сущности (и группировать их в библиотеки).
EP>>Framework я точно не просил. Между framework'ами и библиотеками огромная разница. Framework это скафандр ограничивающий движения, а библиотека это ручной инструмент. WH>Именно его ты и просишь. WH>Ты просишь шаблоны С++ но на немерле. Их сделать можно. Но это и есть фреймворк.
Шаблоны это только одно из конкретных решений. Подобная задача решается на Python'е без шаблонов.
В сухом остатке — на данный момент в Nemerle нет ни то что библиотеки для гетерогенных последовательностей, а даже и готовых языковых фич для описания её интерфейса (можешь называть это хоть фрейворком — сути это не меняет).
EP>>>>Полного рабочего кода на Nemerle не было, WH>>>А это что? WH>>>http://rsdn.ru/forum/philosophy/5342142.1
EP>>Обрезок с мясокомбината. WH>И чего же в нём не хватает?
Как минимум полного рабочего кода, а желательно online demo.
EP>>>>точно также как и ответа на сообщение по ссылке WH>>>А на что там вообще отвечать то? EP>>То есть "слился" = "не получил ответ, отвечать-то не на что"? M'kay WH>Слился = не представил решение задачи и развёл тонну демагогии.
Демагогия это вот это? "Но никто это делать не будет, ибо макросы всё равно мощнее."
Здравствуйте, slava_phirsov, Вы писали:
_>Ну в стандарте много всякого было — и неоднократно проклятый vector<bool>, и спецификации исключений, и встроенные массивы для облегчения членовредительства ... Что касается optional, то вот (просто например) объясни, зачем в нем определены operator-> и operator* : optional — не указатель, и предназначен не для того совсем, а с ним используется синтаксис указателей. "Похожие вещи должны выглядеть похоже, а разные — по-разному". Это все равно, как если бы в vector были бы определены operator+ (для дублирования push_back) и оператор-- (для дублирования pop_back).
А что не так со встроенными массивами? )
Насчёт optional... Ну всё же это некий контейнер, так что некие аналогии (скажем с xxx_ptr) имеются. )
Кстати, например в D добавление в массив реализуется оператором "=+" — всё вполне удобно. )
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>И сколько вообще шаблонных библиотек на Nemerle?
Нисколько. Ибо шаблоны в немерле не нужны.
EP>"Добавить во все методы классов находящихся в заданном пространстве имён логирование" — это точно такое же решение какой-то проблемы.
Нет. Это именно задача.
Именно так будет написано в трекере.
При этом никто в здравом уме не напишет в трекере "обработать гетерогенную последовательность".
EP>Со следующим тезисом согласен? EP>По возможности следует обобщать регулярно дублирующийся код/макро-генерацию в отдельные именованные сущности (и группировать их в библиотеки).
Я тоже за всё хорошее и против всего плохого.
EP>Шаблоны это только одно из конкретных решений. Подобная задача решается на Python'е без шаблонов.
Динамическая типизация давно реализована. Но что характерно тоже почти никому не нужна.
EP>В сухом остатке — на данный момент в Nemerle нет ни то что библиотеки для гетерогенных последовательностей, а даже и готовых языковых фич для описания её интерфейса (можешь называть это хоть фрейворком — сути это не меняет).
Там просто есть несравнимо более мощная замещающая технология.
И именно из-за этого такой фигнёй в немерле никто не занимается.
О чём я тебе уже несколько сообщений твержу.
EP>Как минимум полного рабочего кода, а желательно online demo.
EP>Демагогия это вот это? "Но никто это делать не будет, ибо макросы всё равно мощнее."
Нет. Это объяснение, почему в немерле никто шаблоны не добавил. Хотя это и возможно.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
_>>Нуу на самом деле не помню каких-то особых претензий там к нему. Основное, что он реализовал отдельную функцию, а не функцию-член. Ну так это в C++ это как раз не проблема поправить, благодаря множественному наследованию. WH>И как ты множественным наследованием собрался реализовать абстрактный метод? WH>..
Эээм, какой ещё абстрактный метод? ) У нас была задача добавить в некий класс автоматический метод GetHash(). В варианте на Nemerle это реализовано через добавление атрибута класса. В варианте на D через добавление одной строки в сам класс (mixin), а в варианте на C++ можно реализовать через добавление дополнительного предка у класса. Никаких сомнительных интерфейсов и наследования от них не требуется.
_>>В общем моё мнение тут такое: как только в C++ появится нормальная интроспекция (естественно времени компиляции), то пример Евгения честно можно будет позиционировать как полноценное решение, причём оно возможно будет ещё и самым красивым. Ну а пока... WH>Нельзя. Плюс я могу придумать ещё миллион задач которые на шаблонах С++ не решить.
Я тоже могу) Но речь то шла про конкретное решение. И я не вижу у него каких-то недостатков, если не считать костыльной реализации интроспекции.
Здравствуйте, alex_public, Вы писали:
_>Эээм, какой ещё абстрактный метод? ) У нас была задача добавить в некий класс автоматический метод GetHash(). В варианте на Nemerle это реализовано через добавление атрибута класса. В варианте на D через добавление одной строки в сам класс (mixin), а в варианте на C++ можно реализовать через добавление дополнительного предка у класса. Никаких сомнительных интерфейсов и наследования от них не требуется.
Кстати, это я ещё не упомянул самого стандартного для C++ метода для решения подобных вещей — использования макроса. При использование такого способа добавление новой функций-члена будет выглядеть в стиле D: дополнительная строчка в классе (раскрываемая в метод).
В общем варианты на все вкусы, причём код получается покрасивее чем на конкурентах. Единственный минус, как я уже говорил, в реализации интроспекции.
Здравствуйте, PM, Вы писали:
PM>Гм, да, про wxWidgets забыл. И не только один я Сходил на сайт, судя по новостям, wxWidgets даже обновляются. Но вот растут они тоже из начала 90-х и архитектурно от MFC мало отличаются.
Да, растёт оттуда, но при этом вполне себе эволюционирует. К примеру обработчики сообщений давно задаются по современному (через функцию connect), а не через таблицу макросов (явное наследие идей MFC). Внутренние строки давно переделаны в std::string и т.д. и т.п. В общем вполне можно пользоваться. И такое развитие (синхронное, с развитием самого языка) является как раз следствием нормальной изначальной архитектуры, без коверканья языка, в отличие от Qt.
Здравствуйте, alex_public, Вы писали:
_>Эээм, какой ещё абстрактный метод? )
В .НЕТ GetHeshCode виртуальный метод.
_>Никаких сомнительных интерфейсов и наследования от них не требуется.
Это я тебе просто показал что как только задача чуть меняется так С++ окончательно ласты склеивает.
_>Я тоже могу) Но речь то шла про конкретное решение. И я не вижу у него каких-то недостатков, если не считать костыльной реализации интроспекции.
Конкретное решение не решает поставленную задачу.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, alex_public, Вы писали:
_>В общем варианты на все вкусы, причём код получается покрасивее чем на конкурентах. Единственный минус, как я уже говорил, в реализации интроспекции.
Ну покажи как ты будешь делать генерацию нескольких методов в зависимости от того что уже объявлено в классе.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, PM, Вы писали:
PM>>>Наверно иногда да. Но на мой взгляд, препроцессор, как он сейчас есть в С/С++ довольно опасная вещь. V>>Самая безобидная вещь в с++, можно легко получить результат препроцессинга и понять где ошибся. Очень мощный плюс, где вы ещё такой в с++ найдёте? PM>Угу, промотав пару мегабайт включенных заголовков. Вам когда-нибудь приходилось вызывать функции типа Sleep, GetMessage из каких-нибудь сторонних библиотек? При компиляции под Windows на ровном месте вываливается ошибка о несоответствии типов аргументов. И по неопытности можно долго ломать голову, глядя на абсолютно корректный вызов, имея #define GetMessage GetMessageW где-то в неявно включенном windows.h
А причём здесь препроцессор? Во-первых, это затея МС — с них и спрос. Во-вторых, делаешь препроцессинг и в месте ошибки смотришь результат — лучше чем ничего вообще. Просто вы не пользовались таким, вот и всего.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, WolfHound, Вы писали:
EP>>И сколько вообще шаблонных библиотек на Nemerle? WH>Нисколько. Ибо шаблоны в немерле не нужны.
"Гнилые блаб-отмазки и слив"
EP>>Со следующим тезисом согласен? EP>>По возможности следует обобщать регулярно дублирующийся код/макро-генерацию в отдельные именованные сущности (и группировать их в библиотеки). WH>Я тоже за всё хорошее и против всего плохого.
И с чем тогда спорил
EP>>"универсальную, конфигурируемую через кучу параметров мега-фень" — всего лишь означает что не найдена правильная абстракция, либо найдена, но реализация которой не оправданна.
WH>Ох... hi_octane по граблям уже попрыгал. Но его ты слушать не хочешь. Ну, продолжай есть кактус.
EP>>В сухом остатке — на данный момент в Nemerle нет ни то что библиотеки для гетерогенных последовательностей, а даже и готовых языковых фич для описания её интерфейса (можешь называть это хоть фрейворком — сути это не меняет). WH>Там просто есть несравнимо более мощная замещающая технология. WH>И именно из-за этого такой фигнёй в немерле никто не занимается. WH>О чём я тебе уже несколько сообщений твержу.
И чем это отличается от моего аргумента?
EP>В разных языках разные подходы. Non-member функция hash_value — это стандартный протокол в C++. И я не вижу никакого смысла использовать функцию член, когда допустим хэш-таблица ожидает non-member, только ради какой-то синтетической задачи.
Даже если бы была простая возможность добавить в класс метод hash — то всё равно на C++ идиомой бы осталась non-member функция hash_value. Точно также как и ты говоришь, что требование использовать шаблоны на Nemerle не соответствует его идиомам
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Даже если бы была простая возможность добавить в класс метод hash — то всё равно на C++ идиомой бы осталась non-member функция hash_value. Точно также как и ты говоришь, что требование использовать шаблоны на Nemerle не соответствует его идиомам
GetHeshCode виртуальный. Как ты его собрался делать внешней функцией?
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, 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-сервер
Здравствуйте, alex_public, Вы писали:
_>А какой в этом смысле? Для тривиальных ("record" в "record") конструкторов логичнее сделать плоскую реализацию (т.е. просто инициализацию всех подряд полей, и своих и предков) — будет и проще и быстрее. А для нетривиальных конструкторов вообще вся эта автогенерация не подходит.
Она не только подходит, но ещё и очень удобна.
На досуге попробуй реализовать наследника System.Exception. Ничего сложного, но на C# тебе придётся написать 4 конструктора. А на немерле их напишет макрос.
WH>>Да вот оказывается, не реализуются. _>Где оказывается то? )
Да вот прямо тут и оказывается.
_>Вот это уже другой разговор. Действительно серьёзные вещи, недоступные на C++.
Как мы выяснили С++у и менее серьёзные вещи недоступны.
_>Кстати, интересно как-нибудь сравнить плюсы и минусы вашей реализации, реализации D,
В D тупое склеивание строк. Никакой гигиены. Короче полный мрак.
_>ну может ещё Rust'a.
Выглядит намного лучше, чем D. Но нужно разбираться.
_>Хотя конечно последние два скорее из одного мира (нативного, позволяющего решать любые задачи), а ваше из другого (из ограниченного мира .net), но в смысле метапрограммирования это наверное не особо принципиально.
От слова совсем.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
K>Да, если юзать спирит, нужно вставить побольше RAM в compile-сервер
Нужно разбивать описание грамматик на части помельче. Что любопытно, MSVC давал в таких местах ворнинг а gcc сегфолт.
И у спирита есть ещё одна фича(?) — тот кто написал вещи типа:
Здравствуйте, alex_public, Вы писали:
_>А что не так со встроенными массивами? )
В том виде, в каком они пришли из C — это вредительство, ИМХО. Ну хотя бы убрать пресловутое "разложение до указателя" хотя бы в 2003 было можно. Например, в неявном виде передавать после указателя на первый элемент длину — примерно так же, как явно делают в C при передаче массива в функцию:
/* C */void foo(int* data, size_t size);
// C++void foo(int data[]) // а на самом деле в функцию передавалось бы то же, что и выше!
{
size_t n = std::array_length(data); // например
// ...
}
_>Насчёт optional... Ну всё же это некий контейнер, так что некие аналогии (скажем с xxx_ptr) имеются. )
Не аргумент. std::vector — тоже контейнер, но он не притворяется указателем ни в каком виде, и нужно слегка постараться, чтобы получить "указатель на элемент".
_>Кстати, например в D добавление в массив реализуется оператором "=+" — всё вполне удобно. )
operator+= или operator=+ ? Вот не нагуглил за 5 минут по теме D operator+= или D operator=+, "Александреску, друг, прости, свой D подальше запусти"(с) Если существует в D operator=+, и он именно используется именно для конкатенации — да на здоровье, вот в Haskell, ЕМНИП, есть оператор конкатенации ++, в Perl конкатенация строк идет через оператор . (точка)
Это я к тому, что оператор "увеличить на значение" и оператор "конкатенация" должны, ИМХО, различаться. "Разные вещи должны выглядеть по-разному, схожие — одинаково".
Кажется, Страуструп писал, что operator<< и operator>> были использованы для ввода/вывода из-за того, что в современной программе практически невозможно будет встретить применение встроенных операторов сдвига. Уже приходилось встречать коллег, которые на вопрос "что делает оператор >>?" бодро отвечали "ввод данных из потока"
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
K>Сейчас кто-нибудь придет и скажет, какой это красивый и выразительный код
Насчет красивого хз, но все понятно.
Непонятно только, зачем там кавычка, если терминатор — '0x1F').
Плюс, чтобы вычитать символы из множества, нет нужды каждый символ оборачивать в bs::ch_p. Так что весь крокодил bs::anychar_p — bs::ch_p( 0x1F ) — bs::ch_p( '"' ) превращается в коротенький ~bs::chset("\x1F\"").
Плюс для чтения строчки, ограниченной всякими '0x1F', есть специальный парсер confix_p.
Т.е. парсер для строчки, ограниченной '\x1F', вместо всего крокодила выше, будет записываться как:
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, kurchatov, Вы писали:
K>>jazzer, расскажите нам, как банки ценят разработчиков со знанием boost.
J>Очень ценят.
Здравствуйте, WolfHound, Вы писали:
WH>Она не только подходит, но ещё и очень удобна. WH>На досуге попробуй реализовать наследника System.Exception. Ничего сложного, но на C# тебе придётся написать 4 конструктора. А на немерле их напишет макрос.
Ну так то, что в C# всё плохо с МП ты можешь меня не убеждать... )))
WH>Да вот прямо тут и оказывается.
Пока по нашей дискуссии ничего не оказывается. Хота в реальности действительно всё весьма слабо.
_>>Кстати, интересно как-нибудь сравнить плюсы и минусы вашей реализации, реализации D, WH>В D тупое склеивание строк. Никакой гигиены. Короче полный мрак.
Не не не. То, что все вспоминают функцию mixin из D, совершенно не означает, что она является единственным инструментом МП там. Скорее наоборот, это инструмент для особых случаев, которые не решаются по нормальному. А обычно там применяются шаблоны, только доведённые до ума (полноценные вычисления во время компиляции, в том числе и со строками).
_>>ну может ещё Rust'a. WH>Выглядит намного лучше, чем D. Но нужно разбираться.
Я пока вообще не в курсе. Но мне показывали примеры с проверкой sql синтаксиса при компиляции (не в кривом варианте типа отображения на функции языка, как в linq или даже в C++ библиотеках, по нормальному) — это впечатляет.
Здравствуйте, slava_phirsov, Вы писали:
_>>А что не так со встроенными массивами? ) _>В том виде, в каком они пришли из C — это вредительство, ИМХО. Ну хотя бы убрать пресловутое "разложение до указателя" хотя бы в 2003 было можно. Например, в неявном виде передавать после указателя на первый элемент длину — примерно так же, как явно делают в C при передаче массива в функцию:
Это будет нарушение принципов C/C++ — лишние накладные расходы. К тому же зачем оно, если у нас имеется std::array? )
_>>Насчёт optional... Ну всё же это некий контейнер, так что некие аналогии (скажем с xxx_ptr) имеются. ) _>Не аргумент. std::vector — тоже контейнер, но он не притворяется указателем ни в каком виде, и нужно слегка постараться, чтобы получить "указатель на элемент".
Не, это другой контейнер, хранящий много экземпляров. А у optional аналогия как раз ближе к какому-нибудь unique_ptr или future. )
_>>Кстати, например в D добавление в массив реализуется оператором "=+" — всё вполне удобно. ) _>operator+= или operator=+ ? Вот не нагуглил за 5 минут по теме D operator+= или D operator=+, "Александреску, друг, прости, свой D подальше запусти"(с) Если существует в D operator=+, и он именно используется именно для конкатенации — да на здоровье, вот в Haskell, ЕМНИП, есть оператор конкатенации ++, в Perl конкатенация строк идет через оператор . (точка)
Ой, это я ерунду сказал. ))) На самом деле конечно же оператор "~=" добавляет что-то в новый. В то время как оператор "~" реализует именно создание нового массива состоящего из старого, плюс новый элемент.
Здравствуйте, TimurSPB, Вы писали:
EP>>Тут даже не нужно знать Boost.Spirit, чтобы понять что происходит TSP>А потом туда добавляются всякие правила для комментариев, потом ещё что то. И всё превращается в тяжело поддерживаемую простыню.
Зачем в простыню-то? Расстилать простыни можно на любом языке.
TSP>У меня доходило до того, что компилятор падал на этапе компиляции.
Выше была претензия про понятность такой грамматики — я показал конкретный пример, который на мой взгляд понятен даже человеку не знакомому с Boost.Spirit.
То что у него есть какие-то другие недостатки — я с этим не спорю. Время компиляции — один из них, хотя часто и не является show stopper'ом.
Кстати говоря, использование новых языковых фич позволит ему компилироваться быстрее, например: http://boost-spirit.com/home/2013/02/23/spirit-x3-on-github/
Здравствуйте, alex_public, Вы писали:
_>Это будет нарушение принципов C/C++ — лишние накладные расходы. К тому же зачем оно, если у нас имеется std::array? )
А неявная передача указателя this — не лишние накладные расходы? В ту пору std::array не было, а с std::vector была небольшая проблемка — списков инициализации еще не придумали, и заполнять содержимое контейнера приходилось руками:
string items[] = {"I'v", "been", "expecting", "you", ",", "mr", "Stroustrup"};
call(items); // Опасно, ведь call(), увы, не знает размер переданного массива
// А если бы знал - было бы безопасно!
_>Не, это другой контейнер, хранящий много экземпляров. А у optional аналогия как раз ближе к какому-нибудь unique_ptr или future. )
Не согласен, на том и остановимся
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Здравствуйте, alex_public, Вы писали:
WH>>Она не только подходит, но ещё и очень удобна. WH>>На досуге попробуй реализовать наследника System.Exception. Ничего сложного, но на C# тебе придётся написать 4 конструктора. А на немерле их напишет макрос. _>Ну так то, что в C# всё плохо с МП ты можешь меня не убеждать... )))
Ты уходишь от темы про нужность нетривиальных конструкторов.
WH>>Да вот прямо тут и оказывается. _>Пока по нашей дискуссии ничего не оказывается. Хота в реальности действительно всё весьма слабо.
Ну как же?
Дали вам две задачки. Обе не решены.
Мне про метапрограммирование на С++ рассказывать не нужно. Я про него всё знаю. По тому и могу легко задачки неберучки придумывать.
_>Не не не. То, что все вспоминают функцию mixin из D, совершенно не означает, что она является единственным инструментом МП там. Скорее наоборот, это инструмент для особых случаев, которые не решаются по нормальному. А обычно там применяются шаблоны, только доведённые до ума (полноценные вычисления во время компиляции, в том числе и со строками).
Ну, ты дай ссылку на "то". Чтобы я опять что-то "не то" не подумал.
_>Я пока вообще не в курсе. Но мне показывали примеры с проверкой sql синтаксиса при компиляции (не в кривом варианте типа отображения на функции языка, как в linq или даже в C++ библиотеках, по нормальному) — это впечатляет.
Ссылку?
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, slava_phirsov, Вы писали:
_>>Это будет нарушение принципов C/C++ — лишние накладные расходы. К тому же зачем оно, если у нас имеется std::array? ) _>А неявная передача указателя this — не лишние накладные расходы?
Так оно же не в дополнение, а вместо. )
_>В ту пору std::array не было, а с std::vector была небольшая проблемка — списков инициализации еще не придумали, и заполнять содержимое контейнера приходилось руками: _>... _>Сравни с: _>...
Нуу, если очень нужна безопасность и это у нас C++, то можно было сделать банально call<N>(items);
Но в любом случае в современном C++ это уже всё давно не актуально. )
Здравствуйте, WolfHound, Вы писали:
WH>Ты уходишь от темы про нужность нетривиальных конструкторов.
Естественно они нужны. Но как это пересекается с темой автоматической генерации тривиальных конструкторов...
WH>Ну как же? WH>Дали вам две задачки. Обе не решены.
Я вижу в основном мелкие придирки)
WH>Мне про метапрограммирование на С++ рассказывать не нужно. Я про него всё знаю. По тому и могу легко задачки неберучки придумывать.
Вообще то судя по сегодняшнему обсуждению, про C++ ты на самом деле не совсем в курсе. Во всяком случае про современный. Но при этом тезис о слабости метапрограммирования в C++ (естественно в сравнение с D/Rust/Nemerle, а не каким-нибудь C#, где вообще ничего нет) я оспаривать не собираюсь. Причём я об этом писал тут уже не раз.
WH>Ну, ты дай ссылку на "то". Чтобы я опять что-то "не то" не подумал.
А функция mixin (http://dlang.org/mixin.html) живёт по сути отдельно от всего этого и типа реализует всё что угодно, что не укладывается в варианты выше.
_>>Я пока вообще не в курсе. Но мне показывали примеры с проверкой sql синтаксиса при компиляции (не в кривом варианте типа отображения на функции языка, как в linq или даже в C++ библиотеках, по нормальному) — это впечатляет. WH>Ссылку?
(вообще, для такого простого парсера достаточно коротенького регэкспа ([^\x1F"]*)\x1F?, так что я предполагаю, что это часть какого-то большого парсера)
CC>На деле оказывается проще сразу расстрелять агитирующих за спирит и изначально писать на чёи либо другом.
TSP>>тот становится незаменим при поддержки кода. Если такой бусто-спиритист уходит из команды, то проще переписать.
CC>На деле оказывается проще сразу расстрелять агитирующих за спирит и изначально писать на чёи либо другом.
Так ты предложи внятную замену спириту. А то много кому не нравится буст и спирит в частности, но ничего внятного на замену предложить не могут.
И вот здесь, внезапно, оказывается так, что любой человек, который способен написать внятный парсер, становится незаменимым при поддержке кода. А переписывать — так принято у программитов. Заодно это еще и хороший способ разобраться с теми же парсерами.
Здравствуйте, Ikemefula, Вы писали:
CC>>На деле оказывается проще сразу расстрелять агитирующих за спирит и изначально писать на чёи либо другом.
I>Так ты предложи внятную замену спириту. А то много кому не нравится буст и спирит в частности, но ничего внятного на замену предложить не могут.
<раз уж мы все равно в СВ />
Ну как не могут? Точнее, так — думают что могут — героически переписывают это на scanf (заодно и "перфоманс поднимут" (с), ага =)
А потом любой случайно залетевший дятелпробел в данных ломает их "быстренько написанный" код на тысчонку другую строк — к такой-то матери. Потом, поскольку эти тонны кило легко усвояемой лапши на самом деле никак не перевариваются — рядом пишется еше сотни такой же. В общем нет предела совершенству. Наступает этакое экологическое равновесие — круговорот говна в природе.
[]
K>Ну, это очередной контейнер данных. K>Конечно, это помогает. Но вряд ли это составляет хотя бы 20% работы программиста.
У не любителей буста, и по совместительству любителей, велосипедов — наверное все 80%
А если учесть, что они эти лисапеды нифига не тестят, а потом тратят кучу времени на поиск и фикс в них багов — то собственно этим в основном они и занимаются. Я лично насмотрелся на все эти самописные стороки\списки\мютексы ...
Не, есть конечно команды, которые осознано отказываются от буста\стл и т. д. и у которых есть свои вменяемые аналоги нужных им кирпичиков.
Правда я таких в живую не встречал, только и инторнетах, по типу — "и вы говорите" (с).
ЗЫ Вместо "буста" здесь можно подставить тот же qt. Да даже и std, т. к. пересечение множества не любителей буста и не любителей STL нифига не пусто.
Здравствуйте, Ikemefula, Вы писали:
I>Так ты предложи внятную замену спириту. А то много кому не нравится буст и спирит в частности, но ничего внятного на замену предложить не могут.
Генераторов парсеров нафигачено более чем достаточно.
Проблема в метапрограммировании на шаблонах — стремительно растущее время компиляции при росте сложности парсера + отладка всей этой херни уж очень на любителя.
Чисто с менеджерской точки зрения — код на спирите банально высокорисковый и слишком завязан на автора.
I>И вот здесь, внезапно, оказывается так, что любой человек, который способен написать внятный парсер, становится незаменимым при поддержке кода.
Внятно написанный парсер проще поддерживать и развивать.
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, CreatorCray, Вы писали:
CC>Здравствуйте, Ikemefula, Вы писали:
I>>Так ты предложи внятную замену спириту. А то много кому не нравится буст и спирит в частности, но ничего внятного на замену предложить не могут. CC>Генераторов парсеров нафигачено более чем достаточно.
И? Покажи класс, чтоб мы все увидели, что решения не на спирите низкорисковые, их отладка не на любителя, ничего не завязано на автора, код понятный и легко поддерживаемый?
CC>Проблема в метапрограммировании на шаблонах — стремительно растущее время компиляции при росте сложности парсера + отладка всей этой херни уж очень на любителя.
Компиляция — да (но это улучшается с приходом С++11), а вот с отладкой вообще никогда проблем не было.
CC>Чисто с менеджерской точки зрения — код на спирите банально высокорисковый и слишком завязан на автора.
Мой опыт противоречит этим утверждениям.
CC>Внятно написанный парсер проще поддерживать и развивать.
Здравствуйте, CreatorCray, Вы писали:
I>>Так ты предложи внятную замену спириту. А то много кому не нравится буст и спирит в частности, но ничего внятного на замену предложить не могут. CC>Генераторов парсеров нафигачено более чем достаточно.
Нет в мире простых генераторов парсеров. Для просто грамматики все просто, но, что характерно, не проще чем парсер комбинаторы (спирит). Для сложной — надо приседать и приседать.
CC>Проблема в метапрограммировании на шаблонах — стремительно растущее время компиляции при росте сложности парсера + отладка всей этой херни уж очень на любителя. CC>Чисто с менеджерской точки зрения — код на спирите банально высокорисковый и слишком завязан на автора.
Отладкой спирита не надо заниматься, нужно думать над внятной грамматикой. А вот когда на выходе AST, там надо и повозиться с отладкой. Что характерно, работу с АСТ тебе ни один генератор парсеров не заменит.
I>>И вот здесь, внезапно, оказывается так, что любой человек, который способен написать внятный парсер, становится незаменимым при поддержке кода. CC>Внятно написанный парсер проще поддерживать и развивать.
Спирит это, считай, в чистом виде БНФ. Идея простая до безобразия — комбинаторы парсеров.
J>(вообще, для такого простого парсера достаточно коротенького регэкспа ([^\x1F"]*)\x1F?, так что я предполагаю, что это часть какого-то большого парсера)
CC>>На деле оказывается проще сразу расстрелять агитирующих за спирит и изначально писать на чёи либо другом.
J>Критикуя — предлагай! (с)
J>yacc? bison? scanf? istream?
Чисто врукопашную получается не сильно длиннее
template <class It, class Str> void foo(It& start, It e, Str& attr)
{
It s = start;
for (; s != e; ++s)
if (*s == '0x1F' | *s == '\"')
break;
// можно добавить здесь условие if (s != start) чтобы было как со спиритом
attr = Str(start, s);
if (*s == '0x1F')
++s;
start = s;
}
О том, какой вариант понятнее, можно спорить. Зато компилируется влет и когда вложишь штук 30 парсеров друг в друга — не придется по исходникам вылавливать наличие всяких там FUSION_MAX_VECTOR_SIZE. Я уж не говорю про BOOST_SPIRIT_THREADSAFE и прочие грабли, которых в либе такого размера наверняка пара штук припрятана.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, alex_public, Вы писали:
_>Но в любом случае в современном C++ это уже всё давно не актуально. )
После std::initializer_list (2011г) — да. Вопрос, нужен ли бы был std::initializer_list, если бы в C++ были нормальные встроенные массивы —
Любители оптимизации, считающие, что неявная передача размера губит им производительность, могли бы использовать передачу указателя на первый элемент в явном виде (откуда бы вызываемая функция узнала размер массива, это уже другой вопрос, но, наверное, откуда-нибудь бы узнала, ну там ограничивающий элемент в конце, например).
Для совместимости с C можно было бы оставить "разложение" массива до указателя для случая функций со спецификатором extern "C".
И уж ни в C, ни в C++ нет оправдания вот такому:
void foo(int x[4]);
...
int z[3] = {};
foo(z); // ну вот тут-то компилятор мог бы возмутиться!!! Ну я так думаю...
Эээх, но это же было все не прикольно, WG21 прикольно было играться с шаблонами, исключениями, множественным наследованием, виртуальными базовыми классами, а вот довести до ума массивы — скучно.
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
J>>(вообще, для такого простого парсера достаточно коротенького регэкспа ([^\x1F"]*)\x1F?, так что я предполагаю, что это часть какого-то большого парсера)
ХГД>Чисто врукопашную получается не сильно длиннее
ХГД>template <class It, class Str> void foo(It& start, It e, Str& attr)
ХГД>{
ХГД> It s = start;
ХГД> for (; s != e; ++s)
ХГД> if (*s == '0x1F' | *s == '\"')
ХГД> break;
ХГД> // можно добавить здесь условие if (s != start) чтобы было как со спиритом
ХГД> attr = Str(start, s);
ХГД> if (*s == '0x1F') // вот здесь ты разыменовываешь е (если в строке не было 1F и кавычки)
ХГД> ++s; // а здесь ты вылетаешь за е
ХГД> start = s; // и возвращаешь этот веселый итератор обратно через start
ХГД>}
ХГД>О том, какой вариант понятнее, можно спорить. Зато компилируется влет и когда вложишь штук 30 парсеров друг в друга — не придется по исходникам вылавливать наличие всяких там FUSION_MAX_VECTOR_SIZE. Я уж не говорю про BOOST_SPIRIT_THREADSAFE и прочие грабли, которых в либе такого размера наверняка пара штук припрятана.
Да не о чем спорить, все в комментах к коду выше
Спасибо за иллюстрацию
ХГД>>template <class It, class Str> void foo(It& start, It e, Str& attr)
ХГД>>{
ХГД>> It s = start;
ХГД>> for (; s != e; ++s)
ХГД>> if (*s == '0x1F' | *s == '\"')
ХГД>> break;
ХГД>> // можно добавить здесь условие if (s != start) чтобы было как со спиритом
ХГД>> attr = Str(start, s);
J>ХГД> if (*s == '0x1F') // вот здесь ты разыменовываешь е (если в строке не было 1F и кавычки)
ХГД>> ++s; // а здесь ты вылетаешь за е
ХГД>> start = s; // и возвращаешь этот веселый итератор обратно через start
ХГД>>}
J>
ХГД>>О том, какой вариант понятнее, можно спорить. Зато компилируется влет и когда вложишь штук 30 парсеров друг в друга — не придется по исходникам вылавливать наличие всяких там FUSION_MAX_VECTOR_SIZE. Я уж не говорю про BOOST_SPIRIT_THREADSAFE и прочие грабли, которых в либе такого размера наверняка пара штук припрятана.
J>Да не о чем спорить, все в комментах к коду выше J>Спасибо за иллюстрацию
Ну да, косякнул, в низкоуровневом коде это бывает чаще. Зато найти это на порядок проще, чем последствия неприменения BOOST_SPIRIT_THREADSAFE, коих на прошлой неделе в коде коллег пришлось воткнуть три штуки.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Хон Гиль Дон, Вы писали:
ХГД>Ну да, косякнул, в низкоуровневом коде это бывает чаще. Зато найти это на порядок проще, чем последствия неприменения BOOST_SPIRIT_THREADSAFE, коих на прошлой неделе в коде коллег пришлось воткнуть три штуки.
так забавно видеть оправдания последствий нечтения доки =)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
ХГД>>Ну да, косякнул, в низкоуровневом коде это бывает чаще. Зато найти это на порядок проще, чем последствия неприменения BOOST_SPIRIT_THREADSAFE, коих на прошлой неделе в коде коллег пришлось воткнуть три штуки. X>так забавно видеть оправдания последствий нечтения доки =)
Я вообще не видел пользователей spirit, которые бы про этот дефайн из доки узнали. Я про него, например, узнал, когда разбирался чего у меня boost::serialization при работе с xml архивами падает. И если не ошибаюсь, то оно до сих пор в бусте по умолчанию так небезопасно и собирается.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Хон Гиль Дон, Вы писали:
ХГД>Здравствуйте, jazzer, Вы писали:
ХГД>>> if (*s == '0x1F') // вот здесь ты разыменовываешь е (если в строке не было 1F и кавычки)
ХГД>>> ++s; // а здесь ты вылетаешь за е
ХГД>>> start = s; // и возвращаешь этот веселый итератор обратно через start
ХГД>>>}
ХГД>>>О том, какой вариант понятнее, можно спорить. J>>Да не о чем спорить, все в комментах к коду выше J>>Спасибо за иллюстрацию
ХГД>Ну да, косякнул, в низкоуровневом коде это бывает чаще.
О чем и речь. Вместо простецкого полуоднострочного спирит-парсера (который еще короче записывается вообще регэкспом), есть полотенце низкоуровневого кода, в котором мало что понятно, зато легко напортачить и потом разгребать коредампы.
ХГД>Зато найти это на порядок проще, чем последствия неприменения BOOST_SPIRIT_THREADSAFE, коих на прошлой неделе в коде коллег пришлось воткнуть три штуки.
Ну это разве что если сравнивать с поиском многопоточных ошибок.
Потому что ошибки парсинга и обработки краевых случаев искать замучаешься.
А ведь ты там еще что-то про 30 вложенных парсеров писал...
Ну недаром же генераторы парсеров придумали, ой, недаром
А насчет многопоточности — не проще компилятору -DBOOST_SPIRIT_THREADSAFE скормить, раз уж у вас многопоточный парсинг, и забыть о проблеме раз и навсегда?
J>(вообще, для такого простого парсера достаточно коротенького регэкспа ([^\x1F"]*)\x1F?, так что я предполагаю, что это часть какого-то большого парсера)
Да именно так — часть большого парсера. Сам написал четыре года назад, впервые решив использовать спирит.
Недавно возник вопрос по коду. SVN показывает, что это писал я. В комите ссылка на баг в трекере, в котором написанно про проблемы со старыми файлами. "Падает на символе 0x1F"
Здравствуйте, Хон Гиль Дон, Вы писали:
ХГД>Я вообще не видел пользователей spirit, которые бы про этот дефайн из доки узнали. Я про него, например, узнал, когда разбирался чего у меня boost::serialization при работе с xml архивами падает. И если не ошибаюсь, то оно до сих пор в бусте по умолчанию так небезопасно и собирается.
ну я про этот макрос узнал из тестов спирита, он там используется.
в доке не искал, да. но я хз, неужели этот макрос не упоминается в доке?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, TimurSPB, Вы писали:
TSP>Да именно так — часть большого парсера. Сам написал четыре года назад, впервые решив использовать спирит.
То есть ты здесь дал пример кода, написанного человеком, который "впервые решил использовать спирит", и предлагаешь нам сделать на его основе далеко идущие выводы о самом спирите?
TSP>>Да именно так — часть большого парсера. Сам написал четыре года назад, впервые решив использовать спирит. J>То есть ты здесь дал пример кода, написанного человеком, который "впервые решил использовать спирит", и предлагаешь нам сделать на его основе далеко идущие выводы о самом спирите?
Выводы каждый сам сделает. Но если мне понадобится сделать парсер, то я всё таки буду использовать спирит. Но делать это надо осознанно.
Здравствуйте, jazzer, Вы писали:
ХГД>>Ну да, косякнул, в низкоуровневом коде это бывает чаще. J>О чем и речь. Вместо простецкого полуоднострочного спирит-парсера (который еще короче записывается вообще регэкспом), есть полотенце низкоуровневого кода, в котором мало что понятно, зато легко напортачить и потом разгребать коредампы.
Когда там спирита набегает не одна строка, а хотя бы десять, 200 строк низкоуровнего кода уже не выглядят столь ужасными. Лично для меня, естественно.
ХГД>>Зато найти это на порядок проще, чем последствия неприменения BOOST_SPIRIT_THREADSAFE, коих на прошлой неделе в коде коллег пришлось воткнуть три штуки. J>Ну это разве что если сравнивать с поиском многопоточных ошибок. J>Потому что ошибки парсинга и обработки краевых случаев искать замучаешься.
Это при применении спирита их искать замучаешься А уж если надо вычислять позицию, на которой случился синтакс еррор — вообще вешайся. А с низкоуровневым кодом пофиг, все прекрасно отлаживается, если чего-то не хватает — дописать можно без многочасовых копаний в доках или чужих исходниках.
J>А ведь ты там еще что-то про 30 вложенных парсеров писал...
Дебаг итераторам это без разницы
J>Ну недаром же генераторы парсеров придумали, ой, недаром
J>А насчет многопоточности — не проще компилятору -DBOOST_SPIRIT_THREADSAFE скормить, раз уж у вас многопоточный парсинг, и забыть о проблеме раз и навсегда?
Ну так зачем было примеры на классике постить Ки, конечно, значительно лучше, но и там привязка семантических действий вся такая же неудобная и по-прежнему чертова уйма уровней вложенности.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, niXman, Вы писали:
ХГД>>Я вообще не видел пользователей spirit, которые бы про этот дефайн из доки узнали. Я про него, например, узнал, когда разбирался чего у меня boost::serialization при работе с xml архивами падает. И если не ошибаюсь, то оно до сих пор в бусте по умолчанию так небезопасно и собирается.
X>ну я про этот макрос узнал из тестов спирита, он там используется.
Ну сам же видишь — дока в этом плане бесполезна
X>в доке не искал, да. но я хз, неужели этот макрос не упоминается в доке?
В доке к спириту упоминается. Но, например, в доке к serialization при него вроде бы ничего нет и автор сериализации, похоже, вообще про него не знал. Я его спрашивал когда-то, а как типа твою либу с таким дефайном собирать, а то не линкуется, thread требует — внятного ответа не получил.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, NeoCode, Вы писали:
NC>Но считаю что врага надо знать в лицо У меня тоже есть хобби — разработка своего языка программирования, не менее (и даже гораздо более) мощного чем С++, но без всей этой головной боли.
Может стоит посмотреть на Ada?
Здравствуйте, alex_public, Вы писали:
_>Т.е. вот допустим есть тривиальная задачка: прочитать большой текстовый файл в специфическом формате (например какая-нибудь вариация на тему csv). Какое вы предложите решение, чтобы оно было быстродействующим и при этом занимало пару строчек кода? )
Вариант ничего не использовать, взять да и написать ручками не рассматривается?
Здравствуйте, alex_public, Вы писали:
WH>>Ты уходишь от темы про нужность нетривиальных конструкторов. _>Естественно они нужны. Но как это пересекается с темой автоматической генерации тривиальных конструкторов...
Вот так:
[Record]
public class ParsingFailureException : Exception
{
public ParseResult : ParseResult { get }
}
_>Я вижу в основном мелкие придирки) У вас там основной функциональности нет.
WH>>Мне про метапрограммирование на С++ рассказывать не нужно. Я про него всё знаю. По тому и могу легко задачки неберучки придумывать. _>Вообще то судя по сегодняшнему обсуждению, про C++ ты на самом деле не совсем в курсе.
Или ты?
WH>>Ну, ты дай ссылку на "то". Чтобы я опять что-то "не то" не подумал. _>Нуу даже не знаю на что кинуть тут ссылку.
Много букв. Потом посмотрю.
_>>>Я пока вообще не в курсе. Но мне показывали примеры с проверкой sql синтаксиса при компиляции (не в кривом варианте типа отображения на функции языка, как в linq или даже в C++ библиотеках, по нормальному) — это впечатляет. WH>>Ссылку? _>https://github.com/sfackler/rust-postgres-macros
Это как я понял плагин к компилятору.
Скорей всего клон вот этого: https://github.com/rsdn/nemerle/wiki/SQL-macros https://github.com/rsdn/nemerle/blob/master/macros/Data.n
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Mystic, Вы писали:
_>>Т.е. вот допустим есть тривиальная задачка: прочитать большой текстовый файл в специфическом формате (например какая-нибудь вариация на тему csv). Какое вы предложите решение, чтобы оно было быстродействующим и при этом занимало пару строчек кода? )
M>Вариант ничего не использовать, взять да и написать ручками не рассматривается?
Нуу вообще говоря если надо искать нужную библиотеку, скачивать её, компилировать, подключать, смотреть документацию и т.п., то действительно иногда проще написать велосипед. Но Boost то чаще всего уже подключён к проекту, так что...
Здравствуйте, alex_public, Вы писали:
_>Но Boost то чаще всего уже подключён к проекту, так что...
Я бьі не бьі так категоричен насчет "чаще всего". Кроме того, документацию по spirit тоже читать надо, покурить примерьі. Т. е. уже день потратить. Потом человек, которьій будет смотреть/поддерживать код, далеко не факт, что знаком со spirit. Плюс опять же, можно наткнуться на что-нить, типа ошибки компиляции на несколько страничек. И не разобраться сразу, в чем подвох.
Здравствуйте, WolfHound, Вы писали:
WH>Вот так: WH>...
Аааа, т.е. подразумевается создание у наследника всех вариантов конструктора предка? Так это совсем другая задачка. И она действительно можно быть удобна в специфических случаях.
_>>Я вижу в основном мелкие придирки) WH> У вас там основной функциональности нет.
Вариант Евгения я уже указал как подправить в точности под ваши требования, хотя на мой взгляд это всего лишь придирка (вообще не принципиально функция-член или отдельная шаблонная функция). Про вариант с record тоже всё работает в соответствие с примерами из описания. То, что при этом внутри реализуется чуть другая логика — это опять же придирка. )
_>>Вообще то судя по сегодняшнему обсуждению, про C++ ты на самом деле не совсем в курсе. WH>Или ты?
Здравствуйте, alex_public, Вы писали:
_>Аааа, т.е. подразумевается создание у наследника всех вариантов конструктора предка? Так это совсем другая задачка. И она действительно можно быть удобна в специфических случаях.
Так я тебе именно это и говорил.
_>Вариант Евгения я уже указал как подправить в точности под ваши требования, хотя на мой взгляд это всего лишь придирка (вообще не принципиально функция-член или отдельная шаблонная функция). Про вариант с record тоже всё работает в соответствие с примерами из описания. То, что при этом внутри реализуется чуть другая логика — это опять же придирка. )
Конструкторы предка не создаёт.
С приватными членами класса не работает.
Фильтрации нет.
...
_>Про std::atomic и move semantic ты похоже явно не в курсе.
В курсе.
_>А хоть variadic template и полиморфные лямбды видел на практике? )
Я столько всего видел
_>Ну так реализуется то через макросы, а не пересборкой компилятора. )
В случае немерле это одно и то же. А в случае rust существенно разные механизмы.
Кстати я тут ещё раз на него глянул. До немерлового варианта ему как до пешком луны.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Cyberax, Вы писали:
S>>В Lisp красиво, без того уродства, коим являются шаблоны C++, любая, и самая сложная, грамматика, парсится в несколько десятков строк. C>Ну так в LISP уродливо всё остальное.
Здравствуйте, Mna, Вы писали:
C>>Ну так в LISP уродливо всё остальное. Mna>Есть претензии к Common Lisp кроме скобок?
Отсутствие типов, отсутствие нормального синтаксиса и т.п.
Здравствуйте, Хон Гиль Дон, Вы писали:
ХГД>Здравствуйте, jazzer, Вы писали:
ХГД>>>Ну да, косякнул, в низкоуровневом коде это бывает чаще. J>>О чем и речь. Вместо простецкого полуоднострочного спирит-парсера (который еще короче записывается вообще регэкспом), есть полотенце низкоуровневого кода, в котором мало что понятно, зато легко напортачить и потом разгребать коредампы.
ХГД>Когда там спирита набегает не одна строка, а хотя бы десять, 200 строк низкоуровнего кода уже не выглядят столь ужасными. Лично для меня, естественно.
Вот честно, никогда не имел проблем со спиритом, хотя он у нас используется для парсинга разнообразнейших конфигов только в путь.
парсеры бывают и поболе, чем 10 строк.
Я вот, честно, не вижу ни единого аргумента за то, чтоб писать низкоуровневый код.
ХГД>>>Зато найти это на порядок проще, чем последствия неприменения BOOST_SPIRIT_THREADSAFE, коих на прошлой неделе в коде коллег пришлось воткнуть три штуки. J>>Ну это разве что если сравнивать с поиском многопоточных ошибок. J>>Потому что ошибки парсинга и обработки краевых случаев искать замучаешься.
ХГД>Это при применении спирита их искать замучаешься А уж если надо вычислять позицию, на которой случился синтакс еррор — вообще вешайся. А с низкоуровневым кодом пофиг, все прекрасно отлаживается, если чего-то не хватает — дописать можно без многочасовых копаний в доках или чужих исходниках.
На этот счет у меня есть специальный одноклеточный "парсер" throw_p, который прекращает парсинг и бросает исключение со всем необходимым (строка, колонка, объяснение).
Типа:
И синтаксические ошибки сразу перестают быть проблемой.
Ну и про насчет дописывания — ничего удобнее спирита я пока не видел. Ну разве что perl
J>>А ведь ты там еще что-то про 30 вложенных парсеров писал...
ХГД>Дебаг итераторам это без разницы
в смысле, что они позволят отследить вылет за границы? Но и только ведь...
Ну недаром же генераторы парсеров придумали, ой, недаром
J>>А насчет многопоточности — не проще компилятору -DBOOST_SPIRIT_THREADSAFE скормить, раз уж у вас многопоточный парсинг, и забыть о проблеме раз и навсегда?
ХГД>Можно, конечно. Но кто вообще знал, что spirit через property_tree затянуло
Ну, батенька, это тогда уже не проблемы спирита, а проблемы property_tree. Это в их обязанности входит уведомить пользователя о подводных граблях в многопоточном окружении. И, по-хорошему, им бы надо иметь свой собственный дефайн на этот счет, раз есть зависимость от многопоточности.
J>>Не говоря уж о том, что это болезнь древнего спирита 1.х, в спирите-2 ее нет уже лет пять как: J>>http://boost-spirit.com/home/2010/11/07/multi-threaded-qi-6-hours-37-seconds/
ХГД>Ну так зачем было примеры на классике постить
Это не ко мне вопрос
Я отвечал на то, что запостили.
ХГД>Ки, конечно, значительно лучше, но и там привязка семантических действий вся такая же неудобная и по-прежнему чертова уйма уровней вложенности.
Ци же? Или ты на японский манер этот иероглиф читаешь?
семантические действия в том виде, в каком они былы в первом спирите, во втором не нужны — там парсеры атрибутированы и все можно достать из атрибутов (или дать контейнер/структуру, в который она сама сложит результаты парсинга). Смотри здесь — как раз про то, как внезапно исчезают семантические действия, если заюзать атрибуты.
Вот тут мы парсим список чисел через запятую, и наполняем вектор v через семантическое действие с push_back, в стиле 1-го спирита:
phrase_parse( first, last
, double_[push_back(phoenix::ref(v), _1)] % ','
, space);
А вот как надо парсить во втором спирите:
phrase_parse( first, last
, double_ % ','
, space, v); // v здесь, в парсере о нем ни слова
Здравствуйте, jazzer, Вы писали:
ХГД>>Когда там спирита набегает не одна строка, а хотя бы десять, 200 строк низкоуровнего кода уже не выглядят столь ужасными. Лично для меня, естественно. J>Вот честно, никогда не имел проблем со спиритом, хотя он у нас используется для парсинга разнообразнейших конфигов только в путь. J>парсеры бывают и поболе, чем 10 строк. J>Я вот, честно, не вижу ни единого аргумента за то, чтоб писать низкоуровневый код.
Очевидно же — высокий порог вхождения. Мне вот парсеры писать нужно бывает редко, грубо говоря раз в год. Поэтому детали я где-то не знаю, где-то не помню. И в целом сложилось впечатление, что я код без спирита быстрее бы писал. Благо и так, и так пробовал.
ХГД>>Это при применении спирита их искать замучаешься А уж если надо вычислять позицию, на которой случился синтакс еррор — вообще вешайся. А с низкоуровневым кодом пофиг, все прекрасно отлаживается, если чего-то не хватает — дописать можно без многочасовых копаний в доках или чужих исходниках.
J>На этот счет у меня есть специальный одноклеточный "парсер" throw_p, который прекращает парсинг и бросает исключение со всем необходимым (строка, колонка, объяснение). J>Типа:
J>И синтаксические ошибки сразу перестают быть проблемой.
А позицию откуда брать?
J>Ну, батенька, это тогда уже не проблемы спирита, а проблемы property_tree. Это в их обязанности входит уведомить пользователя о подводных граблях в многопоточном окружении. И, по-хорошему, им бы надо иметь свой собственный дефайн на этот счет, раз есть зависимость от многопоточности.
Ну вот так странно получается, что 2 библиотеки из состава буста, использующие спирит, предоставляют отличную возможность поиметь проблемы от многопоточности. Т.е. довольно неглупые и квалифицированные люди с задачей прочтения документации и безопасного использования старого спирита не справились. У нас в конторе уровень разработчиков явно ниже. Выводы отсюда, по-моему, вполне очевидные наклевываются.
J>семантические действия в том виде, в каком они былы в первом спирите, во втором не нужны — там парсеры атрибутированы и все можно достать из атрибутов (или дать контейнер/структуру, в который она сама сложит результаты парсинга). Смотри здесь — как раз про то, как внезапно исчезают семантические действия, если заюзать атрибуты. J>А вот как надо парсить во втором спирите: J>
J>phrase_parse( first, last
J> , double_ % ','
J> , space, v); // v здесь, в парсере о нем ни слова
J>
Доку я читал. Это все, конечно, супер, но, например, в строке эскейпы убрать — задача что со старым спиритом, что с новым не особо очевидная. И если б добры люди не выложили готовое решение на стековерфлоу, я б точно времени на простенький парсер на базе спирита потратил больше, чем на рукопашный.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Хон Гиль Дон, Вы писали:
ХГД>Здравствуйте, jazzer, Вы писали:
ХГД>>>Когда там спирита набегает не одна строка, а хотя бы десять, 200 строк низкоуровнего кода уже не выглядят столь ужасными. Лично для меня, естественно. J>>Вот честно, никогда не имел проблем со спиритом, хотя он у нас используется для парсинга разнообразнейших конфигов только в путь. J>>парсеры бывают и поболе, чем 10 строк. J>>Я вот, честно, не вижу ни единого аргумента за то, чтоб писать низкоуровневый код.
ХГД>Очевидно же — высокий порог вхождения. Мне вот парсеры писать нужно бывает редко, грубо говоря раз в год. Поэтому детали я где-то не знаю, где-то не помню. И в целом сложилось впечатление, что я код без спирита быстрее бы писал. Благо и так, и так пробовал.
Да нет там никакого порога, если человек знает EBNF (а это из раздела базовых вещей, имхо).
Все очень естественно и по докам моментально делается, особенно во втором спирите.
J>>На этот счет у меня есть специальный одноклеточный "парсер" throw_p, который прекращает парсинг и бросает исключение со всем необходимым (строка, колонка, объяснение). J>>Типа:
J>>И синтаксические ошибки сразу перестают быть проблемой.
ХГД>А позицию откуда брать?
так throw_p ее получит от сканера, когда до него дойдет очередь, как и любой другой парсер (иначе как парсер будет сканить строку дальше?).
Код такой:
scan.first — это оно. spirit_error::format — это моя внутренняя функция, перегруженная для разных типов итераторов (и итератор spirit::classic::position_iterator2 как раз отслеживает строку и колонку).
J>>Ну, батенька, это тогда уже не проблемы спирита, а проблемы property_tree. Это в их обязанности входит уведомить пользователя о подводных граблях в многопоточном окружении. И, по-хорошему, им бы надо иметь свой собственный дефайн на этот счет, раз есть зависимость от многопоточности.
ХГД>Ну вот так странно получается, что 2 библиотеки из состава буста, использующие спирит, предоставляют отличную возможность поиметь проблемы от многопоточности. Т.е. довольно неглупые и квалифицированные люди с задачей прочтения документации и безопасного использования старого спирита не справились. У нас в конторе уровень разработчиков явно ниже. Выводы отсюда, по-моему, вполне очевидные наклевываются.
Никаких тут выводов не наклевывается, кроме выводов о головотяпстве автора property_tree. Такие проблемы могут возникнуть с абсолютно любой библиотекой А, юзающей какую-то другую библиотеку Б, если у Б есть какие-то дополнительные требования, а автор А не потрудился их выяснить и транслировать своим пользователям. Библиотека Б тут ни в чем не виновата — это может быть какая-нть сишная библиотека вообще, пользующая, скажем, какой-нть не thread-safe posix API (tzset, скажем) — автор А обязан своим пользователям об этих ограничениях сказать, даже если собственный код самой А никаких многопоточностей не содержит.
J>>семантические действия в том виде, в каком они былы в первом спирите, во втором не нужны — там парсеры атрибутированы и все можно достать из атрибутов (или дать контейнер/структуру, в который она сама сложит результаты парсинга). Смотри здесь — как раз про то, как внезапно исчезают семантические действия, если заюзать атрибуты. J>>А вот как надо парсить во втором спирите: J>>
J>>phrase_parse( first, last
J>> , double_ % ','
J>> , space, v); // v здесь, в парсере о нем ни слова
J>>
ХГД>Доку я читал. Это все, конечно, супер, но, например, в строке эскейпы убрать — задача что со старым спиритом, что с новым не особо очевидная. И если б добры люди не выложили готовое решение на стековерфлоу, я б точно времени на простенький парсер на базе спирита потратил больше, чем на рукопашный.
Здравствуйте, smeeld, Вы писали:
S>Это засилье в отрасли понтарезов и олимпиадников, которые не осилили разработку на функциональных ЯП, S>но которым выпендренуться, по разным причинам, требуется. Они и уцепились за сущности aka "Метапрограммирование, S>Boost.Fusion, Boost.Mpl...". Но выглянуть из песочницы у них кругозора не хватает. S>В Lisp красиво, без того уродства, коим являются шаблоны C++, любая, и самая сложная, грамматика, парсится в несколько десятков строк.
Лисп безбожно устарел
Автор Closure, наконец то изобрёл монады. Ну и новый термин сходу выдал — трансдьюсеры. Браво, концепция которая даже в императивных языках появилась 10 лет назад, наконец то появилась в Лиспе
Здравствуйте, jazzer, Вы писали:
ХГД>>Очевидно же — высокий порог вхождения. Мне вот парсеры писать нужно бывает редко, грубо говоря раз в год. Поэтому детали я где-то не знаю, где-то не помню. И в целом сложилось впечатление, что я код без спирита быстрее бы писал. Благо и так, и так пробовал. J>Да нет там никакого порога, если человек знает EBNF (а это из раздела базовых вещей, имхо).
Как знание EBNF поможет мне узнать способ получения текущей позиции внутри кода семантического действия? J>Все очень естественно и по докам моментально делается, особенно во втором спирите.
Где в доке написано, что надо подкрутить, чтобы ее не было?
ХГД>>А позицию откуда брать? J>так throw_p ее получит от сканера, когда до него дойдет очередь, как и любой другой парсер (иначе как парсер будет сканить строку дальше?). J>Код такой: J>
J>scan.first — это оно. spirit_error::format — это моя внутренняя функция, перегруженная для разных типов итераторов (и итератор spirit::classic::position_iterator2 как раз отслеживает строку и колонку).
Классик не интересно. Про qi я в доке этого за приемлемое время найти не смог.
J>Никаких тут выводов не наклевывается, кроме выводов о головотяпстве автора property_tree. Такие проблемы могут возникнуть с абсолютно любой библиотекой А, юзающей какую-то другую библиотеку Б, если у Б есть какие-то дополнительные требования, а автор А не потрудился их выяснить и транслировать своим пользователям. Библиотека Б тут ни в чем не виновата — это может быть какая-нть сишная библиотека вообще, пользующая, скажем, какой-нть не thread-safe posix API (tzset, скажем) — автор А обязан своим пользователям об этих ограничениях сказать, даже если собственный код самой А никаких многопоточностей не содержит.
У нас работает народ ничуть не менее склонный к головотяпству, чем авторы property_tree и serialization. Соответственно, с высокой вероятностью так же накосячат. Ну да ладно, классик считай проехали. J>Если честно, я не понял, какое отношение имеет к парсеру задача убирания эскейпов.
Ну как-то же мне их убирать надо. В рукопашном парсере это задача решается походя. Предлагаешь совмещать спирит с низкоуровневым анескейпером? Тоже вариант, конечно, но по-моему его необходимость (или хотя бы предпочтительность) свидетельствовала бы не в пользу спирита. J>и вот на спирите-2: J>http://boost-spirit.com/home/articles/qi-example/parsing-escaped-string-input-using-spirit-qi/ J>благодаря атрибутированности он может вернуть сразу строчку — в классическом пришлось бы push_back-ать каждый символ явным семантическим действием
Я с другого источника драл, но тут тоже отличная иллюстрация к вопросу о низком пороге вхождения. Вот про qi::_r1 я откуда знать должен — из EBNF или таки придется доку штудировать? Еще я вижу, что вместо единожды скомпилированного куска делаются какие-то манипуляции в рантайме. В конструкторе unescaped_string какой-то контейнер содержимым набивают. Т.е., если нужна скорость, в случае сложного парсера мне уже придется выносить его на верхний уровень и протягивать к месту использования в параметрах, чтобы на каждый чих не создавать/разрушать. Да, и я там например хочу на незнакомые эскейпы ругаться "unrecognized escape sequence", с указанием позиции — как добавить?
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, niXman, Вы писали:
ХГД>>Где в доке написано, что надо подкрутить, чтобы ее не было? X>дока моцг не заменит, да.
Это было опровержение утверждения
"Да нет там никакого порога, если человек знает EBNF (а это из раздела базовых вещей, имхо). Все очень естественно и по докам моментально делается, особенно во втором спирите."
, если кто не понял.
Тут доки мало, тут желательно немножко опыта работы с конкретной либой, чтобы потом не тупить над такими ошибками подолгу. Вот тебе что конкретно моск подсказывает на счет этой ошибки? Сообщение об ошибке, которое я привел, содержит достаточно информации, чтобы при желании можно было сказать как это фиксить. Только вот времени у типичного программиста это займет нифга не мало. А некоторые так может и вовсе не осилят.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, niXman, Вы писали:
X>ну епс, нужно знать инструмент который используешь. подобные простыни получаются не только при использовании спирита.
Как раз это и называется "высокий порог вхождения"
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Хон Гиль Дон, Вы писали:
ХГД>Как раз это и называется "высокий порог вхождения"
думается мне, тут последовательность другая.
тот кто только "входит в с++" — вряд ли станет юзать спирит. а тот кто сознательно и объективно выбирает спирит — уже имеет весь необходимый "багаж знаний", чтоб понять о чем простыня размером в *надцать страниц. но это ИМХО, конечно.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, kurchatov, Вы писали:
K>Какие средства предоставляет буст для отладки метапрограмм?
как же ты любишь винить в своей некомпетентности что-то кроме себя =)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали:
X>Здравствуйте, kurchatov, Вы писали:
K>>Какие средства предоставляет буст для отладки метапрограмм? X>как же ты любишь винить в своей некомпетентности что-то кроме себя =)
? Я вообще-то серьезно спросил, про средства отладки.
Здравствуйте, WolfHound, Вы писали:
_>>Вариант Евгения я уже указал как подправить в точности под ваши требования, хотя на мой взгляд это всего лишь придирка (вообще не принципиально функция-член или отдельная шаблонная функция). Про вариант с record тоже всё работает в соответствие с примерами из описания. То, что при этом внутри реализуется чуть другая логика — это опять же придирка. ) WH>Конструкторы предка не создаёт. WH>С приватными членами класса не работает. WH>Фильтрации нет. WH>...
Конструкторы не создаёт, а в описание к Record такого и нет. ) С приватными членами класса никаких проблем нет. С фильтрацией тоже — я чётко описал как её реализовать. )
А к варианту Евгения уже вопросов нет вроде? )
_>>Ну так реализуется то через макросы, а не пересборкой компилятора. ) WH>В случае немерле это одно и то же. А в случае rust существенно разные механизмы. WH>Кстати я тут ещё раз на него глянул. До немерлового варианта ему как до пешком луны.
А что там не так? )
Если что, я сам не смотрел и вообще про Rust почти не в курсе. Хотя подумываю попробовать поиграться и с ним... Так сказать сравнить с D, который я уже более менее ощущаю как инструмент.
ХГД>>Как раз это и называется "высокий порог вхождения" X>думается мне, тут последовательность другая. X>тот кто только "входит в с++" — вряд ли станет юзать спирит. а тот кто сознательно и объективно выбирает спирит — уже имеет весь необходимый "багаж знаний", чтоб понять о чем простыня размером в *надцать страниц. но это ИМХО, конечно.
Ну это несколько противоречит сказанному в соседних сообщениях — "да какой порог вхождения, достаточно EBNF знать, остальное интуитивно" и "лучше все равно ничего нет".
Если же говорить про конкретную ошибку, то тут не в размере простыни дело. Это, увы, своего рода "задачка на сообразительность". О причине ошибки даже проще догадаться было бы не по той простыне, а по следующему за тем, что я привел, однострочному сообщению об ошибке —
boost/fusion/container/vector/convert.hpp(25): error C2027: use of undefined type 'boost::fusion::detail::as_vector<12>'
Вот только для этого, IMHO, надо хоть как-то представлять общие принципы написания подобных fusion либ. Что автоматически исключает не только новичков, но и просто широкие массы не склонных к метапрограммированию и ковырятельству в потрохах библиотек разработчиков. И я, собственно, не вижу в спирите ничего такого, ради чего стоило бы со всем этим возиться. Разве что задача стать мастером ци-гун является самоцелью.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, kurchatov, Вы писали:
K>Отладка компиляции — это прекрасно. Какие средства предоставляет буст для отладки метапрограмм?
(я тут надеюсь, ты это серьезно спрашиваешь, а не просто троллишь)
boost::mpl::print, BOOST_MPL_ASSERT_MSG вкупе с правильно организованной диагностикой.
(пример использования можно увидеть в конце http://rsdn.ru/forum/cpp/3722136.1
)
Рулез последнего в том, что его очень хорошо видно благодаря куче звездочек, и все полотенце можно смело не читать.
Почему-то программисты, которые продумывают обработку ошибок в своих программах, совершенно об этом забывают при написании метапрограмм.
А потом получают коредамп огромный вывод компилятора и говорят, что очень трудно отлаживать.
Как будто легко разбираться в дампе обычной рухнувшей программы, если в ней не было никакой обработки ошибок.
Писать метапрограммы надо, вынося обработку ошибок в отдельное место, чтоб компилятор не пытался компилировать заведомо неправильный код и не выносил пользователю мозг тоннами сообщений об ошибках в нем: http://rsdn.ru/forum/cpp/4530248.1
Здравствуйте, jazzer, Вы писали:
ХГД>>Это при применении спирита их искать замучаешься А уж если надо вычислять позицию, на которой случился синтакс еррор — вообще вешайся. А с низкоуровневым кодом пофиг, все прекрасно отлаживается, если чего-то не хватает — дописать можно без многочасовых копаний в доках или чужих исходниках. J>На этот счет у меня есть специальный одноклеточный "парсер" throw_p, который прекращает парсинг и бросает исключение со всем необходимым (строка, колонка, объяснение). J>Типа:
Здравствуйте, alex_public, Вы писали:
_>А к варианту Евгения уже вопросов нет вроде? )
Надоело повторять. Всё равно очевидное не признаешь.
_>А что там не так? )
Rust только проверяет синтаксис. А немерле ещё много чего делает.
Прочитай описание. Там полторы страницы на двоих.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
_>>А к варианту Евгения уже вопросов нет вроде? ) WH>Надоело повторять. Всё равно очевидное не признаешь.
Имелось в виду с моей поправкой (что реализуем функцию-член через наследование) — тогда даже с вашей дурацкой придиркой всё в точности выходит.
WH>Rust только проверяет синтаксис. А немерле ещё много чего делает.
А что ещё может быть нужно? ) Ну т.е. конечно ещё типобезопасность передаваемых в запрос параметров, но это уже надо схему базы данных и т.п. )
Здравствуйте, alex_public, Вы писали:
_>Имелось в виду с моей поправкой (что реализуем функцию-член через наследование) — тогда даже с вашей дурацкой придиркой всё в точности выходит.
Наследование не работает. Я тебе это показал.
_>А что ещё может быть нужно? ) Ну т.е. конечно ещё типобезопасность передаваемых в запрос параметров, но это уже надо схему базы данных и т.п. ) https://github.com/rsdn/nemerle/wiki/SQL-macros
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, niXman, Вы писали:
X>абсолютно каждая компания в_которой/с_которой мне приходилось работать — использовали boost. так что я хз, о чем ты...
У меня ровно обратное — ни в одной компании boost не использовали.
Здравствуйте, Dair, Вы писали:
X>>абсолютно каждая компания в_которой/с_которой мне приходилось работать — использовали boost. так что я хз, о чем ты... D>У меня ровно обратное — ни в одной компании boost не использовали.
Более того — есть конторы где явный запрет использовать в продакшне либы навроде буста.
J>>И синтаксические ошибки сразу перестают быть проблемой.
EP>Причём если не хочется, можно даже свой throw_p не писать (хоть он и удобен) — есть готовые qi::eps, operator> и т.п.
Если честно, я не знаю, как из eps достать позицию. Поэтому и написал свой парсер.
Т.е. примерно понятно, как это сделать в классическом спирите, там в действие приходит пара итераторов, а как с qi — не знаю, там же атрибут приходит.
Я просто основную массу своих парсеров написал на классическом, второй вышел слишком поздно, у меня на нем пара парсеров всего.
Здравствуйте, jazzer, Вы писали:
J>Если честно, я не знаю, как из eps достать позицию. Поэтому и написал свой парсер. J>Т.е. примерно понятно, как это сделать в классическом спирите, там в действие приходит пара итераторов, а как с qi — не знаю, там же атрибут приходит.
И не нужно доставать (насколько я представляю, они и не передаются в семантическое действие) — expectation parser сам кинет исключение expectation_failure, в котором есть пара итераторов и what_ (которое зависит от .name правил). Можно исключение самому ловить, а можно просить Spirit через on_error. Причём там даже можно восстановится после ошибки и продолжить разбор.
Полный пример тут — Mini XML Error Handling.
J>Я просто основную массу своих парсеров написал на классическом, второй вышел слишком поздно, у меня на нем пара парсеров всего.
Кстати, а мне задачи парсинга вообще редко попадаются, но Spirit использую без проблем.
Здравствуйте, WolfHound, Вы писали:
WH>Наследование не работает. Я тебе это показал.
Ты ничего не показал. Ты написал некую ерунду, я тебе на это указал и дальше ты промолчал. Давай ещё раз по пунктам:
1. Вообще то изначально говорилось просто про функцию-член, а не члена некого абстрактного интерфейса, так что классический вариант примеси (mixin) на C++ отлично работал.
2. Но если захотим и абстрактный интерфейс использовать, то тоже абсолютно никаких проблем. Я не понял откуда ты взял тот бредовый код с наследованием структурки (а не примеси) от интерфейса. Вот нормальный пример:
Значит имеем некий интерфейс:
struct IHash{ virtual int GetHash()=0; };
и некий класс, которому мы хотим добавить автоматическую реализацию этого интерфейса:
struct Person{
string name;
int age;
bool sex;
};
Ну так это будет банально выглядеть так:
struct Person: public HashImpl<Person>{
string name;
int age;
bool sex;
};
void PrintHash(IHash* h) {cout<<h->GetHash()<<endl;}
Person p;
PrintHash(&p);
где реализация является тривиальным
template<typename T> struct HashImpl: public IHash{
int GetHash() override {/* здесь код Евгения */}
};
3. Самое забавное, что это далеко не единственный способ. Можно ещё и по другому добавлять. Например самый банальный способ будет таким:
struct Person{
string name;
int age;
bool sex;
declare_hash;
};
с реализацией вида
#define declare_hash int GetHash() {/* здесь код Евгения */}
Опять же ровно одна дополнительная строка в классе (как и в D или Nemerle). Так что не вижу вообще никаких проблем в данной области. Собственно я вообще считаю глупым придирку по поводу функции вместо функции-члена, т.к. в целом речь была о другом. Но даже эта придирика у вас не вышла.
А особенно это всё забавно на фоне того факта, что на C++ действительно недоступно множество возможностей МП, которые есть в D/Rust/Nemerle. Но вы в них почему-то не попадаете никак — похоже привыкли демонстрировать превосходство Nemerle над совсем унылым C#, а не над C++.)))
_>>А что ещё может быть нужно? ) Ну т.е. конечно ещё типобезопасность передаваемых в запрос параметров, но это уже надо схему базы данных и т.п. ) WH>https://github.com/rsdn/nemerle/wiki/SQL-macros
О, а вот передача параметров в запрос по имени локальной переменной — это действительно выглядит классно. В C++ библиотечке для работы с БД аналогичное делается только по порядку, что значительно менее наглядно. Про проверку синтаксиса я вообще не говорю. )))
Да, а вот на D думаю без проблем делается нечто похожее, хотя готовых реализаций не видел.
Здравствуйте, Ikemefula, Вы писали:
I>Более того — есть конторы где явный запрет использовать в продакшне либы навроде буста.
назовите, пожалуйста, хоть одну такую контору. ибо я предполагаю, что это либо никчемный стартап, либо что-то низко-совковое. потому что ни твитер, ни фейсбук, ни гугл, ни адоб, ни оракл — быть не может в вашем списке.
спасибо, очень жду ваш список конторок.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали:
K>>Какие средства предоставляет буст для отладки метапрограмм?
Браво, хороший вопрос! )
X>как же ты любишь винить в своей некомпетентности что-то кроме себя =)
<психоанализ мод он>Парень спросил про буст, а ты подумал что раз очевидно что это должен делать язык и рантайм,
но рантайм не может по определению, то значит в языке С++ такое невозможно —
следовательно упоминание конкретно про буст была нападка.
А ведь это серьезный вопрос.
<психоанализ мод офф>
Действительно: С++ такого не может. Жаль, и мне нравится С++ тоже, но это так.
---
Я всегда говорю: хотите узнать насколько готова среда для реальной настоящей работы, а не исследовательской
или поиграться — посмотрите для этого какие есть средства для отладки в этой среде.
Потому что в реальной жизни всегда есть реальные проблемы, т.е. трудные. Если есть отладчик,
значит тут кто-то был до нас и сделал как надо для работы для решения проблем. а не выпендрежа.
Особенно хорошо если это кто-то был из разработчиков ядра системы, и встроил концепции глубоко и правильно,
а не для собственного прикола, как в данном случае со Страуструпом случилось.
Вот например в Common Lisp-e макрос отладить можно с помощью функций macroexpand и macroexpand-1.
Видно, что лисп сделан как "программируемый язык программирования" (это его мотто).
Те, кто хотят работать с С++ом на этом уровне берут OpenC++ и т.п. вещи, допиливают для себя, делают из
него инструменты, пытаются коммерциализировать (сипровер весь хабр заспамил), и все равно не дотягивает,
и в итоге то что в "лиспах" есть из коробки и в его ядре, в других языках чаще всего недоступно вообще никак.
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, Mna, Вы писали:
C>>>Ну так в LISP уродливо всё остальное. Mna>>Есть претензии к Common Lisp кроме скобок? C>Отсутствие типов, отсутствие нормального синтаксиса и т.п.
Скобки для лиспа и синтаксис это одно и то же.
Это преодолевается таким образом:
на самом деле я думаю Питон взял отступы из Лиспа, ведь там дописывают закрывающие скобки
автоматом в среде, а открывают перед каждым нужным новым keyword-ом, и учитывая отступы по вложенности,
то есть получается как в Питоне, но без обязаловки с отступами.
ну то есть это в принципе нормально. среда рулит.
Остаются динамические типы против статических.
Тут сказать нечего: программисты бывают двух типов.
1 выбирающие мощь и свободу, или
2 выбирающие ограничения и призрачную надежду.
Ограничения в виде барьеров лишних объявлений, и инквизиции статических проверок компилятора,
с надеждой что такой язык/компилятор себя окупит в среде масс корпоративных программистов, которые согласно обычаю
не проверяют ни типов и не пишут никогда тестов, согласно тому же обычаю.
Их девиз "компилируется значит работает"
Здравствуйте, Mna, Вы писали:
Mna>Остаются динамические типы против статических. Mna>Тут сказать нечего: программисты бывают двух типов. Mna>1 выбирающие мощь и свободу, или Mna>2 выбирающие ограничения и призрачную надежду. Mna>Ограничения в виде барьеров лишних объявлений, и инквизиции статических проверок компилятора, Mna> с надеждой что такой язык/компилятор себя окупит в среде масс корпоративных программистов, которые согласно обычаю Mna> не проверяют ни типов и не пишут никогда тестов, согласно тому же обычаю. Mna> Их девиз "компилируется значит работает"
А можно озвучить мощный и свободный язык программирования, который позволит мне осуществлять сложную фильтрацию в реальном времени FHD/4K видео? )
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Mna, Вы писали:
Mna>>Остаются динамические типы против статических. Mna>>Тут сказать нечего: программисты бывают двух типов. Mna>>1 выбирающие мощь и свободу, или Mna>>2 выбирающие ограничения и призрачную надежду. Mna>>Ограничения в виде барьеров лишних объявлений, и инквизиции статических проверок компилятора, Mna>> с надеждой что такой язык/компилятор себя окупит в среде масс корпоративных программистов, которые согласно обычаю Mna>> не проверяют ни типов и не пишут никогда тестов, согласно тому же обычаю. Mna>> Их девиз "компилируется значит работает"
_>А можно озвучить мощный и свободный язык программирования, который позволит мне осуществлять сложную фильтрацию в реальном времени FHD/4K видео? )
Если ты про производительность,
то когда нужна производительность выбираешь низкоуровневый язык поближе к железу и не рыпаешься просто нет других вариантов, -- тут понятно, я ничего не смогу предложить : С++/С -- и может даже писать ассемблерные вставки вручную, если С компилятор новые инструкции пока не поддерживает.
Но если С компилятор не поддерживает, то тот же асм можно сгенерировать и функциональными языками программирования, почему нет. может даже и попроще будет.
А ежели ты про то, что статические ограничения особенно увеличивают производительность, я считаю что пример Haskell-а, самого органичивающего показывает, что ограничения не спасают, и все равно получается медленно.
Или например С++, его "метапрограммы" жутко медленно компилируются.
Нет я бы тоже хотел, чтоб все хорошее в языке было (не важно название) и не было ничего плохого , но приходится выбирать.
Здравствуйте, Mna, Вы писали:
_>>А можно озвучить мощный и свободный язык программирования, который позволит мне осуществлять сложную фильтрацию в реальном времени FHD/4K видео? )
Mna>Если ты про производительность, Mna>то когда нужна производительность выбираешь низкоуровневый язык поближе к железу и не рыпаешься просто нет других вариантов, -- тут понятно, я ничего не смогу предложить : С++/С -- и может даже писать ассемблерные вставки вручную, если С компилятор новые инструкции пока не поддерживает.
Инструкции он все знает. Но не все максимально эффективно использует — есть исключение в виде SIMD. Т.е. если классический код даже хороший спец. по ассемблеру сейчас вряд ли напишет эффективнее компилятора C/C++, то SIMD код написанный руками пока что заметно эффективнее созданного компилятором (так называемая автовекторизация циклов). Надеюсь когда-нибудь и simd будет автоматом на максимуме оптимальности, ну а пока для этого есть ручные спец. инструменты (в том числе и в самом C++).
Mna>Но если С компилятор не поддерживает, то тот же асм можно сгенерировать и функциональными языками программирования, почему нет. может даже и попроще будет.
Так а есть такие готовые платформы? ) Потому как об использование подобного я бы может ещё и задумался, а вот писать самому с нуля — нет спасибо. )))
Mna>А ежели ты про то, что статические ограничения особенно увеличивают производительность, я считаю что пример Haskell-а, самого органичивающего показывает, что ограничения не спасают, и все равно получается медленно.
В Хаскеле у нас сборщик мусора, параметрический полиморофизм и попытка (в реальности конечно полностью не выходит, но даже это замедляет) работы исключительно с иммутабельными данными. Это весьма сомнительный пример.
Да, и ограничения действительно помогают в производительности. В том смысле, что сообщают компилятору необходимую ему для оптимизации информацию.
Mna>Или например С++, его "метапрограммы" жутко медленно компилируются.
Согласен, медленно. Только при этом они потом работают быстрее всех. )
Mna>Нет я бы тоже хотел, чтоб все хорошее в языке было (не важно название) и не было ничего плохого , но приходится выбирать.
Здравствуйте, Mna, Вы писали:
Mna>Или например С++, его "метапрограммы" жутко медленно компилируются.
Причина этому ровно одна — компиляторы не заточены архитектурно под быструю компиляцию метапрограмм.
Они заточены под быструю компиляцию "обычного" кода, где типов мало (и, как следствие, разных воплощений шаблонов тоже мало).
В GCC, например, использовались простые односвязные списки воплощений шаблонов. Соответственно, если ты шаблон воплотил с разными типами тысячу раз — будут тормоза на ровном месте. В какой-то из версий GCC это пофиксили, ускорение, как и следовало ожидать, оказалось алгоритмическим.
Так что постепенно подтянутся.
Ну и язык на месте не стоит.
Те же variadic templates существенно сократили необходимый код и сложность шаблонов с неопределенным количеством аргументов. То есть когда раньше тебе приходилось генерить все возможные варианты шаблона для каждого количества аргументов препроцессором или через рекурсивные шаблоны (что приводило к взрыву в смысле количества вариантов шаблонов и их воплощений), то теперь ты пишешь ровно один шаблон, и компилятор знает, как его обрабатывать, дял любого количечства аргументов.
Или разрешение использовать для воплощения шаблонов локально объявленные типы (ну и полиморфные лямбды туда же). Это позволяет компилятору выкинуть все локальные типы и шаблоны по окончании компилирования данной области видимости (скажем, внутри if) — а раньше приходилось все объявлять в глобальной области видимости и оно все в результате анализировалось всеми остальными частями программы, что, понятно, могло только замедлять компиляцию.
Ну и еще одна причина — модель текстового включения через #include, когда одно и то же компилится по многу раз для разных единиц трансляции. Но это решается прекомпилированными заголовками.
Здравствуйте, Ikemefula, Вы писали:
X>>>абсолютно каждая компания в_которой/с_которой мне приходилось работать — использовали boost. так что я хз, о чем ты... D>>У меня ровно обратное — ни в одной компании boost не использовали. I>Более того — есть конторы где явный запрет использовать в продакшне либы навроде буста.
Ну, такого не видел, но в реальной жизни у меня не было задач, требующих boost больше чем, например, смартпоинтеры. Да, смартпоинтеры мы из буста взяли, они там хорошие, годные. Остальное, наверно, тоже хорошее, но как-то что-то не надо.
Mna>Я всегда говорю: хотите узнать насколько готова среда для реальной настоящей работы, а не исследовательской Mna>или поиграться — посмотрите для этого какие есть средства для отладки в этой среде. Mna>Потому что в реальной жизни всегда есть реальные проблемы, т.е. трудные. Если есть отладчик, Mna>значит тут кто-то был до нас и сделал как надо для работы для решения проблем. а не выпендрежа. Mna>Особенно хорошо если это кто-то был из разработчиков ядра системы, и встроил концепции глубоко и правильно, Mna> а не для собственного прикола, как в данном случае со Страуструпом случилось.
Это интересный вопрос. Я раньше думал, что Страуструп добавил шаблоны только для статического полиморфизма, но теперь понимаю, что этот человек не мог не предвидеть, как шаблоны станут использоваться для метапрограммирования. Хотя в его книге нет упоминания про вычисления в compile time (или я ошибаюсь?), он дал молчаливое согласие на развитие концепций метапрограммирования в С++ и библиотеки boost.
Кстати, хорошая книга по метапрограммированию в С++ (ну или кому хочется убить свое время ): C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond (Abrahams, Gurtovoy)
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Mna, Вы писали:
_>>>А можно озвучить мощный и свободный язык программирования, который позволит мне осуществлять сложную фильтрацию в реальном времени FHD/4K видео? )
Mna>>Если ты про производительность, -- С++/С -- и может даже писать ассемблерные вставки вручную, если С компилятор новые инструкции пока не поддерживает.
_>Инструкции он все знает. Надеюсь когда-нибудь и simd будет автоматом на максимуме оптимальности, ну а пока для этого есть ручные спец. инструменты (в том числе и в самом C++).
интересно было бы узнать что это за штуки
Mna>>Но если С компилятор не поддерживает, то тот же асм можно сгенерировать и функциональными языками программирования, почему нет. может даже и попроще будет.
_>Так а есть такие готовые платформы? ) Потому как об использование подобного я бы может ещё и задумался, а вот писать самому с нуля — нет спасибо. )))
А я, если бы узкая и четко определенная задача, рискнул бы и с нуля написать
Честно говоря, мне такие штуки не пригождались, не искал, единственно что напомнило -- это проект AsmJit, но он написан на С++е
AsmJit is a complete JIT and remote assembler for C++ language. It can generate native code for x86 and x64 architectures and supports the whole x86/x64 instruction set — from legacy MMX to the newest AVX2. It has a type-safe API that allows C++ compiler to do a semantic checks at compile-time even before the assembled code is generated or run.
не знаю насколько подойдет
--
А из примеров на функциональных языках вспоминается проект встроенного решения С-код для которого генерировался из OCaml.
Mna>>А ежели ты про то, что статические ограничения особенно увеличивают производительность, я считаю что пример Haskell-а, самого органичивающего показывает, что ограничения не спасают, и все равно получается медленно.
_>В Хаскеле у нас сборщик мусора, параметрический полиморофизм и попытка (в реальности конечно полностью не выходит, но даже это замедляет) работы исключительно с иммутабельными данными. Это весьма сомнительный пример.
Я Хаскел приводил как пример языка с самыми сильными constraint-ами.
не знаю что есть сильнее или такое же сильно ограничивающее, но чтоб с zero-overhead-ом, я бы на это посмотрел.
Rust?
Zero overhead бывает двух видов, обычно имеется ввиду первый:
1 язык/рантайм не потребляет больше того что реально нужно, получается шустрая программа, ценой трудов программиста по спецификации типов
2 от программиста не запрашивают специфицировать все типы очень детально, и программа получается не такая шустрая, но зато пишется быстрее.
так и напрашивается автоматический выводитель типов. чтоб тип сразу в текст в исходник вписывал.
_>Да, и ограничения действительно помогают в производительности. В том смысле, что сообщают компилятору необходимую ему для оптимизации информацию.
да-да. Python и Cython: Cython быстрый как почти С++.
Mna>>Или например С++, его "метапрограммы" жутко медленно компилируются.
_>Согласен, медленно. Только при этом они потом работают быстрее всех. )
вот от этой медленности люди и сбегают к динамическим интерпретируемым языкам!
Потому что дольше всех работает оптимизатор машинного кода, а машины сейчас быстрые, для множества задач такой скорости и не требуется
Mna>>Нет я бы тоже хотел, чтоб все хорошее в языке было (не важно название) и не было ничего плохого , но приходится выбирать. _>
Здравствуйте, jazzer, Вы писали:
Mna>>Или например С++, его "метапрограммы" жутко медленно компилируются.
J>Причина этому ровно одна — компиляторы не заточены архитектурно под быструю компиляцию метапрограмм.
J>Они заточены под быструю компиляцию "обычного" кода, где типов мало (и, как следствие, разных воплощений шаблонов тоже мало). J>В GCC, например, использовались простые односвязные списки воплощений шаблонов из версий GCC это пофиксили, ускорение, как и следовало ожидать, оказалось алгоритмическим. J>Так что постепенно подтянутся.
Да, интересно.
А мне всегда казалось что проблемы две, сложная вязь из двух: проблемы с мета-компиляцией, что метакомпиляторы постепенно вырастали из обычных С/С++ компиляторов и метакомпиляция не была изначально органично спроектирована,
ну вот что собственно было выше описано,
И смешаны вперемешку с проблемами оптимизатора, оптимизатор хочет сделать самый оптимальный код, а часто и добивается
его, но тратит на свое динамическое программирование, на переборы и оценки деревьев стоимости кучу времени.
Вот такое интуитивное представление
J>Ну и еще одна причина — модель текстового включения через #include, когда одно и то же компилится по многу раз для разных единиц трансляции. Но это решается прекомпилированными заголовками.
Вот этого никак понять не могу. что мешает отказаться в очередной версии стандарта C++ от модели текстового включения?
Пусть поддерживают оба, новый и исторический способ, а рекомендуют пакетное включение, import как в джаве например.
и все довольны?
а внутри по сути такой же прекомпилированный header, только уже переносимый на уровне языка. и реализации уже есть.
Здравствуйте, Mna, Вы писали:
Mna>Вот этого никак понять не могу. что мешает отказаться в очередной версии стандарта C++ от модели текстового включения? Mna>Пусть поддерживают оба, новый и исторический способ, а рекомендуют пакетное включение, import как в джаве например.
Примерно так и хотят сделать. Правда хз когда окончательно решатся.
Здравствуйте, Mna, Вы писали:
Mna>А из примеров на функциональных языках вспоминается проект встроенного решения С-код для которого генерировался из OCaml.
А еще есть проект на Haskell, где хаскеловская программа транслируется в шаблонный метакод С++
Mna>Zero overhead бывает двух видов, обычно имеется ввиду первый: Mna>1 язык/рантайм не потребляет больше того что реально нужно, получается шустрая программа, ценой трудов программиста по спецификации типов Mna>2 от программиста не запрашивают специфицировать все типы очень детально, и программа получается не такая шустрая, но зато пишется быстрее.
Ну так auto же
Mna>вот от этой медленности люди и сбегают к динамическим интерпретируемым языкам!
Для прототипирования динамические языки — самое оно.
Mna>Потому что дольше всех работает оптимизатор машинного кода, а машины сейчас быстрые, для множества задач такой скорости и не требуется
Ну, для таких задач и С++ не нужен тогда.
С другой стороны, вот, скажем, браузеры — ведь сколько скорости ни дай, всё мало же.
Mna>>>Нет я бы тоже хотел, чтоб все хорошее в языке было (не важно название) и не было ничего плохого , но приходится выбирать.
"все хорошее" бывает либо за счет сильной совместимости с другими языками с вытекающими из этого ограничениями (живой пример — С++ по отношению к Си), либо за счет кучи бабла (нанять армию программеров, которые бы на твоем языке воспроизвели все нужные библиотеки, чтоб не было необходимости с тоской смотреть на недоступные сишные)
Здравствуйте, Mna, Вы писали:
_>>Инструкции он все знает. Надеюсь когда-нибудь и simd будет автоматом на максимуме оптимальности, ну а пока для этого есть ручные спец. инструменты (в том числе и в самом C++). Mna>интересно было бы узнать что это за штуки
В C++ это естественно соответствующие intrinsic-функций (https://gcc.gnu.org/onlinedocs/gcc-4.9.1/gcc/X86-Built-in-Functions.html). Это конечно же совсем низкоуровневый инструмент, который по хорошему надо заворачивать в удобные абстракции (в том числе и с помощью тех же шаблонов).
Mna>Честно говоря, мне такие штуки не пригождались, не искал, единственно что напомнило -- это проект AsmJit, но он написан на С++е Mna>
Mna>AsmJit is a complete JIT and remote assembler for C++ language. It can generate native code for x86 and x64 architectures and supports the whole x86/x64 instruction set — from legacy MMX to the newest AVX2. It has a type-safe API that allows C++ compiler to do a semantic checks at compile-time even before the assembled code is generated or run.
Mna>не знаю насколько подойдет
Нууу тут немного другой интерес. Это скорее аналог функции eval из скриптовых языков. Т.е. главное не в быстродействие, а в возможности динамической генерации кода.
Mna>Я Хаскел приводил как пример языка с самыми сильными constraint-ами. Mna>не знаю что есть сильнее или такое же сильно ограничивающее, но чтоб с zero-overhead-ом, я бы на это посмотрел. Mna>Rust?
Я пока с ним не знаком, по нормальному. Но судя по некоторым оценкам может получиться как раз замечательное решение. Или не получиться — там сейчас все правила меняются раз в месяц. )))
Mna>Zero overhead бывает двух видов, обычно имеется ввиду первый: Mna>1 язык/рантайм не потребляет больше того что реально нужно, получается шустрая программа, ценой трудов программиста по спецификации типов Mna>2 от программиста не запрашивают специфицировать все типы очень детально, и программа получается не такая шустрая, но зато пишется быстрее.
Mna>так и напрашивается автоматический выводитель типов. чтоб тип сразу в текст в исходник вписывал.
Так раздражает статическая типизация или требование указывать все типы? ) Это немного разные вещи... Видно по тому же Хаскелю, да и в современном C++ уже можно писать код из одних auto. )))
Mna>вот от этой медленности люди и сбегают к динамическим интерпретируемым языкам! Mna>Потому что дольше всех работает оптимизатор машинного кода, а машины сейчас быстрые, для множества задач такой скорости и не требуется
Нуу а машина разработчика ещё намного быстрее быстрых машин пользователей... ))) Во всяком случае моя. )))
Здравствуйте, alex_public, Вы писали:
_>2. Но если захотим и абстрактный интерфейс использовать, то тоже абсолютно никаких проблем. Я не понял откуда ты взял тот бредовый код с наследованием структурки (а не примеси) от интерфейса. Вот нормальный пример:
Если пример не вписывается в концепцию тем хуже для примера.
_>
_>#define declare_hash int GetHash() {/* здесь код Евгения */}
_>
Слово private убивает его реализацию.
_>А особенно это всё забавно на фоне того факта, что на C++ действительно недоступно множество возможностей МП, которые есть в D/Rust/Nemerle. Но вы в них почему-то не попадаете никак — похоже привыкли демонстрировать превосходство Nemerle над совсем унылым C#, а не над C++.)))
Вы сначала примитив осильте.
_>О, а вот передача параметров в запрос по имени локальной переменной — это действительно выглядит классно. В C++ библиотечке для работы с БД аналогичное делается только по порядку, что значительно менее наглядно. Про проверку синтаксиса я вообще не говорю. )))
Ты ещё создание локальных переменных по именам колонок результата запроса не заметил.
_>Да, а вот на D думаю без проблем делается нечто похожее, хотя готовых реализаций не видел.
А ты в D можешь на этапе компиляции в базу данных сходить?
Если нет. То не делается.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Если пример не вписывается в концепцию тем хуже для примера.
Ну если ты покажешь мне ситуацию, в которой в данном примере почему-то может быть запрещено наследование HashImpl от IHash, то тогда твои слова ещё будут иметь какой-то смысл. А так, это просто демагогия.
WH> WH>Слово private убивает его реализацию.
Что-что? )
_>>О, а вот передача параметров в запрос по имени локальной переменной — это действительно выглядит классно. В C++ библиотечке для работы с БД аналогичное делается только по порядку, что значительно менее наглядно. Про проверку синтаксиса я вообще не говорю. ))) WH>Ты ещё создание локальных переменных по именам колонок результата запроса не заметил.
Это я как раз видел, но не особо впечатлился, т.к. аналогичный код на C++ выглядит как-то так:
т.е. ни в чём не уступает по удобству. А возможно даже и превосходит за счёт работы автодополнения.
Вот возможность подстановки локальных переменных в запрос по имени — это действительно удобно и подобных решений я на C++ не видел (а вот на Питоне вроде было что-то такое). Хотя тут как раз Евгений выложил очень любопытную реализацию http://rsdn.ru/forum/cpp/5815557
— возможно на её базе и можно было бы сделать что-то близкое...
_>>Да, а вот на D думаю без проблем делается нечто похожее, хотя готовых реализаций не видел. WH>А ты в D можешь на этапе компиляции в базу данных сходить? WH>Если нет. То не делается.
Это было про захват переменной по имени и т.п. А насчёт работы с БД во время компиляции... Т.е. если в данный момент доступа к БД нет, то и проект не удастся скомпилировать? )