Pull to refresh
«Библиотеки для C++ нередко похожи на русскую классику: страдает либо их автор, либо пользователь, либо архитектура». Автор этой цитаты, Сергей Садовников из «Лаборатории Касперского», прошел свой путь от страданий к просветлению и узнал о метапрограммировании в С++ нечто важное и нужное. Сочувствующих приглашаем в волшебный мир макросов, шаблонов, boost и прочих loki.
Подробности – под катом
Total votes 65: ↑64 and ↓1+63
Comments39

Comments 39

А стоит ли вообще заставлять язык делать то, для чего он не был предназначен изначально? Может просто взять ту же Java, где рефлексия встроена с рождения? А C++ оставить для решения задач более ему подходящих.
У Java будут свои слабые места. Но другие. Но так то да — для кого-то может быть и проще. Для других — уже нет. Скажем, где-то Java может оказаться неприменимым как инструмент.
Где вы увидели в java компилтайм-рефлексию? Где вы вообще видели подобное? C++ был изначально рождён на невероятно мощном/расширяемом базовом синтаксисе(java/c# и многие другие не дадут соврать) + в основу были взяты мета/кодоген-возможности. Вот их и расширяют, а C++ находится в авангарде подобного(именно статического, именно компилтайм) функционала в языках вообще.

А C++ оставить для решения задач более ему подходящих.

Именно эти задачи и подходящие. Именно эти возможности и позволяю эффективно решать те самых подходящие задачи.
Где вы вообще видели подобное?
«Что-то подобное» — это что? Метапрограммирование? Lisp в 60е имел приличную поддержку — в том числе компилируемые варианты. Scheme в 70е. Dylan в 90е. Потом все увлеклись «новой игрушкой» — C++. В которой тоже было обнаружено метапрограммирование. Вот собственно именно потому, что оно там было обнаружено, а не дабавлено — оно и получилось таким ужасным.

Однако, к сожалению, до Rust'а все языки с приличным метапрограммированием имели «толстый» рантайм, так что там, где это было неприемлемо — С++ был естественным выбором.

Rust же, разумеется, даёт 100 очков фору C++ — потому что его создатели простую вещь: если у вас компилятор написан на C++/Rust — но можно позволить просто загружать модули в него… и всё! Не нужно разрабатывать десятилетиями метаязык… можно просто основной язык сделать метаязыком — и вы, вдруг, получаете на порядок больше возможностей, чем в C++20.

У Rust'а есть свои заморочки, конечно, но вот конкретно метапрограммирование — в нём сделано правильно… так, как в 60е в LISP'е! Всего-то полвека потребовалось, чтобы разумный подход [почти] добрался до мейнстрима… а кто-то рассказывает сказки про то, что в IT развитие быстро просиходит…
«Что-то подобное» — это что? Метапрограммирование?

Фичи описанные в статье.

Lisp в 60е имел приличную поддержку — в том числе компилируемые варианты.

Покажите. К тому же компиляция компиляции рознь. Тоже самое и с метапрограммированием. Лисп и прочие подобные представители — это просто генерация уровня чуть выше текстовых шаблонов при крайне примитивных синтаксических/статических возможностях. С тех же 60/70 годах в си были макросы и это тоже формально метапрограммирование. Но уже давно никого не волнуют формальности, а волнуют нюансы.

Scheme в 70е. Dylan в 90е.

Аналогично. Я столько слышал, но ни разу не видел. Покажите мне аналог constexpr, описанной статической рефлексии, шаблоны и прочее. Что-то уровня libclang и т.д.

Потом все увлеклись «новой игрушкой» — C++. В которой тоже было обнаружено метапрограммирование.

Оно не было там обнаружено. Оно там было изначально. Обнаружено там было другое — расширенное использование и выход на компилтайм-вычисления.

Вот собственно именно потому, что оно там было обнаружено, а не дабавлено — оно и получилось таким ужасным.

И чем же оно принципиально ужасней лиспа? Вы сможете показать сравнения ужасностей?

Однако, к сожалению, до Rust'а все языки с приличным метапрограммированием имели «толстый» рантайм, так что там, где это было неприемлемо — С++ был естественным выбором.

Раст никоим образом не конкурент С++. Из метапрограммирования там только макросы с инопланетным синтаксисом, т.к. по-сути внешний язык(как и в си). По части же компилтайм-вычислений там вообще ничего нет. Начали пытаться добавлять какие-то зачатки constexpr.

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

Rust же, разумеется, даёт 100 очков фору C++ — потому что его создатели простую вещь:

Его создатели осознали простую вещь — идти простым путём просто, а сложным сложно. И были выбраны везде и всюду простые пути. Можно сколько спорить на тему «почему был сделан такой выбор», но выбор этот сделан — это очевидно.

если у вас компилятор написан на C++/Rust — но можно позволить просто загружать модули в него… и всё!

Ничего не понял. Что мешает загружать эти модули в С++-компилятор? Ничего. Это не имеет никакого отношения к языку. Это просто попытка разыграть карту «у нас один компилятор, а у вас много», но это глупо.

Не нужно разрабатывать десятилетиями метаязык… можно просто основной язык сделать метаязыком — и вы, вдруг, получаете на порядок больше возможностей, чем в C++20.

Где в расте какие-то мета-возможности? Зачем в мета-язык тащить аналог constexpr? Зачем там макросы на внешнем языке?

У Rust'а есть свои заморочки, конечно, но вот конкретно метапрограммирование — в нём сделано правильно… так, как в 60е в LISP'е!

Да, это действительно так. В лиспе придерживались того же пути, той же практики — идти туда, где проще. К чему это привело — все знают. Лисп умер, а то что не умерло — преобразовалось в тот самый аналог С++. Но и его положение так же известно.

Всего-то полвека потребовалось, чтобы разумный подход [почти] добрался до мейнстрима… а кто-то рассказывает сказки про то, что в IT развитие быстро просиходит…

А чего вы взяли, что этот подход «разумный»? Какие этому есть основания? История лиспа? Это контр-пример.

К тому же, года к появлению раста имеют мало отношение. А что действительно имеет отношение — это С++ и развитие его инфраструктуры. И именно компилятор(llvm) и прочий рантайм позволил расту существовать. С++ подарил ту инфраструктуру — которая позволяет кому угодно(хоть студенту первого курса) сделать новый язык, который зарулит все те, которые существовали до.

Оно не было там обнаружено. Оно там было изначально.
Не было там изначально нифига. Изначально шаблоны вообще планировались как параматризованные типы в Extended Pascal, но кому-то пришла в голову светлая мысль со специализациями шаблонов.

После чего оказалось, что, во-первых, эффективно реализовать шаблоны после этого затруднительно с одной стороны, а с другой — было выяснено, что они — полны по Тьюрингу (а да — известно кто и когда это сделал).

Ну а дальше — начали вокруг этого надстраивать многоэтажные уровни костылей.

И чем же оно принципиально ужасней лиспа? Вы сможете показать сравнения ужасностей?
Принципиально ужасней лиспа оно тем, что у вас два разных языка. А не один, как во всех системах с приличным метапрограмированием сделано.

Что мешает загружать эти модули в С++-компилятор? Ничего.
Но ничего и не помогает. Стандартного способа нет.

Это просто попытка разыграть карту «у нас один компилятор, а у вас много», но это глупо.
Это не глупо. Это как раз принципиально. Вы можете сделать не просто модуль, который может как угодно обрабатывать то, что вы пишите на своём языке — вы можете добавлять сущности описанные во внешних файлах или даже базах данных. Когда это появился в C++? В C++40? Или в C++80? А в LISP — это всё было в 60е. В rust — это можно сделать сегодня (хотя diesel появился чуть раньше и, увы, основан на кодогенерации.

Где в расте какие-то мета-возможности? Зачем в мета-язык тащить аналог constexpr? Зачем там макросы на внешнем языке?
Вы пропустили самый главный вопрос: а зачем нам вообще метаязык. Зачем нам все это costexpr и прочая муть? Почему мы не можем просто разрешить обычному коду на C++ работать во время компиляции?

В лиспе придерживались того же пути, той же практики — идти туда, где проще.
Э… вас часом с детстве не роняли? Идти туда, где проще — это как раз девиз Unix, C и C++. Про это даже статью известную написали.

Или вы исходите из того, что C++ сложен, а какой-нибудь Scheme прост — то, значит, С++ было сложно сделать, а Scheme просто? Как бы не так: забить костылей, а потом подпереть их ещё одним рядом костылей и так — 100500 уровней костылей… это как раз просто. Сложно — сделать всё то же самое не множа сущностей без необходимости.

C++ захватил рынок именно потому что он был крив и ужасен. Звучит парадоксально — но факт. Потому что пока остальные всякие Haskell'и и Scheme разрабатывали грамотную архитектуру — создатели C++-компиляторов зарабатывали деньги. Ибо у них уже был продукт, который можно было продать.

Лисп умер
Лисп как раз не умер. А вполне себе активно используются. Людьми, которые понимают что делают. К сожалению таких в современной IT-индустрии немного — это да.

а то что не умерло — преобразовалось в тот самый аналог С++.
Если вы про десятое правило — то да, разумеется. Иначе и быть не могло. Желание сделать нормальное метапрограммирования привело сначала к лиспу (программирование variadic templates — это как раз типичный Lisp и есть), а теперь там появляются аналоги CLOS (концепты — это как раз об этом) и прочее.

История лиспа? Это контр-пример.
Отнюдь. Тот факт, что каждые лет 10-15 кто-то изобретает Лисп в очередной раз (вот и C++ в верссии C++11 до него добрался, а в версии C++20 у нас уже почти что CLOS, то есть не просто LISP 60х, а «продвинутый» LISP 80х) — скорее говорит о том, что подход Лиспа — это и есть окончательная точка. Просто огромное количество неквалифицированных людей, занятых в индустрии, не позволяет это «колесо переизобретения Лиспа» остановить.

И именно компилятор(llvm) и прочий рантайм позволил расту существовать.
А как же все десятки и сотни языков, созданных до rust'а? И даже до LLVM? И даже до C++?

Достоинства C++ тут очень сомнительны. И даже LLVM не очень-то нужен: до этого просто языки прикручивали к GCC (который был написан на C, не на C++), вот и вся разница.
Не было там изначально нифига. Изначально шаблоны вообще планировались как параматризованные типы в Extended Pascal, но кому-то пришла в голову светлая мысль со специализациями шаблонов.

Как это не было, если было. Там было всё. И вы это подтвердили.

После чего оказалось, что, во-первых, эффективно реализовать шаблоны после этого затруднительно с одной стороны, а с другой — было выяснено, что они — полны по Тьюрингу (а да — известно кто и когда это сделал).

Это то, о чём я и сказал. Выяснили, что они пригодны для вычислений. Но кодогенерация и всё их устройство оных было изначально.

Ну а дальше — начали вокруг этого надстраивать многоэтажные уровни костылей.

А ну именно поэтому в расте теперь пастят constexpr и const generics. А так да, ни на чём не обоснованные громкие заявления.

Принципиально ужасней лиспа оно тем, что у вас два разных языка. А не один, как во всех системах с приличным метапрограмированием сделано.

У вас явные проблемы с восприятием. Именно в лиспе, расте и прочих сделано два отдельных языка. В С++ язык один. Так было всегда.

Но ничего и не помогает. Стандартного способа нет.

Покажите мне стандарт раста. Я посмотрю на него. А так же покажите мне там стандарт на расширения.

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

Это так смешно читать в контексте раста. Который существует в рамках llvm-экосистемы и является таким clang-ом на минималках.

Когда это появился в C++? В C++40? Или в C++80?

Это уже есть. А у лиспа ничего нет. И ничего не было. Это всё враньё и инсинуации, а вы ничего не покажете. А что покажете, если покажете, это детский садик в современных реалиях.

А в LISP — это всё было в 60е.

Ничего в леспе и никогда не было. Зачем вы врёте? Никакого аналога описанных в статье фичей не было и нет. А то, что там было — это уровень чуть выше препроцессора в си. Всё это не обладало и не обладает ничем, чем обладают реализации того же на С++. Это не является ни статическим, ни компилируемым, ни имеет никаких средств статического анализа уровня того же libclang/gcc. Не имеет ничего даже близко равного libclang.

В rust — это можно сделать сегодня (хотя diesel появился чуть раньше и, увы, основан на кодогенерации.

Точно так же это можно сделать и clang.

Вы пропустили самый главный вопрос: а зачем нам вообще метаязык. Зачем нам все это costexpr и прочая муть? Почему мы не можем просто разрешить обычному коду на C++ работать во время компиляции?

Неверно. Во-первых constexpr это и есть возможность работать во время компиляции. И ничего этого нигде(в полной мере) нет.

К тому же, вы в очередной раз проигнорировали неудобные вопросы.

Э… вас часом с детстве не роняли? Идти туда, где проще — это как раз девиз Unix, C и C++. Про это даже статью известную написали.

Полная чушь. Юникс куда более сложный, чем всё существующие тогда/сейчас. Это авангард развития ОС и технологий. Просто — это всякий треш 90х уровня бейсика, паскаля и прочего.

Или вы исходите из того, что C++ сложен, а какой-нибудь Scheme прост — то, значит, С++ было сложно сделать, а Scheme просто?

Это очевидно.

Как бы не так: забить костылей, а потом подпереть их ещё одним рядом костылей и так — 100500 уровней костылей… это как раз просто. Сложно — сделать всё то же самое не множа сущностей без необходимости.

Именно таким образом и развивался раст. В С++ никто и никогда не добавлял никаких костылей.

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

C++ захватил рынок именно потому что он был крив и ужасен.

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

Звучит парадоксально — но факт.

Ну когда тебе нужно оправдать неудачи того, чьим адептом являешься — кидаться подобным очень удобно.

Потому что пока остальные всякие Haskell'и и Scheme разрабатывали грамотную архитектуру

И, где эти языки? Где их архитектура? Где софт на них? Я отвечу — лишь в фантазиях их адептов. Так было, так есть и так будет. Этой истории уже 50 лет. И пластинка не меняется.

— создатели C++-компиляторов зарабатывали деньги. Ибо у них уже был продукт, который можно было продать.

Опять же — полная чушь. Кто создавал gcc? Столман на коленке. Тот же llvm — академический проект. Но всё это было состоятельным, всё это работало. Во всё это потянулись люди и инвестиции.

К тому же, все эти компиляторы маргинальные — это попросту уровень нулевых годов. Они не являются даже конкурентами актуальных С/С++ компиляторов.

Лисп как раз не умер.

Умер. Это факт. Вы просто врёте и подменяете понятия. Лисп умер, развалившись на тонны маргинальных диалектов. Потом эти диалекты пытались собрать — родился тот же cl. Но всё это 90е годы.

Тут можно заметить типичную схему манипуляции, которую использую адепты лиспа. Они называют лисп, но в одном контексте — это убогий лисп из 60-70х, который любой студент писал на коленке. Да и так он и родился. А в другом лисп современный, т.е. всякие там cl/scheme. Причём не те старые его редакции, из 80/90, а именно актуальные.

Если адепт пытается говорить про лисп из 60х — он должен говорить именно про тот лисп.

А вполне себе активно используются. Людьми, которые понимают что делают. К сожалению таких в современной IT-индустрии немного — это да.

Никто не использует лисп из 60х. Это очередная попытка врать. Как и никто не использует си с классами из 70/80х.

По поводу того, что кто-то использует — очевидно, что маргинальщину используют. Но это никого не интересует. Все должно интересовать — где плоды этого использования? Но их не видно, на фоне всего остального — это пыль.

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

Нет. Я про обрастание костылями и усложнение.

Желание сделать нормальное метапрограммирования привело сначала к лиспу

Нигде и никогда оно к нему не приводило.

(программирование variadic templates — это как раз типичный Lisp и есть)

Полная ахинея. variadic существовал в си и С++ для макросов/параметров функции десятки лет. variadic — это просто продолжение этой идеи.

а теперь там появляются аналоги CLOS (концепты — это как раз об этом) и прочее.

Опять же глупое враньё. Это ахинея уровня «колёса в современном автомобиле — это аналоги колёс из телеги. Было же в теле — взяли из телеге». Это манипуляции, когда манипулятор пытается сравнивать слова, но не то, что за ними стоит. Тоже самое было с лиспом.

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

Отнюдь. Тот факт, что каждые лет 10-15 кто-то изобретает Лисп в очередной раз

Опять же полная и нелепая чушь. Это примерно так же как говорить, что кто-то каждый раз изобретает автомобиль. Ещё раз повторю — никакой лисп ничего не может и никому и никогда интересен не был. А тот факт, что там появились и использовались какие подходы — обусловлено лишь тем, что никаких требования к лиспу не предъявляется. Именно поэтому в него можно тащить любое дерьмо.

В С++ же совершенно другие критерии, когда как в лиспе критерий один «лишь бы как-то работало». Такой же критерий существует и для раста. Один.

(вот и C++ в верссии C++11 до него добрался, а в версии C++20 у нас уже почти что CLOS, то есть не просто LISP 60х, а «продвинутый» LISP 80х)

О боже, какая же нелепая чушь. Ещё раз повторю. Само наличие какой-то кодогенерации(в ситуации с лиспом — генерации текста) и предкомпиляции(т.е. интерпретации кусков какой-то примитивной скриптухи, которой является лисп) — ничего не стоит. Такую херню писали и пишут студенты на лабах.

Особенно это было модно в 60-70. Всякие m4 и прочее сишной наследение. Да сам С++ тем же самым в начале своего становления языком.

Поэтому я ещё раз повторю. Сам факт наличия чего-то никому не интересен. С++ нигде и никогда не занимался реализаций этой примитивной херни. Он занимался КАЧЕСТВЕННОЙ реализаций этой примитивной херни и она уже не была примитивной.

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

Нет, именно лисп и его изобретали и говорители о нём — неквалифицированные люди. Именно поэтому они и существуют так, где существуют.

Целые специальные учреждения заняты теми, кто уже всё изобрёл и знает как лучше. Там, в мягкой палате, каждый расскажет про заговор, про некомпетентность все вокруг. Как они его гениальные творения — выкидывали.

А как же все десятки и сотни языков, созданных до rust'а? И даже до LLVM? И даже до C++?

Ну дак в этом их и проблема. Они были созданы, но никогда не могли составить никакую конкуренцию. Потому что никто из них не мог написать компилятор, особенно на рождённом ими языке.

Достоинства C++ тут очень сомнительны.

Достоинства С++ тут прямые. Именно эта инфраструктура позволила очередному посредственному языку пиариться как «быстрый язык». До llvm«а — это был бы очередной пхп. Хотя он им и был.

И даже LLVM не очень-то нужен: до этого просто языки прикручивали к GCC (который был написан на C, не на C++), вот и вся разница.

Неверно. Никакие языки не прикручивали к гцц, вернее не прикручивали массово. Зачастую они просто транслировались в си.

Но именно llvm был создан как платформа для создания подобных языков. Сделать тоже самое на гцц — куда сложнее. А как я уже говорил — все эти языки(в том числе и раст) существуют лишь на эксплуатации простых решений.

И появляются они тогда — когда прогресс позволяет простым и убогим решениям — быть эффективными. Вернее минимально эффективными. И вот llvm — это то самое. До llvm»а просто решение не было эффективно. Именно поэтому никакой раст и не мог бы существовать, как он и не существовал. Вернее он существовал, но в другом виде. И довольно долго. Правда никто реализовать его не мог.

А потом пришлось срочно всё менять и делать на llvm. По-сути создавая язык заново. Хотя это не язык, а набор никак не связанных друг с другом костылей/простых решений.
Я тут опять начал распылятся. Хотя для опровержения всех эти рассуждений достаточно вопрос — «почему в раст пастят constexpr и const generics»? Зачем это нужно, если уже язык — метаязык.

А ответ тут прост. Те, кто создают и добавляют это в раст — знают реальное положение дел. А эксперты в комментах — лишь эксперты в комментах, которые очень часто врут/выдают желаемое за действительное.

И вот такой вот у нас(них) метаязык. На словах. А в реальности — отдельный ужасный язык макросов, а так же расширения компилятора.
Аналогично можно заметить, что гадить адепты раста могут, а отвечать нет. Они приходят в тему про С++ и загаживают их своим «языком», который никому не интересен и ненужен. Так же прибегают в темы про С++ и минусуют всех, кому не интересен их объект обожания.

Ну в целом это очень хорошо. Чем больше таких набегов анонимных загаживателей будет — тем больше наблюдатель со стороны будет знать. Знать кто они и что они.
Нет, именно лисп и его изобретали и говорители о нём — неквалифицированные люди.

Это очень большая ошибка. Я бы даже сказал, самоубийственное невежество.
UFO just landed and posted this here
Template Haskell и хаскелевские же дженерики смотрят на все это с некоей иронией.

И какие же для этого есть основания?
UFO just landed and posted this here
Я так и не увидел ответа на вопрос. Возраст ни на что не виляет. Влияет наличие каких-то возможностей и практики их применения. К тому же «время компиляции» не является критерием вне контекста, т.к. везде компиляция разная и назначение разное. Компилтайм прежде всего нужен и верифицируется через отсутствие просачивания любой логики(компилтайм) в рантайм. В контексте хаскеля это вообще не имеет смысла т.к. он целиком и полностью рантайм-зависимый.

Да и вообще всё эти рассуждения не имеют смысла. Берёте любую фишку из статьи, берёте два варианта(на двух языках) и делаете адекватное сравнение. До тех пор все эти рассуждения имеют мало смысла.
UFO just landed and posted this here
Вы там «на уровне С++» и многопоточную версию сделали вашего хелворд-факториала? Или «вбросил и забыл»?



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

Никаких фичей нет и никакие фичи вообще ни на что не влияют. Влияет качество этих фичей их возможности, а методичка с лозунгами «а у моей талеге колёса были ещё 100лет назад — зачем вам новые колёса» — это нелепо и убого.

Во время компиляции можно порождать код. Можно порождать тела функций (а с метаклассами можно?). Можно читать файлы и даже, скажем, загрузить XML-схему по сети (не надо так делать, но можно) и по ней сгенерировать функции и структуры данных.

Этот код — говно. То, что вы там рассказываете — это свойство любой скриптухи. На этом можно заканчивать. Никому в С++ абсолютна неинтересна кодогенерация, которая генерирует говно.

И все это на том же самом языке. Если во время компиляции надо решить какую-то задачу, то можно взять любую имеющуюся библиотеку, и она будет работать просто во время компиляции.

В скриптухе нет компиляции — там есть «компиляция», но это неважно. Покажите мне как работает асист от ide.

Генерация машинного кода, например?

Нет. Опять попытка использовать методичку «у моей телеге тоже колесо». Генерация генерации рознь — определяющим является качество генерации. Генерация с тем качеством кода, который порождает хаскель-компилятор не ненужна никому, кроме его(хаскеля) адептов.

Я сейчас услышу очередные шаблонные лозунги «мы не виноваты» — виноваты. Маргинальность уже вина. К тому же, llvm существует десяток лет. Какие-то потуги в эту сторону даже идут, но они никуда не придут. Потому что лозунг — лишь оправдание.

А в рантайм ничего из TH и не просочится. А у хаскеля в рантайме и типов нет так-то (что иногда проблема, если вы начинаете писать завтипизированный код, но это другой разговор).

Производительность критерий «просочится». Производительности у вас нет, на этом можно закончить. По поводу заявлений про «не торчат» — там торчит rtti во все стороны.

Как и C++, начиная от CRT

Это что-то маздайское? Во-первых методичка потекла, т.к. С++ может работать вообще без рантайм-зависимостей. Исключения, dynamic_cast, статические инициализаторы в функциях. Но всё это неважно, а определяющим является то, что он может(и множество кода так и написано) существовать без, а скриптуха не может.

и заканчивая поддержкой мьютексов, тредов и всего такого от ОС. Просто в хаскеле ещё GC есть и шедулер тредов свой.

Полная чушь. stdlib не является рантайм-зависимостью. Фундаментальным отличием С/С++ от скриптухи является то, что на С/С++ можно написать любую функционал из stdlib. Именно поэтому адепты скриптухи часто называют stdlib зависимостью, ведь их скриптуха без неё превращается в тыкву.

Есть enum class Src. Надо сгенерировать enum class Dst, у которого некоторые значения пропущены, и функции Src -> optional, Dst -> Src с очевидной семантикой. А, ну и определить для Dst передаваемый пользователем набор тайплкассов метаклассов. Печать там, не знаю, хеширование, все такое.

Это не определение задачи, а какая-то херня.
Dst передаваемый пользователем набор тайплкассов метаклассов.

С чего вдруг задача стала зависеть от понятий какой-то там скриптухи?

У меня код на хаскеле есть. С вас код на плюсах, потом сравним.

Мы уже сравнивали, а я вас поймал на вранье. Вы там многопоточную версию своего «факториала» напишите, но об этом я уже говорил выше.

UFO just landed and posted this here
У вас какие-то конкретные претензии есть, или это так, шаблонная отмазка, чтобы отписаться?

Есть — бенчмарки и положение хаскеля.

А по существу будет? Я не ожидал, что дискуссия скатится в «$otherlang — говно просто потому, что говно».

Опять лозунги уровня начальной школы. Я уже определил основной критерий. Говно а) потому что нет производительности. б) потому что нет свидетельств написания чего-то уровня С/С++-софта на скриптухе. Вы должны доказывать состоятельность своей скриптухи, а не я.

Хаскель — не скриптуха. Это компилируемый язык (хоть у мажорной реализации и есть repl, кстати, как там с repl у мажорных реализаций C++?). Непонятно, зачем вы сравниваете со скриптухой.

Хаскель — это скриптуха. Если в скриптуха добавить компиляцию(а она есть везде, пусть и рантайм, но никакой нет проблемы прикрутить aot), то она не перестанет быть скриптухой. Скриптуха — это всё, что является рантам-зависимым.

По поводу repl — с чего вдруг он у С++ должен быть и зачем он вообще нужен? repl — это и есть скриптуха. Я вот не понимаю — почему адепты постоянно берут какие-то базворды из своего фентезийного мира и начинают требовать их от других? С чего вдруг меня вообще должно это волновать?

Не понял, чем вас не устраивает?

Когда из «собираться в один файлик» стало что-то следовать? Критерий — нулевые рантайм-зависимости. Зависимости без проблем можно заинжектить в бинарник. Туда хоть что можно заинжектить. Показывайте дамп дизассемлера.

А чем вам код не нравится?

Тем же, чем код любой скриптухи — отсутствие производительности и предсказуемости.
На 95% моих задач работает шустро, шустрее… э, а нет аналогов. Но шустрее того, что люди там на питонах пишут. А разница с плюсами на задачах парсинга текста, или кодогенерации, или чего ещё, несущественна, а вот время разработки отличается на порядок.

«моя скриптуха быстрее пистончика» — это ничего не значит. Любая скриптуха быстрее пистона.

По поводу «разницы» — вы её уже показывали на факториале. Вы так же там кричали «меньше кода, проще», но потому кричать перестали.

Я не видел ни одного используемого парсера на хаскеле. Где же все эти парсеры?

По поводу «проще» — говно писать всегда проще. К скриптухе никто и никогда не предъявляет никаких требований за исключением «хотя-бы работает». Сравнивать это с С/С++-реализациями верх идиотии. Там совершенно другие критерии и другие условия.

А можете озвучить голоса, с которыми вы тут говорите?

Когда ответить нечего — займёмся клоунадой.

Можно любой факториал в компилтайме посчитать (правда, собираться будет долго, дольше плюсов). В рантайме будет за миллисекунду любая задача решаться. Чем не удовлетворение вашего критерия?

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

Ещё раз, сообщаю вам новость. Критерий «работает» существует только в мире вашей скриптухи. В мире другом — критерий «работает» находится даже не на первом месте.

Ахинея про «миллисекунды» — это вообще смех. Какие ещё миллисекунды, что это за клоунада?

И динамическое выделение памяти. Потому что ой, куча. Ой, управление памятью. Ой, защищённый режим. Ой, ОС нужно.

Опять потоки шизофрении. Никакая динамическая память ненужна, а если нужна — она написана руками. Это не является рантайм-засисимостью и обязанностью. Это может быть, а может не быть.

Методичка про ОС так же смешна. Как минимум ОС находится за рамками контекста т.к. является базой для запуска любой программы. Использовать её можно безо всяких проблем. К том уже, ОС — это сишный рантайм. Это такой же си-код как и любой другой. Это такое же фундаментальное отличии скриптухи — она внешняя, она чуждая.

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

Слив засчитан. На этих крестах написана половина софта. К тому же, тут можно видеть как адепт, сев в лужу, начинает отрицать и кидаться лозунгами.

А можно и на хаскеле написать кодогенератор, который будет эмитить ассемблерный код (его немного надо, в ghc rts не так много кода на сях), будет полный аналог. Устроит вас?

Когда напишите — приходите. К тому же, это равно расписки «на моей скриптухе писать код нельзя — нужен другой язык».

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

Сложно, что ли? Решать не будем?

Сложно? Решать многопоточную версию не будем? С чего вдруг вы решили, что можете ставить какие-то нелепые условия, а после требовать их исполнения?

Давайте поиграем:

[code=c]
templatestruct Foo
{
template struct value
{
friend bool operator>(bool, value) { return false; }
};
};

template<>
struct Foo{
static constexpr auto value = 10;
};

constexpr bool someComputation() { return true; }
constexpr bool otherComputation() { return false; }

int main()
{
Foo<someComputation()>::value < 10 > var;
{
Foo<otherComputation()>::value < 10 > var;
}
}
[/code]

Такой же код, только на хаскеле, в студию. У нас код уже есть, вот и посмотрим на эти супер-решения и интернет в компилтайме.

Метакласс — понятие из скриптухи? Ну ок.

Опять враньё. Там был не только метакласс.

Мне надоела бессмысленность того спора, сорьки.

Нет, просто несмоглось.
Про оверхед по памяти я уже написал. Вы что, прувер, что вам терм обязательно предоставь?

Я уже на это отвечал — как угодно. Хотя это будет не зачёт, но хоть что-то.

Спасибо за публикацию!
Толково и грамотно.
Очень хорошо оформлена статья.
Ценю высокий профессиональный уровень.

А как же Qt с его moc? Можно обходить все сигналы слоты и property. Но нужно писать setter/getter для всех property, что немного не хочется когда они тривиальные, но наверное можно повесить это дело на макрос.

Qt с его moc заточены под конкретные кейсы. Ну и требуют, собственно, Qt и его инфраструктуры. Средство хорошее, работающее, но, на мой взгляд, нишевое. Можно, конечно, было упомянуть в разделе про генерацию кода, но не хотелось сильно объём раздувать.
Приятно обнаружить, что иногда совпадаешь мыслями с умными людьми. Давно топлю за редактирование AST в С++ на этапе компиляции. Причём тоже считаю что императивный стиль лучше функционального. В этом комментарии описал нечто похожее на предложение по метаклассам.

Надеюсь, плюсы будут двигаться от функционального ада шаблонов к какому-нибудь императивно-объектному генератору кода на этапе компиляции под поставляемые вместе с плюсовыми библиотеками DSL.

Главное чтобы всё это умели красиво прожёвывать парсеры IDE. На текущем проекте частенько избегаю использования шаблонов из-за изрыгаемых Студией длинющих типов в подсказках IDE по специализациям (например, при использовании в качестве аргумента шаблонного метода decltype-типа по полю шаблонного аргумента — вываливает «decltype(bla-bla-bla)» вместо раскрываемого типа). Я уж не говорю о жутких сообщений об ошибках при неправильных подстановках типов. Мне-то не тяжело читать эти простыни, я люблю метапрограммирование за его семантическую точность. Но люди, не привыкшие к подобным чудесам, будут страдать.

Ну вот, собственно, в субботу на C++ Russia буду рассказывать об одном из решений, которое и парсеры IDE смогут прожевать (просто потому, что всё в итоге в явный исходный текст превращается). Сами метаклассы (на уровне компилятора) — сильно сочувствую тем, кто будет это реализовывать.

Причём тоже считаю что императивный стиль лучше функционального.
Императивный стиль не лучше и не хуже функционального. Он просто другой. Вообще же хочется для программирования и метапрограммирования использовать один язык. Потому в C++, так как основной язык императивен, метапрограммирование тоже хочется иметь императивное…
Лично я не вижу в шаблонах функционального ада. А при желании и должной смекалке, сделать ад можно с помощью любого инструмента.
В последнем примере/блоке написано «switch (value) {», думаю это не верно. Правильно наверное так: «switch (e) {».

Да, полагаю, правильнее так. Но это цитата из оригинального документа. :)

Рад, что С++ активно развивается и дает пищу для размышлений, экспериментов и творчества. Страдания были лет 15 назад :) Тогда мы, в ЛК, использовали STLport вместо GNU'шной STL из-за нестабильности последней, а clang'а еще вообще не было, а о метапрограммировании, вообще, начали говорить в 2005-2010, если не ошибаюсь, после статьи Бартлетта.
UFO just landed and posted this here
неразрешима

В чём именно? Да и кого вообще должны волновать эли религиозные критерии?
UFO just landed and posted this here
Второй var — это заshadowенное имя или кусок сравнения?

Это было так очевидно. Дефолтная методичка с typename и я хотел о ней написать, но это не пример неразрешимости — он разрешим и он собирается. Это решается приоритетами. Я уж думал, что не увижу подобной глупости и писать о ней не стал.

В первую очередь разработчиков компиляторов, тулинга и тому подобного, что должно уметь разбирать C++-код. А за ними — тех, кто этим всем пользуется (то есть, всех разработчиков на C++).

Разработчики не жалуются. Тулинг никому ненужен — эта методичка давно устарела, т.к. уже давно существует тот же libclang, который предоставляет всю необходимую информацию.

К тому же, этой методичкой вы умножаете на ноль смысл того же хаскеля. Потому что его сложно оптимизировать, сложно на нём писать и прочее. Так можно сказать про любую скриптуху, где 95% сложности — борьба с самой природой скриптухи.

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

UFO just landed and posted this here
Нет, там ни слова о тайпнейме, и оно там не нужно.

Именно о нём. Суть методички в том, что в структуре тип и значение и T::value — может быть типом/значением. Пример построен на базе этой методички.

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

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

По поводу этих функция — их ненужно вычислять. Да и компилятор их умеет вычислять.

Приоритетами чего и отчего ж до сих пор не решено?

Как же не решено, если решено. Код собирается — значит решено. В противном случае он бы не собирался.

К тому же, выше уже поднималась тема ide. Очевидно, что С++ — это не хаскель на котором можно писать только в блокноте. Компилятор всё знает — ide всё знает.

И нужен интерпретатор в компиляторе, чтобы код собрать

У вас опять методичка течёт. Вы же в интернете в компилтайме ходите, а тут вдруг нужен.
Адовая грамматика — одна из причин, почему плюсы собираются меееедленно

Полная и нелепая чушь. Кресты собираются куда быстрее всякой скриптухи. Тут методичка пытается сравнивать несравнимое.
И рефакторить их меееедленно.

Религиозные критерии меня волнуют мало.

И нормальные IDE для джавы или сишарпа были почти что изначально, а для плюсов стало что-то адекватное получаться, да, только после libclang

Опять шиза. Шарп — это на 90% кресты. Опять методичка маздайщика, который нихрена не знает. В том же kdevelop ещё более 10 лет назад была поддержка крестов на уровне(в чём-то даже выше) сегодняшнего libclang.

Компилятор Haskell 2010 (и 2020) написать сильно проще, чем компилятор плюсов.

Примитивная скриптуха с примитивных компилятором. Очередное сравнение несравнимых вещей.

Да и плюсы, тащем, тоже сложно оптимизировать.

Полная чушь.
Пришлось бабло вливать лет 20 или 30, чтобы компиляторы что-то там смогли начать делать. И почти все из компиляторов сдохли в процессе.

Методичка про 20лет. О боже, насколько это нелепо. Сообщаю новость — шланг был запилен за пару лет, а всякую скриптуху он ломал об колено ещё с момента появления.

Разрешимость или неразрешимость — это, извините, не религиозное понятие, а вполне себе математическое.

Достаточно фундаментальные: так, например, некоторые виды подсветки для C++ нельзя в принципе сделать так, чтобы они работали корректно для любой правильной программы.

Пустячок — а неприятно. Так-то, если вы программу на бумажке пишите и на перфокартах вводите — то вам всё равно. А вот уже для более продвинутых иструментов — это проблема…
Разрешимость или неразрешимость — это, извините, не религиозное понятие, а вполне себе математическое.

Религиозное. Попытка приписать судя какое-то «математическое» — полная чушь, глупая попытка манипулировать и врать. Очевидно, что неразрешимой грамматика быть не может, а под «неразрешимостью» срыватели покровов имеют ввиду совершенно другое.

Достаточно фундаментальные: так, например, некоторые виды подсветки для C++ нельзя в принципе сделать так, чтобы они работали корректно для любой правильной программы.

Я для начала вам советую не для С++ сделать подсветку хотя-бы на уровне С++, а там далее чём-то рассказывать.

К тому же, на чём основаны эти заявления — мне непонятны. Если компилятор может собрать программу, то грамматика по определению разрешима. А любая корректная программа должна собираться. С++ — это не скриптуха, где компилятор может чего-то не знать(да и в подавляющем большинстве случаев действительно не знает). Это не работает даже на уровне типов.

Если методичка такого же уровня качества «как выше», то я могу предположить — о чём именно идёт речь, если она вообще о чём-то идёт. Это шаблоны. Это единственное место, где этот «фундаментальный» недостаток может проявиться. Но, проблема только в одном — других шаблонов в природе не существует. Либо примитивные генерики с аннотированием типов, либо все те же проблемы.

Хотя даже тут можно сделать подсветку и асист. Подобные механизмы есть в любой скриптухе.
UFO just landed and posted this here
Sign up to leave a comment.