Здравствуйте, Amras S. Singollo, Вы писали:
R>>А для него почти весь С++ — это трюк. Как для дикаря зажигалка.
ASS>В интернете кто-то неправ? Пора доставать х. и заливать всех спермой. ASS>"У тебя сперма стекает по твоим пухлым щёчкам." (с) rg45
Не понял я, что ты хочешь мне предъявить. Я себе позволил больше, чем позволяют себе другие или что?
--
Справедливость выше закона. А человечность выше справедливости.
Re[6]: The Big OOPs: Anatomy of a Thirty-five-year Mistake
Здравствуйте, Doom100500, Вы писали:
D>Там кто-то сказал, что в плюсах не проектировалось закрытое наследование. Мне возразили, что то, что я привёл — это приватное. А что такое приватное?
Речь шла о закрытых иерархиях.
Это когда у вас есть несколько конкретных типов (например, ConstantExpression, BinaryExpression, UnaryExpression), и есть некоторый общий тип, к которому они все приводимы.
И у вас есть гарантия того, что если вы видите экземпляр общего типа, он является экземпляром одного из этих типов и ничем больше (поэтому у нас есть возможность выполнять exhaustiveness checking).
В ФП это обычно моделируется алгебраическим типом, когда вы пишете type Expression = ConstantExpression | BinaryExpression | UnaryExpression;.
В ООП довольно сложно изобразить такую штуку, потому что в нём мы обычно вот эту приводимость обеспечиваем при помощи наследования конкретных типов от абстрактного базового.
И вот тут и возникает некоторая проблема — как запретить порождать других наследников от Expression? В каком-нибудь дотнете это достигается package visibility для Expression.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, so5team, Вы писали:
S>Выглядит так, что люди попытались воплотить мечты г.Мызыченко в жизнь и попробовали таки скрестить макросы с компайл-тайм рефлексией. Но уперлись в непреодолимые в их условиях сложности. После чего решили свернуть попытки.
Выглядит так, что в их проекте были определённые требования, которым противоречила такая реализация макросов, которую они пытались получить.
Конкретнее — инкрементальная компиляция и hot reload. Я подозреваю, что потребности вашего оппонента с этими требованиями никак не пересекаются.
Как, впрочем, и потребности примерно всех, кто пишет на С++. Я вот в прошлом году троллил нашу команду вопросом про то, какое время сборки большого проекта команда Хейльсберга сочла неприемлемым настолько, что для ускорения решила портировать компилятор на другой язык и платформу. Команда, естественно, матёрых плюсовиков.
Результат опроса был вполне предсказуем — не угадал никто. Ну нет в этом комьюнити людей с потребностью "сборка проекта за секунды". Все, кто такое хотел, давно ушли в более комфортные места.
В общем, compiler costs, ассоциированные с "семантическими макросами", или там "императивными шаблонами", вряд ли напугают целевую аудиторию плюсов.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[28]: The Big OOPs: Anatomy of a Thirty-five-year Mistake
Здравствуйте, so5team, Вы писали:
S>Шаблоны не дали радикальных улучшений?
Радикальные улучшения они дали на основном своем применении (для подстановки конкретных типов/значений в абстрактную заготовку). То, что трюковые варианты применения дали возможность еще немного повысить гибкость, я не готов считать радикальными улучшениями. Хотя бы потому, что каждое незначительное повышение гибкости достигалось все более сложными и запутанными комбинациями трюков, а разработчики языка не торопились переносить в язык хотя бы самое основное, вроде условной генерации по is_*/has_.
S>variadic templates не дали радикальных улучшений в сравнении с обычными шаблонами?
Это ж, по сути, чисто количественное улучшение — вместо пачки подстановок стало можно написать одну со списком.
S>constexpr/consteval не дал радикальных улучшений?
А это сюда каким боком? Не вижу в них ничего трюкового.
S>Может это из-за того, что вы занимаетесь задачами, для которых нужно что-то не сильно выше ассемблера?
В моих задачах найдется немало мест, куда можно было бы вставить шаблонные конструкции из std. И я даже несколько раз пробовал это делать. Но, как уже говорил, все упирается в то, что они реализованы средствами языка, но не имеют возможности избавить меня от знакомства с особенностями своей внутренней реализации. Будь они сделаны так, чтоб либо работать, либо выдавать, как компилятор, информативное сообщение об ошибке разумного объема, не требующее копания в кишках, то я б, наверное, это как-то пережил.
S>новые фичи снижают стоимость реализации тех или иных задач.
Они снижают ее, когда затраты на знакомство с фичами компенсируются выгодами от их использования. Большинство программистов, использующих C++, как я уже подчеркивал, лишь в общих чертах понимает, как работают шаблонные конструкции, активно использующие SFINAE, рекурсию, особенности частных случаев и прочее. Эти люди сами не смогли бы написать подобные реализации без серьезных затрат на изучение этих механизмов, а то и вообще. Пока им удается на этом уровне понимания более-менее интуитивно вставлять свои параметры в кем-то подготовленные примеры, их работа ускоряется. Когда они упираются в то, что при введении новых типов, или коррекции имеющихся, давным-давно обкатанные фрагменты кода вдруг разваливаются совершенно непонятным для них образом, они предсказуемо впадают в ступор. А дальше все определяется тем, насколько быстро получится угадать, почему так получилось.
Если уж довольно серьезные и опытные люди периодически заявляют об отказе от использования трюковых методов, а то и о возврате к чистому C, то проблема явно существует не только в уме отдельно взятого музыченко.
S>в групповой разработке приходится следить за тем, чтобы сложность применяемых элементов языка соответствовала способностям самых слабых участников группы. И чем больше группа, тем внимательнее за этим нужно следить.
Так вся-то беда в том, что на первый взгляд эти элементы вовсе не выглядят сложными — вроде бы понятные имена, список параметров в угловых скобках, подставляй да пользуйся. Он раз подставил — получилось, два — снова получилось, а на третий раз он получает несколько сотен сообщений об ошибках, 95% которых указывают на какие-то служебные файлы, и содержат какие-то исходники, которых у него нет. Подобные впечатления, наверное, были бы от какого-нибудь телевизора на Android, который вместо сообщений "нет сигнала", "источник данных недоступен" и т.п., вываливал бы на экран выдачу logcat.
S>Само употребление термина "трюк" выглядит неоднозначным. Непонятно что вы под этим понимаете.
Ровно то же самое, что и другие специалисты — использование побочных эффектов от средств, изначально предназначенных для других целей. По сути это то же самое, что арифметические/логические трюки в машинном коде, передача управления "внутрь команды", самомодификация кода и подобное.
S>Например, есть способы, которые позволяют обратиться к приватному члену класса не будучи другом этого класса. S>Как по мне, это трюк -- нечто уникальное и лежащее на грани разумности/дозволенности.
По мне, такие трюки лежат за границей и разумности (потому, что они чрезмерно сложны и непрозрачны), и дозволенности (потому, что позволяют делать нежелательные/опасные вещи, которые трудно обнаружить даже целенаправленным поиском). Куда правильнее были бы встроенные языковые средства, вроде "принудительного" приведения типов в стиле C, на которые компилятор мог бы по умолчанию выдавать предупреждения. Тогда и нужный результат бы достигался, если уж иначе невмоготу, и по настройкам предупреждений сразу было бы видно — использует программа подобное жульничество, или она "честная".
S>мне почему-то кажется, что вы что-то гораздо более простое называете трюками.
Суть трюка не меняется от уровня его сложности. Какая разница, достигает фокусник нужного эффекта простым зеркалом или навороченной электронной системой? Суть в том, что он вроде бы честно и открыто показывает вам одно, а за спиной при этом делает совершенно другое. В развлекательных целях это работает отлично, но многие ли захотят нанять фокусника, чтоб он делал такими методами серьезные вещи?
Здравствуйте, Sinclair, Вы писали:
S>>Выглядит так, что люди попытались воплотить мечты г.Мызыченко в жизнь и попробовали таки скрестить макросы с компайл-тайм рефлексией. Но уперлись в непреодолимые в их условиях сложности. После чего решили свернуть попытки. S>Выглядит так, что в их проекте были определённые требования, которым противоречила такая реализация макросов, которую они пытались получить.
В любом проекте будут какие-то ограничения.
Взять тот же C++. Он изначально развивался как язык, который допускает множество независимых реализаций.
Одной из таких реализаций была реализация GCC (которая сейчас является одной из ведущих и наиболее значимых).
В GCC, емнип, каждая стадия обработки исходников выполняется отдельным процессом. Т.е. сперва запускается отдельный препроцессор, который разбирается с макросами, затем компилятор, затем оптимизатор и т.д.
При этом GCC умудряется поддерживать целую пачку разных языков, задействуя общие компоненты компилятора.
Если бы в C++ попытались бы развить некие хитрые макросы, которые могут прыгать со стадии препроцессинга в стадию компиляции и обратно (и так произвольное количество раз), то это могло бы затруднить поддержку C++ в GCC, а без GCC-шного компилятора весь мир C++ был бы сейчас немного (или много) другим.
S>Я подозреваю, что потребности вашего оппонента с этими требованиями никак не пересекаются.
Я уверен в том, что оппоненту в C++ нужно в разы меньше чем среднему C++нику по больнице и на порядок меньше, чем лично мне. И на пару порядков меньше чем упоротым про производительности перцам из HFT или HPC.
Re[29]: The Big OOPs: Anatomy of a Thirty-five-year Mistake
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, so5team, Вы писали:
S>>Шаблоны не дали радикальных улучшений?
ЕМ>Радикальные улучшения они дали на основном своем применении (для подстановки конкретных типов/значений в абстрактную заготовку).
Так и запишем: дали.
S>>variadic templates не дали радикальных улучшений в сравнении с обычными шаблонами?
ЕМ>Это ж, по сути, чисто количественное улучшение — вместо пачки подстановок стало можно написать одну со списком.
Это тот случай, когда количество переходит в качество, потому что с variadic-шаблонами вы можете написать так:
А я и не про трюки, а про возможности C++, которые в нем появляются чтобы упростить решение стоящих перед разработчиками задач.
S>>Может это из-за того, что вы занимаетесь задачами, для которых нужно что-то не сильно выше ассемблера?
ЕМ>В моих задачах найдется немало мест, куда можно было бы вставить шаблонные конструкции из std.
Например?
S>>новые фичи снижают стоимость реализации тех или иных задач.
ЕМ>Они снижают ее, когда затраты на знакомство с фичами компенсируются выгодами от их использования.
Почему-то когда люди сталкиваются со сложными научными или инженерными проблемами, для которых нужно хорошее знание дифференциального исчисления и ТФКП, то никому в голову не приходится жаловаться на то, что это сложные в изучении дисциплины. И что даже когда прошедшие отбор экзаменами студенты далеко не все способы нормально в это дело вникать, к этому относятся нормально -- ну не всем дано и не у все хватает мозгов (у меня, например, не хватило).
А вот когда по мере роста сложности софта требуется применять более сложные инструменты, то здесь уже "ай-ай-ай", как-так, пачиму-так-сложна!
S>>в групповой разработке приходится следить за тем, чтобы сложность применяемых элементов языка соответствовала способностям самых слабых участников группы. И чем больше группа, тем внимательнее за этим нужно следить.
ЕМ>Так вся-то беда в том, что на первый взгляд эти элементы вовсе не выглядят сложными — вроде бы понятные имена, список параметров в угловых скобках, подставляй да пользуйся. Он раз подставил — получилось, два — снова получилось, а на третий раз он получает несколько сотен сообщений об ошибках, 95% которых указывают на какие-то служебные файлы, и содержат какие-то исходники, которых у него нет.
Сообщения об ошибках, при всей их безобразности в C++, далеко не самая большая проблема при использовании сложных элементов языка. Вот непонимание (или незнание) ADL может вести к гораздо более серьезным последствиям. Как и, например, непонимание сути undefined behavior некоторыми персонажами.
S>>Само употребление термина "трюк" выглядит неоднозначным. Непонятно что вы под этим понимаете.
ЕМ>Ровно то же самое, что и другие специалисты — использование побочных эффектов от средств, изначально предназначенных для других целей.
Блин, это выглядит как заход на очередной круг. Я уже пытался вытащить от вас примеры этих самых "побочных эффектов", но не преуспел. Вряд ли получится и в этот раз.
S>>мне почему-то кажется, что вы что-то гораздо более простое называете трюками.
ЕМ>Суть трюка не меняется от уровня его сложности. Какая разница, достигает фокусник нужного эффекта простым зеркалом или навороченной электронной системой? Суть в том
Что вашим оппонентам все еще непонятно что вы считаете трюком, а что нет.
Re[29]: The Big OOPs: Anatomy of a Thirty-five-year Mistake
Здравствуйте, Евгений Музыченко, Вы писали:
S>variadic templates не дали радикальных улучшений в сравнении с обычными шаблонами?
ЕМ>Это ж, по сути, чисто количественное улучшение — вместо пачки подстановок стало можно написать одну со списком.
Что, даже сравнение реализаций boost:: и std:: tuple не убеждает в качественности изменений?
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, Sinclair, Вы писали:
S>В общем, compiler costs, ассоциированные с "семантическими макросами", или там "императивными шаблонами", вряд ли напугают целевую аудиторию плюсов.
Тем более, что эти costs вовсе не ожидаются неизбежно высокими. Тело макроса обычно состоит либо преимущественно из текста с относительно редкими включениями операций, что обрабатывается довольно просто и быстро, либо преимущественно из метаязыка, и тогда возможна предварительная компиляция.
А уж при наличии прямого доступа ко всей информации, собранной компилятором, реализация многих конструкций, которые сейчас делаются на вложенно-рекурсивных шаблонах, будет достаточно тривиальной. Легко может получиться, что время компиляции даже уменьшится, в ряде случаев — сильно.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>А уж при наличии прямого доступа ко всей информации, собранной компилятором, реализация многих конструкций, которые сейчас делаются на вложенно-рекурсивных шаблонах, будет достаточно тривиальной.
Здравствуйте, so5team, Вы писали:
S>Если бы в C++ попытались бы развить некие хитрые макросы, которые могут прыгать со стадии препроцессинга в стадию компиляции и обратно
Вы, судя по всему, действительно не понимаете даже принципов предлагаемых идей, поэтому совершенно зря требуете примеров, которые Вам совершенно в этом понимании не помогут.
Перечисленные идеи вообще не предполагают препроцессинга, как сколько-нибудь отдельной стадии. Для сохранения совместимости препроцессор, разумеется, придется сохранять и тащить дальше. Но, если делать "умные" макросы, то исключительно внутри компилятора.
Если уж Ваше восприятие настолько прочно залипло на концепции плюсовых шаблонов, то попробуйте вместо "макрос" подставить "шаблон", затем допустить, что шаблон может содержать внутри себя синтаксически бессмысленные конструкции, которые примут осмысленный вид только после подстановки параметров (и не тривиальной, а, возможно, после их определенной обработки), и после этого представить, что внутри шаблона могут быть служебные конструкции метаязыка (желательно похожего на C/C++), на которых можно написать "подпрограмму времени компиляции", которая и обработает заданные параметры, породив код для компилятора.
S>Я уверен в том, что оппоненту в C++ нужно в разы меньше чем среднему C++нику по больнице и на порядок меньше, чем лично мне.
Если хоть среднему C++нику, хоть Вам, нужны хотя бы те убогие средства обобщенного программирования, что предоставляет std, то это как раз и для них, и для Вас. Даже если ни они, ни Вы не будете сами сочинять все эти "умные" макросы/шаблоны, их сочинят для всех вас так же, как в свое время сочинили Boost/std. Но сделают это в человеческом виде, относительно легко поддающемся пониманию, исправлению и доработке, и способным выдавать сообщения об ошибках/предупреждениях осмысленно, а не просто в виде вывернутых наружу потрохов std.
Здравствуйте, so5team, Вы писали:
S>В любом проекте будут какие-то ограничения.
Совершенно верно. И даже исходя из одних и тех же ограничений, разные команды могут прийти к существенно различным решениям.
S>Взять тот же C++. Он изначально развивался как язык, который допускает множество независимых реализаций.
Это в какой-то степени спорный тезис. В том смысле, что для его осмысленного обсуждения стоило бы уточнить, что такое "независимых реализаций".
Например — какая-нибудь Java тоже изначально развивалась как язык, который допускает множество независимых реализаций. При этом мы видим, что она подошла к этому вопросу совершенно по-другому, чем C++.
В частности, я примерно всегда могу взять компилятор java от вендора X, собрать при помощи него набор .сlass — файлов, которые зависят от пакетов, собранных вендором Y при помощи компилятора от вендора W, и запустить всё это на JVM от вендора Z. И если никто из участников, включая меня, не предпринял специальных усилий, то этот код заведётся и прекрасно заработает.
Вот тут видно — да, независимость реализаций имеет место. Все эти X, Y, W, и Z могут вообще ничего не знать друг о друге.
А что вы называете "независимостью реализаций" в C++?
Независимость от платформы, т.е. возможность получить бинарь для платформы Y путём запуска компилятора на произвольной платформе X? Совершенно точно эта возможность не ставилась во главу угла при разработке С++. Она и сейчас является малопопулярной экзотикой — для неё даже специальное название есть.
Возможность иметь несколько компиляторов С++ для одной и той же платформы? Ну, для начала хотелось бы простого — возможности подключить к проекту, собираемому компилятором X, библиотеку, собранную компилятором Y. Ах, вы не это имели в виду?
Ну, наверное, в виду имелась в виду независимость от компилятора — то есть возможность "взять и заменить" один компилятор на другой, хотя бы в пределах одной платформы, и если нам повезло иметь весь проект и все его зависимости в исходниках, то всё заработает? Но ведь чёрт возьми нет — прямо в стандарте у нас есть всякие implementation-defined специально для того, чтобы вендор мог ставить палки в колёса тем, кто пытается такую штуку сделать.
S>Одной из таких реализаций была реализация GCC (которая сейчас является одной из ведущих и наиболее значимых). S>В GCC, емнип, каждая стадия обработки исходников выполняется отдельным процессом. Т.е. сперва запускается отдельный препроцессор, который разбирается с макросами, затем компилятор, затем оптимизатор и т.д.
Простите, это какие-то детали реализации. Причём примерно все они определяются не столько великим замыслом создателей языка, сколько отсутствием в этом замысле нескольких важных деталей.
В частности — отсутствием поддержки модульности хоть в каком-то виде. Причем дело вовсе не в том, что С++ был создан слишком рано для того, чтобы было откуда черпать такие идеи.
Тот же самый Паскаль, к примеру, изначально строился не на костыльном механическом склеивании кусочков различных файлов для последующего использования, а на нормальных юнитах с секциями экспортов.
Что ОЧЕНЬ сильно упрощает сборку больших проектов — разбор библиотечного кода делается один раз, а потом компилятор пользуется готовыми метаданными. Авторы компиляторов С++ были вынуждены пердолиться с precompiled headers пару десятков лет перед тем, как в C++ попытались заретрофиттить модули.
Вот так буквально одно мелкое неудачное решение способно породить целое дерево всё менее удачных решений.
Примерно все остальные на этой поляне избежали этой "ошибки на миллион долларов".
S>При этом GCC умудряется поддерживать целую пачку разных языков, задействуя общие компоненты компилятора.
Это совершенно не является уникальным достижением в современном мире. Мультиплексирование фронтендов и бэкендов — хорошо известная практика, и она совершенно не требует тащить с собой богатый набор неудачных практик.
Например, та же джава (в широком смысле) тащит "целую пачку" разных языков, потому что бэкенд у неё работает с промежуточным представлением. Как, впрочем, делает и MSVC, и GCC, и примерно все остальные.
Я, конечно, очень уважаю проект GCC и его участников. Но всё же значительно более конструктивным является подход LLVM, когда стандарт IR открыт и публичен. От этого сильно выигрывают все участники процесса, а не только один отдельный компилятор отдельного языка.
S>Если бы в C++ попытались бы развить некие хитрые макросы, которые могут прыгать со стадии препроцессинга в стадию компиляции и обратно (и так произвольное количество раз), то это могло бы затруднить поддержку C++ в GCC, а без GCC-шного компилятора весь мир C++ был бы сейчас немного (или много) другим.
Совершенно непонятно, зачем бы нам потребовалось прыгать со стадии компиляции в стадию препроцессинга. Это не так уж часто требуется, даже от самых развесистых конструкций метапрограммирования. Это пока мы работаем на уровне "препроцессорных макросов", нам приходится пердолиться со всякими синтаксически чудовищными конструкциями вида BEGIN_MESSAGE_MAP(), которые просто сыплют в следующий этап конвеера произвольные лексемы.
Для метапрограммирования такого не нужно примерно никогда. Всё, что нужно — это порождать одни деревья на основе других деревьев. См. например LISP. В нём это невыносимо просто из-за отсутствия синтаксиса. Но ничто не мешает нам поехать по пути статически типизированного языка со статически типизированными AST. Тут трудности С++ скорее связаны с тем, что это слишком низкоуровневый язык. Поэтому простой гражданский код типа "давайте возьмём тело функции и заменим в нём все обращения к оператору +(X, X) на вызов функции parallel_add(X, X)" на плюсах превращается в трэш и угар, который ещё и при любом неловком движении прекрасно компилируется, но в рантайме приводит к разрыву селезёнки. Даже если удастся обойтись в этом коде без undefined behavior.
Но тут я полностью на стороне тех, кто владеет этим языком — пжалста, раз вы умеете писать работоспособный и надёжный код на нём, то, стало быть, вы напишете и работоспособный и надёжный "макрос" или там "императивный шаблон", который банально берёт и императивно хреначит по метаданным+AST, выплёвывая наружу готовые AST и пополняя метаданные. Делов-то. Вряд ли вам захочется в этом коде делать что-то вроде "а давайте запихаем в тело программы последовательность "><><". Вы скорее захотите делать там что-то типа "вот в этот scope пусть попадёт новая временная переменная. Имя ей сам придумай, если тебе надо — я к ней буду обращаться не по имени, а по ссылке на ResolvedName".
S>Я уверен в том, что оппоненту в C++ нужно в разы меньше чем среднему C++нику по больнице и на порядок меньше, чем лично мне. И на пару порядков меньше чем упоротым про производительности перцам из HFT или HPC.
Я не очень понимаю, какое отношение всё это имеет к перцам, упоротым по производительности.
Производительность рантайма более-менее ортогональна производительности компайл-тайма. Скорее наоборот: чем больше у нас требования к рантайм-перформансу, тем больше мы готовы пожертвовать компайл-таймом. Пусть лучше у меня будет специальный "плагин к компилятору", который будет для моего относительно высокоуровневого кода статически генерировать всю обвязку сериализации/десериализации. Пусть даже ему на это потребуется чуть больше времени. А все вот эти вот адские низкоуровневые оптимизации, за которые вы любите С++, примерно никакого отношения к шаблонам и макросам не имеют. Пусть компилятор выплёвывает LLVM IR, а всякими loop unroll-ами, constant propagation и прочим уже есть кому заняться.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Тем более, что эти costs вовсе не ожидаются неизбежно высокими.
Ну, мы-то можем только рассуждать. А парни в Dart потратили несколько лет на эксперименты. Если они видят, что компиляция выезжает дорогая — значит, для них так и есть.
Хотя С++ практически целенаправленно организован так, что в нём невозможно сделать эффективную компиляцию.
Я, конечно, не претендую на способность до конца моей жизни родить реализацию настоящего С++ компилятора, я про его трудности знаю скорее понаслышке. (Кстати, ваше упоминание про способность навелосипедить аналог Borland C++ 3.0, скорее продиктовано недостатком квалификации, чем её избытком. Даже ранние версии языка были заботливо спроектированы так, чтобы порог входа в комьюнити осиливших компилятор был запретительно высоким)
Но всякие SFINAE выглядят как неизбегаемые грабли, заложенные с самого начала.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Вы, судя по всему, действительно не понимаете даже принципов предлагаемых идей, поэтому совершенно зря требуете примеров, которые Вам совершенно в этом понимании не помогут.
Во-первых, я пока еще нигде не видел связно изложенных идей.
Вот пропозалы по рефлексии для С++ есть (как старые на базе шаблонов, так и новые, которые в итоге вошли в стандарт).
Описания разных типов макросов для Rust есть.
Да даже описание для прастихоспади Немерле есть.
А где ваши идеи сформулированы?
Нигде, полагаю.
ЕМ>Перечисленные идеи вообще не предполагают препроцессинга, как сколько-нибудь отдельной стадии.
Во-вторых, если вы говорите про макросы, которые выплевывают новый исходный код, то когда они этот код выплевывают, то опять должна быть повторена стадия обработки этого исходного кода. Т.е. какой-то предпроцессинг опять будет, потому что в новом исходном коде опять могут оказаться макросы, требующие раскрытия.
Если же у вас "макросы" -- это метапрограммы, которые не имеют ничего общего с доставшимся от Си препроцессором, то a) их именовать нужно иначе просто чтобы путаницы не было и b) они внезапно начинают смахивать на шаблоны, которые и есть исключительно внутри компилятора.
ЕМ>Если уж Ваше восприятие настолько прочно залипло на концепции плюсовых шаблонов, то попробуйте вместо "макрос" подставить "шаблон", затем допустить, что шаблон может содержать внутри себя синтаксически бессмысленные конструкции, которые примут осмысленный вид только после подстановки параметров (и не тривиальной, а, возможно, после их определенной обработки), и после этого представить, что внутри шаблона могут быть служебные конструкции метаязыка (желательно похожего на C/C++), на которых можно написать "подпрограмму времени компиляции", которая и обработает заданные параметры, породив код для компилятора.
Я не могу отделаться от впечатления, что вы тупо не знаете C++, т.к. в современном C++ внутри шаблона могут быть служебные конструкции метаязыка, очень похожего на С++, на которых и пишутся программы времени компиляции: if constexpr, constexpr/consteval, static_assert-ы.
S>>Я уверен в том, что оппоненту в C++ нужно в разы меньше чем среднему C++нику по больнице и на порядок меньше, чем лично мне.
ЕМ>Если хоть среднему C++нику, хоть Вам, нужны хотя бы те убогие средства обобщенного программирования, что предоставляет std, то это как раз и для них, и для Вас.
Смешались в кучу кони, люди...
Что такое предоставляет мне std?
Что вообще вы понимаете под std? Стандартную библиотеку C++?
Покажу вам два примера, для которых средств стандартной библиотеки особо и не потребовалось: номер раз (парсинг текста посредством PEG-парсера) и номер два (альтернатива express-js роутеру). Причем все это было сделано исключительно на шаблонах и в рамках C++14, даже не С++17.
ЕМ>Даже если ни они, ни Вы не будете сами сочинять все эти "умные" макросы/шаблоны, их сочинят для всех вас так же, как в свое время сочинили Boost/std.
Вы сейчас вообще о чем?
ЕМ>Но сделают это в человеческом виде, относительно легко поддающемся пониманию, исправлению и доработке, и способным выдавать сообщения об ошибках/предупреждениях осмысленно, а не просто в виде вывернутых наружу потрохов std.
Вообще-то работа с шаблонами в С++ с каждым новым стандартом в этом направлении и движется. Иногда прям большими такими шагами (один if constexpr в c++17 чего стоит и концепты из C++20).
Евгений, вот ейбоху если бы вы следили за развитием C++, то, вероятно, уже давно бы заметили, что С++ с развитием свох стандартых шаблонов уже давно движется в сторону того, о чем вы грезите много лет.
Здравствуйте, Sinclair, Вы писали:
S>А что вы называете "независимостью реализаций" в C++?
То, что есть разные компиляторы от разных производителей и эти самые производители не подчиняются какому-то одному центру принятия решений. И развивают свои продукты независимо друг от друга.
При этом если программа написана на С++ (а не на поддерживаемым конкретным компилятором диалекте), то она компилируется любым из этих компиляторов.
S>Но ведь чёрт возьми нет — прямо в стандарте у нас есть всякие implementation-defined специально для того, чтобы вендор мог ставить палки в колёса тем, кто пытается такую штуку сделать.
Мне думается, что вы не разбираетесь в предмете.
S>Простите, это какие-то детали реализации.
Это детали, с которыми нужно жить. И стандарт должен либо лояльно относиться к вариативности этих деталей (допускать различные реализации), либо должен их строго регламентировать. Вот как раз к тому, как и во сколько проходов делается обработка единицы трансляции, стандарт относится лояльно. Как раз из-за того, что стадии препроцессинга и компиляции отделены друг от друга.
S>В частности — отсутствием поддержки модульности хоть в каком-то виде.
Как бы в каком-то вполне себе определенном виде модульность есть в стандарте начиная с C++20.
Может вам таки продолжать пропагандировать .NET? Благо усилиями подобных евангелистов RSDN уже давно превратился в унылое это самое, где Шмыгам позволяется срать сколько угодно.
S>Причем дело вовсе не в том, что С++ был создан слишком рано для того, чтобы было откуда черпать такие идеи.
Не слишком рано, время тут не при чем. Критична была совместимость с Си.
Вы, вероятно, могли еще не родиться вообще, а программистам приходилось писать код на C++ и Си так, чтобы этот код мог компилироваться как Си-шным, так и C++ным компиляторами.
S>>Если бы в C++ попытались бы развить некие хитрые макросы, которые могут прыгать со стадии препроцессинга в стадию компиляции и обратно (и так произвольное количество раз), то это могло бы затруднить поддержку C++ в GCC, а без GCC-шного компилятора весь мир C++ был бы сейчас немного (или много) другим.
S>Совершенно непонятно, зачем бы нам потребовалось прыгать со стадии компиляции в стадию препроцессинга.
Чтобы разрешить макросам порождать новый исходный код, в котором используются другие макросы, требующие своего раскрытия.
S>>Я уверен в том, что оппоненту в C++ нужно в разы меньше чем среднему C++нику по больнице и на порядок меньше, чем лично мне. И на пару порядков меньше чем упоротым про производительности перцам из HFT или HPC. S>Я не очень понимаю, какое отношение всё это имеет к перцам, упоротым по производительности.
Например, использование паттерна CRTP дает чуть более производительный код, чем использование обычных виртуальных методов. Но CRTP требуют от программиста сдвига мозгов, которое позволяет осознать, что означает запись
class Derived : public Base<Derived> {...};
Есть у меня уверенность, что это один из тех "трюков", за которые г.Музыченко ругает шаблоны C++ и который г.Музыченко не нужен.
S>А все вот эти вот адские низкоуровневые оптимизации, за которые вы любите С++, примерно никакого отношения к шаблонам и макросам не имеют.
А вы точно уверены что знаете за что именно я люблю C++?
Здравствуйте, so5team, Вы писали:
S>То, что есть разные компиляторы от разных производителей и эти самые производители не подчиняются какому-то одному центру принятия решений. И развивают свои продукты независимо друг от друга.
Ну вот я про это написал. S>При этом если программа написана на С++ (а не на поддерживаемым конкретным компилятором диалекте), то она компилируется любым из этих компиляторов. S>Мне думается, что вы не разбираетесь в предмете.
В достаточной степени, увы. Ну, то есть я, конечно, в предмете разбираюсь плохо, но по моей статистике те, кто громче всех считает себя С++-профи, чаще всего разбираются в этом предмете ещё хуже, чем я.
S>Это детали, с которыми нужно жить.
Кому нужно-то? S>И стандарт должен либо лояльно относиться к вариативности этих деталей (допускать различные реализации), либо должен их строго регламентировать. Вот как раз к тому, как и во сколько проходов делается обработка единицы трансляции, стандарт относится лояльно. Как раз из-за того, что стадии препроцессинга и компиляции отделены друг от друга.
Стадия препроцессинга — это не то, чем стоит гордиться в современном компиляторе. А всё, что дальше — там тёмный лес, и никаких ограничений на количество проходов даже в нынешнем С++ нету.
S>Как бы в каком-то вполне себе определенном виде модульность есть в стандарте начиная с C++20.
Ну так я же вам об этом и пишу. Вирт втащил модули в 1978 году. С++ появился через 5 лет. А ещё через 37 модули появились в С++. Вы в самом деле считаете, что стоит гордится таким быстрым прогрессом? S>Может вам таки продолжать пропагандировать .NET? Благо усилиями подобных евангелистов RSDN уже давно превратился в унылое это самое, где Шмыгам позволяется срать сколько угодно.
Ну, я особо и не переставал. Что вы хотели узнать про .Net?
S>Не слишком рано, время тут не при чем. Критична была совместимость с Си.
Как совместимость с Си могла помешать реализации модульности? И что случилось с этой совместимостью в C++20?
S>Вы, вероятно, могли еще не родиться вообще, а программистам приходилось писать код на C++ и Си так, чтобы этот код мог компилироваться как Си-шным, так и C++ным компиляторами.
Я всё-таки постарше С++. И его код никак-никак не мог компилироваться С-шным компилятором.
S>Чтобы разрешить макросам порождать новый исходный код, в котором используются другие макросы, требующие своего раскрытия.
Для этого совершенно необязательно порождать буквы.
S>Например, использование паттерна CRTP дает чуть более производительный код, чем использование обычных виртуальных методов. Но CRTP требуют от программиста сдвига мозгов, которое позволяет осознать, что означает запись S>
S>class Derived : public Base<Derived> {...};
S>
О, вот может вы мне объясните подробнее сценарий использования этого трюка — почему нельзя сделать просто
Чем этот код хуже приведённого по ссылке?
S>Есть у меня уверенность, что это один из тех "трюков", за которые г.Музыченко ругает шаблоны C++ и который г.Музыченко не нужен.
А вы точно уверены, что знаете, за что г.Музыченко ругает шаблоны C++? Может он ругает их за какие-нибудь громоздкие сообщения об ошибках, если где-то что-то при подстановке не сошлось.
S>А вы точно уверены что знаете за что именно я люблю C++?
Нет, неточно. Приходится полагаться на ваши собственные слова.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[30]: The Big OOPs: Anatomy of a Thirty-five-year Mistake
Здравствуйте, so5team, Вы писали:
S>с variadic-шаблонами вы можете написать так:
Я и без них могу так написать, только писать придется на макросах, и обработка ошибок будет не менее заморочной.
Но можно поздравить себя, что даже к такой простейшей возможности пришлось двигаться почти двадцать лет, когда при минимальной поддержке компилятора и это, и еще до черта удобного/полезного, можно было сделать за несколько лет еще в 90-х.
S>А я и не про трюки, а про возможности C++, которые в нем появляются чтобы упростить решение стоящих перед разработчиками задач.
Неужто Вы не понимаете, что в этом примере constexpr выполняет исключительно формальную роль? Он не образует никакой конструкции или функции, которой компилятор не умел бы без него. Он лишь говорит компилятору, что в этом месте разрешаются вычисления только на стадии компиляции, и генерация run-time кода не предполагается. Такое и в традиционных "макросах для препроцессора" имело бы достаточный спрос (и наверняка имеет у тех, кто ими активно пользуется).
ЕМ>>В моих задачах найдется немало мест, куда можно было бы вставить шаблонные конструкции из std.
S>Например?
У меня, как ни удивительно, есть ряд более-менее общих классов и функций, структура и поведение которых меняются в зависимости от контекста. Сейчас там многое сделано на макросах, а будь в языке или std подходящие средства без трюков, я бы с удовольствием их использовал.
S>Почему-то когда люди сталкиваются со сложными научными или инженерными проблемами, для которых нужно хорошее знание дифференциального исчисления и ТФКП, то никому в голову не приходится жаловаться на то, что это сложные в изучении дисциплины.
И что, многие ли прикладники нынче решают свои задачи непосредственно этими методами? Они ж тупо берут подходящие пакеты, отдают им исходные данные, взамен получают результат (или его заготовку, которую достаточно доработать напильником). Если на вход поданы некорректные данные — годный пакет выдает вменяемую диагностику ошибки, а не вываливает трассировку стека.
Непосредственно сами математические методы необходимы теоретикам, исследователям, а прикладникам они требуются лишь при решении задач, для которых теоретиками не разработано типовых методов.
Вообще, если углубляться в этот аспект, то придем к тому, что даже программисту на питоне совершенно необходимо в совершенстве знать систему команд своей платформы, и уметь программировать в машинных кодах.
S>ну не всем дано и не у все хватает мозгов (у меня, например, не хватило).
Их не всегда "не хватает" — нередко мозги попросту иначе устроены/настроены. Кому-то вообще нетрудно покрутить в уме какой-нибудь гиперкуб и прикинуть, какой угол получится при том или ином сечении. А мои мозги тоже не заточены под ФА/ТФКП и подобные дисциплины, поэтому и в обработку сигналов глубоко не лезу, там все на этой высокой математике.
S>А вот когда по мере роста сложности софта требуется применять более сложные инструменты, то здесь уже "ай-ай-ай", как-так, пачиму-так-сложна!
Тут принципиально разные виды сложности. Сложность математических аппаратов проистекает от необходимости описать с их помощью явления, "данные нам в ощущениях", когда более простых способов описания попросту не существует. А сложность трюковых шаблонов сродни сложности ведения бизнеса в условиях, когда законы вроде бы и есть, но невнятны и противоречивы, и для интуитивно понятных операций изобретаются разного рода схематозы "тут надо отстегнуть Петровичу, там перетереть с Резким, а мэру пора бы напомнить, как мы его отмазывали после того залета". И ведь есть категория людей, которая в таких условиях чувствует себя очень комфортно, а наличие четких и прозрачных законов и правил их, наоборот, угнетает — негде проявить смекалку и срезать углы.
S>Сообщения об ошибках, при всей их безобразности в C++, далеко не самая большая проблема при использовании сложных элементов языка.
Когда ошибка возникает из-за непонимания самой сути элемента, или способа его применения в конкретной ситуации, а компилятор не в состоянии объяснить программисту, в чем проблема, так как ему неизвестен замысел последнего, это не вызывает особых претензий. А вот когда язык не дает программисту адекватных способов объяснить свой замысел компилятору, и вместо ясного и последовательного изложения приходится обходиться намеками и иносказаниями, это сильно раздражает.
S>Я уже пытался вытащить от вас примеры этих самых "побочных эффектов", но не преуспел.
Да Вы ж их сами прекрасно знаете — языковая конструкция, исходно предназначенная для порождения классов/функций, чтобы использовать их сами по себе, стала регулярно применяться для порождения сугубо нефункциональных, костыльных классов, единственная цель существования которых — извлечение отдельных свойств. Это как использовать матрицы для хранения признаков четности/нечетности или положительности/отрицательности в одном из элементов.
S>вашим оппонентам все еще непонятно что вы считаете трюком, а что нет.
Если им непонятно — пусть почитают отзывы известных специалистов, их есть в количестве, даже среди поклонников C++.
Re[31]: The Big OOPs: Anatomy of a Thirty-five-year Mistake
Здравствуйте, Евгений Музыченко, Вы писали:
S>>с variadic-шаблонами вы можете написать так:
ЕМ>Я и без них могу так написать, только писать придется на макросах, и обработка ошибок будет не менее заморочной.
- Ты же не можешь ответить "потому что гладиолус".
— Могу!!!
Кстати, вы проигнорировали мой вопрос относительно магнитофона tuple.
--
Справедливость выше закона. А человечность выше справедливости.
Re[27]: The Big OOPs: Anatomy of a Thirty-five-year Mistake
Здравствуйте, Евгений Музыченко, Вы писали:
M>>А если бы осилил, то полезное тебе подмножество было бы сильно больше
ЕМ>Количественно — больше, но качественно — не намного полезнее. Если б там просматривались какие-то качественные для меня прорывы, то давно освоил бы.
Намного полезнее. Просто ты зашорился в своём нежелании изучать инструмент, которым пользуешься
ЕМ>В большинстве-то случаев все эти трюки не дают радикальных улучшений, позволяя лишь более единообразно записывать то, что раньше делалось вразнобой. То есть, это полезно в первую очередь в групповой разработке, в открытом ПО, или в ПО, которое делает один, продает другому, тот дорабатывает, продает третьему, и т.п. Ничем из этого я не занимаюсь.
ЕМ>Поэтому, повторюсь, "осиливать" технологии, в основе которых лежат трюки, мне тупо эстетически неприятно, и я не вижу смысла заниматься этим до того, как ожидаемый эффект достигнет серьезных (для меня величин).
Так о любой технологии можно сказать, что в основе лежат трюки
ЕМ>Вот забавно, кстати: сейчас ведь набирают силу тренды вроде производства белков из насекомых, и многие категорически заявляют, что "не будут есть эту дрянь ни за что", хотя возможности определить фактический источник того белка в своей еде у большинства из них нет. И это считается позицией, вполне заслуживающей уважения — по крайней мере, пока. Однако нежелание таких, как я, погружаться в извращенную кухню трюковых шаблонов лишь потому, что они считается модными, и с их помощью можно сэкономить единицы процентов времени разработки, почему-то объявляется "ретроградством", "ограниченностью", "неспособностью осилить" и т.п. А ведь полностью избавиться от знакомства с "подкапотом" этой кухни невозможно, даже тупо используя готовые конструкции из примеров.
ЕМ>Вот лично Вы как относитесь к пище с "насекомыми" белками?
Да пофигу, если меня не будут лишать нормального мяса.
А "кухня" шаблонов тебе кажется "извращённой" потому, что ты её не осилил. Насчёт модности — ну, опять фигню сказал. Дело не в модности, а в том, что эта кухня упрощает жизнь и позволяет меньше писать, но больше делать
Здравствуйте, Евгений Музыченко, Вы писали:
M>>фишка в том, что терминология есть, какая есть. И чтобы понимать друг друга, следует её придерживаться.
ЕМ>Ну, это как большинство современных русскоязычных программистов, хорошо ориентирующееся в "корутинах", впадает в ступор при виде термина "сопрограмма", который в русском языке использовался еще с 60-х, но потом сошел на нет по причине угасания техник изготовления сопрограмм подручными средствами.
Покажи мне того, кто впадает в ступор от термина "сопрограмма". Сдаётся мне, это очередная твоя фантазия.
ЕМ>Так что терминология, которую отстаивает so5team, сложилась исключительно от нехватки образования и исторической преемственности. Полагаете, это следует приветствовать?
Ты про макросы/макропрограммирование? Ну, не важно, по какой причине, но так сложилось. Ты хочешь, чтобы весь мир перешел на твою терминологию? Это менее реально, чем тебе написать компилятор плюсов с блэкджеком
ЕМ>Кроме этого, не забывайте, что я не столько предлагаю ввести в C++ эти "макросы" сейчас, сколько сожалею, что они не были в него введены тридцать лет назад, когда термин "метапрограммирование" еще не примелькался так, как в последние годы.
Уж ты столько времени сожалеешь, что взял бы и написал