Усложнение C++ неизбежно. И не только C++

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


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


    Язык программирования — это технологичный продукт, но не все так просто


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


    Один из самых ярких примеров: цифровая фотография, которая в 1990-х была вообще никакой, но спустя всего 20 лет привела к краху такого монстра XX-го века, как Kodak (который, кстати говоря, первым и сделал прототип цифровой камеры).


    image

    Другой пример, близкий к разработчикам: эволюция жестких дисков. От здоровенных монстров времен мейнфреймов и мини-компьютеров, до небольших 3.5" и 2.5" дюймовых моделей, а затем до SSD формата M.2 и распаянных прямо на плате eMMC.


    image

    Тоже самое и с дискетами, которые сперва дошли до 3.5", а потом исчезли как класс под давлением USB-шных флешек.


    image

    Еще один пример из нашей профессиональной области — это развитие персональных компьютеров. Которые изначально были не в состоянии соперничать с «настоящими» компьютерами середины-конца 1970-х годов. А потом просто уничтожили мини-компьютеры как класс. Потом привели к появлению современных серверов, чем-то напоминающих тогдашние мини-компьютеры. И теперь ПК сами исчезают из массового потребления под влиянием ноутбуков, планшетов и смартфонов.


    image

    Авторы книги декларируют, что события во всех подобных случаях развиваются по одному и тому же сценарию:


    • сперва появляется потребность в каком-то продукте, решающем ту или иную задачу. Допустим, гибкий магнитный диск;
    • поскольку на начальном этапе все конкурирующие решения (коих, в принципе, немного) строятся на одних и тех же технологиях, то рынок оказывается поделен между более-менее похожими продуктами;
    • производители успешных продуктов начинают конкурировать между собой и в этой конкурентной борьбе доводят свои продукты чуть ли не до максимально выгодного соотношения цена-качество. И, главное, при этом существующие продукты максимально соответствуют взглядам на то, как должны решаться задачи, для которых эти продукты предназначены. Грубо говоря, все знают, что для переноса информации с одного мини-компьютера на другой посредством гибких магнитных дисков отлично подходят 8" дискеты. И другого способа никто в мейнстриме себе не представляет;
    • где-то в стороне, базируясь на каких-то новых открытиях/материалах/технологиях, появляется новый продукт, существенно уступающий уже имеющимся продуктам практически по всем параметрам. Как правило, дороже. Как правило, не сопоставимый по возможностям/мощностям. Но обладающий очень важным качеством: он может применяться там, где невозможно или затруднительно применять мейнстримовые решения. Например, в персональный компьютер не воткнешь 8" дисковод. А владельцам ПК не интересно таскать с собой 8" дискеты. Это просто не практично. Тогда как 5.25" дискета — вполне себе. И плевать, что по стоимости килобайта 5.25" дискета изначально была дороже 8". Выбора-то все равно не было;
    • вокруг нового продукта формировался новый рынок, который изначально был совсем не интересен производителям мейнстримовых продуктов. Но, поскольку это был новый рынок, то на него устремялись новые игроки, которые создавали серьезную конкуренцию друг другу. И эта конкуренция быстро переводила маргинальную и неэффективную технологию в чрезвычайно эффективную. Которая вскоре переставала быть маргинальной, ибо как только она превосходила по совокупности своих качеств старые мейнстримовые продукты, она стремительно заменяла их в их собственной нише. Грубо говоря, если вокруг есть сотни тысяч 5.25" дисководов и миллионы 5.25" дискет, то какой смысл держаться за гораздо более маргинальные на данный момент 8" устройства?

    Языки программирования как технологические продукты


    На первый взгляд похожие аналогии можно увидеть и в том, как языки программирования приходили в мейнстрим. И, пожалуй, наиболее ярким примерами здесь являются языки Java и Go.


    Язык Java появился как результат попытки создать «правильный C++». Но получившийся тогда язык вряд ли был бы кому-нибудь нужен, т.к. он был весьма убогий и, что еще важнее, медленный и прожорливый. На тогдашнем десктопе, даже учитывая бурный рост мощностей ПК в то время, у Java не было никаких шансов.


    Однако, Java зашла на «рынок» совсем с другой стороны, через нишу, в которой никто тогда толком работать не мог: через Интернет и апплеты для браузера (все было несколько сложнее и был еще рынок JavaCard и STK-апплетов, но не будем уходить в дебри). Интернет был очень горячей темой, а делать динамичные сайты/страницы тогда было просто не на чем (JavaScript появился уже после анонса Java). И, поскольку кроме Java применить было нечего, Java начали применять. Ну а потом, по мере ее развития и преодоления детских болезней, Java вышла в другие сферы, вытеснив оттуда другие технологии. Хотя в том же десктопе существенного куска пирога она себе откусить не сумела.


    Язык Go вряд ли смог бы кого-то заинтересовать в традиционных нишах, где уже жили C, C++, Java, C#, Python, Ruby и т.д. Но развитие продуктов для Интернета породило еще одну нишу — RESTful-сервисы. Для разработки которых Java была оверкиллом, C++ слишком сложным и опасным, Python/Ruby и прочая динамика — слишком тормозными. И вот один из самых убогих в выразительном плане языков, разработанных в XXI-ом веке, становится чуть ли не серебряной пулей для этой прикладной ниши. Откуда, возможно, со временем распространится еще куда-нибудь (чему лично я не удивлюсь с учетом общего уровня квалификации молодого поколения разработчиков).


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


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


    Но не все так просто с языками программирования


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


    Скажем, развитие ПК и рост их мощности делает владение парком ПК дешевле, чем владение одним или несколькими мини-компьютерами. Трехдюймовые дискеты в итоге оказываются дешевле на единицу емкости, чем 5.25" (с учетом большей надежности и пр. факторов). Цифровая фотография в итоге оказывается дешевле на кадр, чем пленочная. И т.д.


    Но с переходом от одного продукта к другому связаны еще два важных показателя — это стоимость/сложность непосредственно перехода, а так же скорость, с которой можно перейти на новый продукт. Эти показатели вполне можно оценить в деньгах. И если выгода от перехода на новый продукт присутствует, то переход осуществляется. Возможно не быстро, но осуществляется.


    И вот тут-то выясняется, что стоимость перехода с одного языка программирования на другой гораздо выше, чем в случае перехода от мини ЭВМ к ПК, от 8" дискет к 5.25" или от HDD к SSD. Поскольку смена языка программирования — это, обычно, полное переписывание программного продукта. Зачастую с нуля.


    А что значит переписывание? Оплата труда новой команды программистов, которой потребуется повторить уже имеющийся в продукте функционал. И пусть даже новый ЯП позволяет в два раза сократить размер команды, все равно это будет означать существенные затраты. Ибо если на разработку старой версии продукта было потрачено $10M, то переписывание потребует, минимум, $5M.


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


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


    И нужно упомянуть еще одну сторону этой медали: если программный продукт эксплуатируется в меняющихся условиях, то продукт неизбежно дорабатывается или перерабатывается под современные нужды. При этом у бизнеса нет возможности подождать год-полтора, пока появится новая версия продукта на новом ЯП, новая функциональность, как правило, нужна в обозримое время. Зачастую, еще вчера.


    Поэтому при переписывании расходы увеличиваются: нужно одновременно и писать новую версию, и развивать старую.


    На мой взгляд, именно это и объясняет, почему новые языки «выстреливают», в первую очередь, в разработке новых приложений для новой прикладной ниши. А вот вытесняют старые языки из ранее занятых областей уже гораздо медленнее. Самыми яркими примерами, наверное, могут считаться Fortran и Cobol. Мало того, что написанный на них софт все еще эксплуатируется, так и новый код на этих языках продолжают писать. И сами эти языки эволюционируют.


    И мне кажется, что один из самых страшных снов владельцев программных продуктов на Cobol, — это переписывание продукта на Java или C# ;)


    И еще один важный фактор: развитие самого ИТ


    Еще один момент, на который я хотел бы обратить внимание, — это факт того, что ИТ существует не так давно и история эволюции языков высокого уровня еще короче. Первая часть этой истории вряд ли даст нам твердую опору для рассуждений о том, как одни языки заменяют другие. 1950-е и 1960-е — это были годы экспериментов. Да еще годы, когда сам рынок компьютеров был сегментирован и значительная часть ПО писалась под конкретные компьютеры и ОС, без особых требований к переносимости. Количество действующих разработчиков ПО, а так же спектр областей, в которых широко применялись компьютеры, не идет ни в какое сравнение с текущим положением дел.


    ИМХО, принципиально вещи поменялись в 1970-х годах, а с 1980-х мы наблюдаем появление ЯП, которые уже опираются как на практический опыт прошлых лет, так и на результаты теоретических исследований. Как по мне, так именно 1980-е (и, может быть, поздние 1970-е) являются началом эпохи языков программирования, нацеленных на производство ПО в промышленных масштабах. Ибо именно тут мы видим Modula-2, SmallTalk, Ada, C++, Eiffel, объектные расширения Паскаля, Objective-C, Perl.


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


    Кстати говоря


    Перечисляя языки, появившиеся в 1980-х, я вспомнил про ЯП разработанные Никлаусом Виртом: сперва Pascal, затем Modula/Modula-2, затем Oberon.


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


    Но эти же языки показывают и то, насколько важно пользователям ЯП оставаться в рамках однажды выбранного языка. Переход с Pascal на Modula-2 был. Но отнюдь не массовый. И, не смотря на то, что Modula-2 более-менее активно использовался, настолько же популярным, как наследники Pascal, в особенности Delphi, так и не стал. А уж какого-то заметного перехода на Oberon так и вообще не наблюдалось, насколько я помню.


    Востребованный язык программирования нельзя просто так заменить. И что из того?


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


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


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


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


    В принципе, об этом давным давно говорил Бьярн Страуструп. И даже то, что я сам наблюдаю в течении почти что тридцати лет, подтверждает слова Страуструпа. Скажем, современная Java уже очень сильно отличается от Java 1.0 образца 1995-го года. Язык C# демонстрирует еще более впечатляющую эволюцию от удачного клона первой Java до, пожалуй, самого выразительного мейнстримового языка, пригодного для использования индусопрограммистами (вне зависимости от их национальности).


    Но самый яркий пример для меня — это все-таки язык Go. Который уже в XXI-ом веке начали делать сознательно повыбрасывав кучу вещей, отлично зарекомендовавших себя на протяжении десятилетий широкого использования в разных ЯП. И который благодаря, в том числе и этому, стал популярным. Но, тем не менее, жизнь берет свое и в Go вынуждены добавлять то, от чего авторы изначально намеренно отказывались — средства для обобщенного программирования (aka шаблоны/генерики).


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


    А так ли это плохо?


    Негативная сторона постоянно увеличивающейся сложности языков программирования (в особенности такого языка, как C++), вроде бы, очевидна: слишком высокий порог входа. Слишком много времени нужно потратить при изучении языка для того, чтобы начать выдавать код приемлемого качества в приемлемые сроки. Что делает разработку на сложном языке программирования и дорогой, и рискованной. Что будет, если из проекта уйдет один или несколько квалифицированных разработчиков? Как быстро и просто будет найти замену? Непростые вопросы.


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


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


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


    Тем не менее, математический аппарат, который осваивается в средней школе, не идет ни в какое сравнение с тем, что студентам ВУЗов затем будут давать на курсах по высшей математике. Особенно если это студент математического или физического факультета (да и не только, серьезно загружают высшей математикой на многих специальностях).


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


    Собственно, тоже самое и с языками программирования.


    Если вам нужно решать относительно простые задачи, то у вас есть выбор: либо вы используете более простой язык программирования, либо вы используете ограниченное подмножество более сложного языка. Но если вы столкнулись со сложной задачей (или специфическими условиями для ее решения), то у вас может не быть такого выбора вообще: трудоемкость решения этой задачи на «простом» языке может быть слишком большой.


    Кстати о задачах


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


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


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


    Однако, нужно принять в рассмотрение еще и такой фактор, постоянно усиливающийся с течением времени, как увеличение объема работы, приходящейся на одного программиста. Грубо говоря, если 25 лет назад один разработчик мог делать средней сложности форму для GUI приложения за один рабочий день, то сейчас такую же форму нужно склепать за два часа. А все остальное время потратить на другие задачи, которые бы 25 лет назад заняли бы еще неделю.


    Поэтому вполне может быть так, что вроде как вокруг тебя и несложная с виду рутина, но ее так много, что ее объем сам по себе представляет сложность. И поэтому сложный инструмент, который позволит автоматизировать рутину и/или снизит количество ошибок при ее реализации, так же может оказаться предпочтительнее более примитивного инструмента, пусть и более простого в освоении.


    Так что, с одной стороны, действительно, можно предполагать увеличение количества задач небольшой или средней сложности, для которых нет смысла использовать сложные языки, уровня C++, Scala или Haskell. Но, с другой стороны, сложные задачи все равно никуда не исчезают. Да и простая, но объемная, задача так же может потребовать для себя инструмента уровнем повыше Go или чистого C.


    При этом в нашем распоряжении есть языки программирования на любой вкус и цвет. Можно выбрать любой. Поэтому, как уже говорилось выше, у разработчиков есть выбор: можно взять простой инструмент для решения простой задачи, можно взять инструмент посложнее, но ограничиться только частью его возможностей. Поэтому, если кого-то смущает сложность современного C++, то это вообще не проблема. Т.к., во-первых, нет смысла применять C++ всегда и везде. И, во-вторых, никто не заставляет использовать сразу все фичи C++ в конкретном проекте, достаточно ограничиться только тем, что реально нужно.


    Итого


    Итак, что же можно сказать в итоге? Несколько вещей:


    • во-первых, времена изменились. Ситуация, когда язык программирования появился, начал широко использоваться, а затем исчез «с радаров», каковая имела место быть в 1960-1970-х годах, стала совсем иной. Появился спектр широкоиспользуемых аппаратных платформ, которые живут долго и будут жить долго. Время доказало всем важность такой штуки, как переносимость кода. Сами программы стали гораздо объемнее и сложнее (особенно с учетом всех их зависимостей). Поэтому если какая-то программа вчера была написана на языке X, сегодня она приносит пользу и завтра надобность в этой программе внезапно не пропадет, то язык X никуда не денется. Собственно, убедиться в этом можно посмотрев на язык C. Говно редкое, да и древнее как копролиты мамонта. Но многие продолжают жрать кактус. Причем, немалое их количество — добровольно и с удовольствием. Так что у мейнстримовых языков сейчас шансов остаться широковостребованными гораздо больше;
    • во-вторых, поскольку языки программирования не будут сменяться один другим так быстро, как это происходило лет 40 назад, то каждый востребованный язык будет неизбежно эволюционировать. Как по мне, так очевидно, что в сторону усложнения. Ну и увеличения объема, т.к. в языке будет сохраняться то, что в нем было изначально, так и будет накапливаться новое;
    • в-третьих, есть приличный выбор инструментов для различных задач. Где-то можно обойтись Ruby/Python, где-то подойдет Go, где-то дешевле всего будет остановиться на Java. Ну а где-то придется воспользоваться Rust-ом, C++, Scala или Haskell-ем. Так что вовсе не обязательно связываться со сложными языками программирования, если перед вами нет реально сложных задач. А если сложный инструмент все-таки потребовался, то вовсе не обязательно использовать его «на полную катушку», можно ограничиться лишь более простым и понятным для вас подмножеством сложного языка. И это нормально.

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

    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 261

      +14

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

        0
        стандартах и рекомендациях «это не использовать», «здесь читать, здесь не читать».
        эти стандарты и рекомендации появились не сколько из-за самих нововведений и расширений, сколько из-за обратной совместимости. Грубо говоря, в чистом C и в старых версиях C++ то-то и то-то делалось так, но это неудобно, а еще чаще небезопасно, поэтому в новом стандарте придумали гораздо более подходящую для этого фичу. Запретить пользоваться старым вариантом разработчикам нельзя, потому что это сломает совместимость с кучей старого кода, а вот рекомендовать не использовать — вполне можно.
        В этом плане, кстати, напрашивается какой-нибудь аналог JS-овского «use strict», который запрещает опасные и устаревшие вещи еще на этапе компиляции.
          0

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

            –1
            Вы себе противоречите: конструкция, которая вызывает неопределённое поведение, не может быть валидной по определению.
              +2

              Для компилятора она может быть вполне валидной.

                +1
                Более того, разные компиляторы разных производителей могут давать вполне определённое для данных настроек данного компилятора поведение (несовместимое с другими компиляторами), а могут и не давать.
                  0
                  Тогда это уже не «undefined», а «unspecified behavior» (или implementation-defined), а это немного разные вещи.
                    0
                    простой пример: по стандарту, прочитать из неактивного поля union'а — UB. При этом «большая тройка» (да и думаю во всех остальных компиляторах тоже) это поведение определяет, причем одинаково. Но формально это всё еще UB.
                      0
                      В C, вроде, это допустимо.
                0
                Ок.

                Арифметическое отрицание значения INT_MIN — неопределенное поведение => арифметическое отрицание не может быть валидной конструкцией (а так же вообще все арифметические операции, при которых может произойти переполнение).
                  0
                  И так же точно можно сказать про все операции. просто у каждой есть область определения (см.школьную математику)
              0
              В этом плане, кстати, напрашивается какой-нибудь аналог JS-овского «use strict», который запрещает опасные и устаревшие вещи еще на этапе компиляции.
              Есть Core C++ Guidelines, которые пытаются это делать на уровне статического анализа
            +9
            Главная проблема C++ — необходимость поддержания обратной совместимости. Это чудовищный груз, который очень мешает. Тут, кстати, недавно выкатили рацпредложение по этому поводу в виде эпох. Вкратце — оставить совместимость на уровне модулей (а это то ли бинарный, то ли AST, то ли нечто среднее между ними) и забыть о совместимости на уровне языка, явно декларируя нужную версию стандарта («эпоху») в исходнике. Компилятору, очевидно, придётся одновременно уметь компилировать разные эпохи.

            А что до усложнения вообще, то нельзя не обратить внимание на вполне очевидную тенденцию: чем сложнее изделие, тем проще им пользоваться.
              0
              необходимость поддержания обратной совместимости

              Эта необходимость есть у всех ЯП, претендующих на широкое использование. На то, что происходит, когда это нарушается, можно наглядно посмотреть на примере Python 2 и Python 3.


              Другой пример — это добавление генериков в Java, когда озаботились не только совместимостью на уровне исходных текстов, но и на уровне байт-кодов.

                +7
                Вот только C++ существует еще с начала 80-х годов, а по некоторым моментам тащит обратную совместимость не только с самим с собой с тех времен, но и с Си, который существует еще с начала 70-х. И, как по мне, в отрасли разработки ПО между 70-ми и 90-ми поменялось гораздо больше, чем между 90-мы и 2010-ми. Плюс C++ компилируется в нативный код на кучу архитектур, в отличие от интерпретируемого Python'а, или Java, у которой по сути только один официальный таргет — JVM.
                То есть у C++ груз «legacy» и требований к обратной совместимости гораздо больше, чем у современных языков, к сожалению. Страдают от этого, увы, все — и разработчики (язык становится все сложнее), и авторы стандартов (нужно вплести в язык новые фишки и не сломать ничего старого), и разработчики компиляторов.
                  0
                  Истинно так. И груз этот становится всё тяжелее и преодолеть его без радикальных мер становится невозможно. Комитетчики вроде, по слухам, даже намекали уже, что в будущем могут частично отказаться от обратной совместимости.

                  А вот если такие меры будут найдены и окажутся действенными, C++ сможет превратиться в элегантный, технологичный, красивый и лёгкий язык.
                    +1
                    «Бескомпромиссная» совместимость с C — важнейшее основание востребованности C++. Уберите ее и станет тяжело решать задачи, которые по объему кода составляют может 1%, но без них никак. И сам C++ с его недостатками скатится в дремучее легаси.
                      0
                      Никто не мешает сделать эту совместимость частичной. указываешь номер стандарта в первой строчке исходника и все. Если не указан, то считается последний стандарт с поддержкой си.
                        0
                        Не взлетит, имхо. 50% смысла начать что-то на C++ — возможность без накладных расходов взаимодействовать с C API и ABI. Даже у Rust накладные расходы есть, хоть и не большие.
                          0
                          Даже у Rust накладные расходы есть, хоть и не большие.

                          Можно поподробнее? Я не могу сходу назвать "небольшие накладные расходы", которые появляются во всех случаях взаимодействия Rust с C ABI.


                          Накладных расходов в рантайме при вызове C ABI в Rust нет совсем.


                          Если для используемой библиотеки C нет биндингов на crates.io, то появятся накладные расходы при разработке, связанные с необходимостью сгенерировать Rust биндинги для этой библиотеки.


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

                            0
                            Вы сами описали накладные расходы, которые есть в Rust и которых нет в C++. Да, они невелики, да, они меньше, чем в других языках, нуждающихся в FFI, но они есть и отличны от нуля.
                              0

                              Я попытался прояснить ситуацию. Эти накладные расходы зависят от конкретных обстоятельств и меняются от полного отсутствия [0], до значительных расходов в рантайме [1], или значительных расходов при реализации [2]. Небольшие накладные расходы есть разве что в среднем по больнице.


                              [0]: Например, в случае использования возможностей libc для работы с файлами с помощью стандартной библиотеки Rust.


                              [1]: Например, работа mio с Windows IOCP. Впрочем, это собираются исправить.


                              [2]: Разработка для неполностью поддерживаемых платформ: arm-unknown-linux-uclibcgnueabi, например.

                            +1
                            Вы видимо меня не совсем верно поняли. Когда подключаете заголовочный файл от старого проекта, то этот заголовочный файл интерпретируется как не соответствующий новому стандарту. Как вариант, можно реализовать через модуль (юнит). Т.е. старый кусок кода собирается в модуль, экспортирующий интерфейс в современном виде. Накладных расходов в рантайме я не вижу. А уж про ABI так вообще молчу. Причем тут двоичная совместимость? Речь идет про фронт компилятора, а бэк можно и старый оставить.
                              0
                              А уж про ABI так вообще молчу. Причем тут двоичная совместимость?

                              Недавно была любопытная статья на похожую тему: https://quuxplusone.github.io/blog/2019/08/08/why-default-order-failed/

                                0
                                Тут речь в первую очередь про экспорт шаблоных функций. Что вообще изначально было криво. А то что C++ ABI не совместим у разных компиляторов известно очень давно.
                                Основная масса API — имеет интерфейс С. И вот его обернуть во все, что угодно, проблем нет.
                                0
                                Вы знаете, я вообще довольно скептически отношусь ко всей возне вокруг модулей. И для C, и для C++ это, имхо, чужеродная концепция. Мне представляется, что ее можно будет использовать исключительно как дополнительную возможность, облегчающую интеграцию динамических библиотек. Причем в первую очередь на платформах, где такие библиотеки суть выполнимые файлы.
                                Так что будем посмотреть.
                                  0
                                  Для С возможно. Для С++ другого пути нет, ИМХО. Так как С++ очень сложный язык, компиляция программы, которая активно использует шаблоны (тот же буст), это вообще тушите свечи — компилятор зашивается из-за объемов разворачиваемых шаблонов. Одно спасение — прекомпилированные заголовки. Но блин, как-то это все криво. Вообще, заголовочные файлы (как и препроцессор) это страшный анахронизм Си, не в последнюю очередь из-за которого страдает развитие С++.
                                    0
                                    Объединение заголовков и прочего в один файл — разве сильно поможет?
                                    А вот шаблоны и препроцессор — РЕАЛЬНО ЖУТЬ!
                                      0
                                      Когда компилируется большой проект, компилятор может сотни (или тысячи) раз компилировать один и тот же заголовочный файл. А если этот файл содержит в себе сложные шаблонные конструкции? Тут спасает только прекомпиляция заголовков, когда компилятор один раз компилирует все часто используемые большие заголовочные файлы, а потом просто использует полученный код при компиляции исходников.
                                      Чем вам шаблоны не угодили? Шаблоны это мощнейшая фича С++, которая позволяла делать на нем то, что язык изначально не поддерживал (STL, например).
                                        0
                                        Было бы лучше то, что делают шаблоны встроить в язык иным образом.
                                          0
                                          В Go нет шаблонов. Ряд контейнеров встроен в язык (вектор и map), но всем не хватает шаблонов. Так как очень часто требуется несколько разных типов, но с одинаковыми обработчиками. И многое другое.
                                        0
                                        Шаблоны хоть на весь остальной С++ похожи, а вот препроцессор кажется чужеродной частью даже в С. Даже стрёмный М4 меня меньше расстраивается, потому что он изначально заявлялся как внешний по отношению к языку инструмент aka prebuild step.
                                          0
                                          Объединение заголовков и прочего в один файл — разве сильно поможет?
                                          Погуглите про jumbo builds — оно уже сильно помогает на больших проектах :)
                                            0
                                            Разве компилятору не должно быть пофигу находятся заголовок и всё остальное в одном файле или нет?
                                              0
                                              Заголовочник и исходник в одной файле или в разных — без разницы, разница появляется тогда, когда один и тот же заголовочник инклудится в большом количестве единиц компиляции (файлов с исходниками).
                                              Компилятор при каждом include должен заново компилировать все используемые хедеры, разворачивать макросы и шаблоны, и т.д. И отсутствие необходимости делать это каждый раз заново может очень существенно сократить время компиляции на больших проектах (правда, при этом существенно возрастают требование к объему памяти на билд-машинах).
                                          0
                                          Попытка скрестить ежа с ужом может породить только химеру колючей проволоки)
                                            +1

                                            Но модули от этого никак не избавят как раз из-за того, как устроены шаблоны. Поэтому в C++ отдельной компиляции шаблонов не будет никогда, а в модулях может лежать максимум токенизированное представление. Даже AST не построишь.

                                +2
                                Обратная совместимость может быть и обеспечена не на уровне языка. Тогда можно смело выбрасывать мусор и добавлять нужные нововведения любой степени радикальности, не опасаясь сломать легаси-код. Старый код просто получит компиляцию по старым правилам. В этом плане автор предложения об эпохах кивает на Rust, который сдюжил этот подвиг, и говорит «нам бы тоже надо нечто в этом роде».
                                  +1
                                  Кстати, питон похоже почти преодолел связанные с этим проблемы.
                                  +1
                                  Напомню, что Delphi умер когда в одной из своих версий потерял обратную совместимость.

                                  А если в результате отказа от совместимости — наступает смерть языка, то вместо создания мертворождённого несовместимца, не лучше ли сразу создать новый язык?!
                                    +1
                                    Обратная совместимость потерялась только на приложениях под мобильные платформы (Android и iOS). И не настолько сильно потерялась, можно включить режим обратной совместимости.

                                    На самом деле Delphi не умер. Microsoft сманил к себе его автора, а фирму-разработчика вынудил в итоге отказаться от Delphi. Сейчас Delphi в хороших руках и постепенно восстанавливает свои позиции. Кроме того, есть полностью опенсорсный бесплатный аналог — FreePascal + Lazarus, который тоже неплохо развивается.
                                      +1
                                      Обратная совместимость потерялась только на приложениях под мобильные платформы
                                      Обратную совместимость начали ломать еще тогда, когда оно под мобильные платформы компилироваться не умело, а именно, после 7-ой версии.
                                        0
                                        Подтверждаю!
                                        После Семёрке был КРАЙНЕ НЕПРИЯТНЫЙ сюрприз, когда старые проекты не работали в новой версии. :(
                                          0
                                          Если вы имеете в виду перевод string на unicode, то это не особо серьезная проблема. Где в string были буквы — работает как прежде и даже лучше. А у кого в string были байты — сами виноваты. Исправляется легко.

                                          Для мобильных платформ стринги сделали 0-based, а AnsiString вообще забанили.
                                            +2
                                            Нет! Проект написанный в предыдущей версии не хотел компилиться на новой, и дело было совсем не в строках!
                                            Точно не помню на что он ругался, но если не подводит память там формы из предыдущей версии не открывались в новой (не говоря уже о том, что полетели все сторонние библиотеки компонентов).
                                              0
                                              После Delphi 7 вышел Delphi 8.Net, который был не совместим принципиально. И все на него плюнули. Потом вышел Delphi 9 под Win32 и всё вернулось на круги своя.

                                              Проблема с исчезновением/устареванием сторонних компонентов — это концептуальная проблема компонентно-ориентированного программирования и к сожалению решения ни у кого нет.
                                                +3
                                                Многие настолько обломились с Delphi 8.Net и были разочарованы, что не стали даже пытаться проверить Delphi 9 под Win32 — кто-то по-прежнему продолжал сидеть на Delphi 7, а большая часть разбежалась кто-куда. :(
                                                0
                                                нормально всё компилируется, по опыту переноса нескольких больших проектов Delphi 7 > Delphi 2010. за неделю примерно утащили. все 100+ форм перенеслись без вопросов
                                                +1

                                                Я понял про что человек имеет в виду.В 7 версии появилась куча кроссплатформенный компонентов (привет Kulix).Основанный компоненты были на QT, но ари было представлено так что можно было применять и другие библиотеки.А в следующей версии все выкинули.

                                            0
                                            Хм. Вот недавно в свойствах своего проекта включил опцию /std:c++17, и, опа, проект не собрался. 'bind2nd': is not a member of 'std' и еще килобайты всякого.
                                              0
                                              Так они уже с 11-й версии устарели. Вот в 17-й их и выпилили. Давно пора использовать std::bind.
                                              +1
                                              Delphi никогда не терял обратной совместимости в общем-то. Большинство кода даже из Turbo Pascal работает. Нормально написанный код работает весь. Ну а тот код, в котором заложено что длина Char всегда = 1, а Pointer всегда 32 бита, конечно, скис. Потому что изначально был неверен.
                                              Вообще, отличная обратная совместимость — одна из основных фич реализаций языка, она реально отличная.
                                              Насчет смерти, то как говорили классики, новости о ней сильно преувеличены. Версии выходят постоянно. Компоненты и библиотеки пишутся (список бесплатных):
                                              github.com/Fr0sT-Brutal/awesome-pascal
                                              Бесплатная реализация хорошо развивается (FreePascal + Lazarus):
                                              wiki.freepascal.org/Lazarus_2.0_fixes_branch
                                              Конференция в телеграмме живёт:
                                              t.me/Delphi_Lazarus
                                              Десяток активных форумов в рунете.
                                            +2

                                            С go не так всё однозначно. Эволюция не в ущерб простоте. Тот же try хотели добавить, но после внимательного рассмотрения недостатки перевесили, и от фичи отказались. То же может случиться и с generics.
                                            Основная фича go — это обратная совместимость. Разработчики могут сконцентрироваться на доменной области или углубляться в CS, но не заниматься переучиванием на новую версию языка раз в пол года и попутно не плодить одинаковые по сути решения, но использующие разные наборы фич.
                                            Это, кстати, ещё одна проблема переусложнения языков программирования. Разработчик, как правило, уже не знает весь язык в совершенстве, а выбирает его подмножество, которое только частично будет пересекаться с подмножествами других программистов. И как итог имеем код в разном стиле в одном проекте и увеличение времени на чтение кода. То же не здорово.
                                            Если что, я не про то, что путь oberon и go точно правильный. Но я к тому, что тут сложнее. И уж точно не стоит говорить про "убогость" в выразительном смысле, возможно, вы не освоили, как на нем писать не убого из-за отсутствия привычных инструментов, но не более.

                                              +1
                                              ИМХО, основная фича Go — минимализм, благодаря которому любое сложное действие раскладывается на элементы с небольшим «собственным логическим сопротивлением». Не могу сказать, что мне это однозначно нравится. Но добавьте к этому продуманный синтаксический сахар для крайне востребованных действий (горутины, слайсы, каналы и т.д.) — и получается бомба.
                                                0
                                                И уж точно не стоит говорить про "убогость" в выразительном смысле, возможно, вы не освоили, как на нем писать не убого из-за отсутствия привычных инструментов, но не более.

                                                Испытать сложности с освоением Go — это нужно постараться.


                                                Но вот вы на нынешнем Go сможете самостоятельно написать аналог встроенного в язык ассоциативного контейнера? А контейнера, который бы позволял обращаться по нескольким ключам (аналог Boost.MultiIndex)? Или могли бы вы сделать средствами Go eDSL, который бы разворачивался во что-нибудь серьезное прямо в компайл-тайм?

                                                  +1
                                                  Испытать сложности с освоением Go — это нужно постараться.

                                                  У вас есть опыт? Есть большая разница между «прочитал синтаксис» и освоил язык.
                                                    0

                                                    Промышленного нет. Но программы строк на 100-200 для себя писал когда-то, дабы понять что это за оно.


                                                    Ну а как с вопросами про ассоциативные контейнеры и eDSL? Или можно считать их риторическими?

                                                      0

                                                      То есть ответ нет, не осваивали. К чему тогда такие резкие выражения?

                                                        0
                                                        То есть ответ нет, не осваивали.

                                                        То есть ответ да.


                                                        К чему тогда такие резкие выражения?

                                                        Давайте я повторю то, на что я бы хотел получить ответ, но вы не можете его дать, даже когда вам об этом напоминают:


                                                        Но вот вы на нынешнем Go сможете самостоятельно написать аналог встроенного в язык ассоциативного контейнера? А контейнера, который бы позволял обращаться по нескольким ключам (аналог Boost.MultiIndex)? Или могли бы вы сделать средствами Go eDSL, который бы разворачивался во что-нибудь серьезное прямо в компайл-тайм?
                                                          0
                                                          >> Но вот вы на нынешнем Go сможете…

                                                          Вы же сами знаете — может. Так зачем упираться в стенку?

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

                                                          При выборе языка не столь важны фичи, это выбор бизнеса, а потому все споры о таком выборе — попытка убедить бизнес в важности своих личных хотелок. Но хотелки субъективны по определению. Поэтому и ваше заявление выглядит бессмысленным, ведь оно точно так же субъективно и не интересно тем же гуглам, которым нужны дешёвые индусы, которым нужны простые языки. И пока вы будете исходить из своих хотелок — так ничего и не поймёте.
                                                            +1
                                                            Вы же сами знаете — может.

                                                            Точно может? А то ведь пока в Go шаблонов/генериков нет, как же он будет делать контейнер, подходящий для разных типов ключей и значений?


                                                            Ну и про eDSL в компайл-тайм тоже интересно.


                                                            И пока вы будете исходить из своих хотелок — так ничего и не поймёте.

                                                            Речь не про мои хотелки, а про то, можно ли считать Go выразительным языком. По современным меркам.


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

                                                              0
                                                              Легко. У Go есть интерфейсы и рефлексия. sync.Map же как-то написали. Другое дело, что по сравнению с дженериками он сильно проиграет по скорости работы и выразительности использования (дженериков реально в Go не хватает). Но поставленную задачу на нем сделать можно.
                                                              Про eDSL ничего не скажу. Я бегло посмотрел что это, разбираться не стал. Скорее всего, это на Go сделать нельзя. А вот задачу, которую решают с помощью eDSL решить на Go можно. Другое дело, может быть это будет не так эффективно или не так выразительно.
                                                                0
                                                                Легко

                                                                Пока не видно.


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

                                                                Ну т.е. не аналог если называть вещи своими именами.


                                                                и выразительности использования (дженериков реально в Go не хватает).

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

                                                                  0
                                                                  Подозреваю, что не видно, так как не нужно.
                                                                  Кто сказал, что аналог должен обладать той же скоростью работы? Он должен выполнять ту же функцию.
                                                                  Просто в Go программа получается легко читаемой. Берешь кусок кода и почти сразу понятно, что он делает. На том же С++ это совсем не обязательно (например, если взять кусок кода с декларацией парсера через boost::spirit, особенно, если для сокращения писанины активно использовался using).
                                                                    +1
                                                                    Кто сказал, что аналог должен обладать той же скоростью работы?

                                                                    Здравый смысл, как минимум.


                                                                    Просто в Go программа получается легко читаемой.

                                                                    Здоровенные портянки примитивного кода создают проблему читаемости просто своим объемом.


                                                                    например, если взять кусок кода с декларацией парсера через boost::spirit

                                                                    Ну вот C++ позволяет сделать spirit без привлечения внешних инструментов. Тогда как Go не позволяет. Следовательно, выразительные возможности C++ выше, а Go — ниже.


                                                                    Так о чем спор?


                                                                    Позволю себе напомнить, что началась эта ветка разговора с "И уж точно не стоит говорить про "убогость" в выразительном смысле". Пока что ничего не опровергает того факта, что Go в выразительном смысле убог. Что вовсе не означает, что в существовании Go нет смысла. Для многих именно эта убогость и есть киллер-фича Go.

                                                                      +1
                                                                      Хорошо, а как вы оцениваете выразительные фичи Перла? Например, всем известная программа: $??s:;s:s;;$?::s;;=]=>%-{<-|}<&|`{;;y; -/:-@[-`{-};`-{/" -;;s;;$_;see
                                                                      Очень выразительно, не правда ли?

                                                                      Разработчики Go, я так понимаю, пошли иным путем. Если тебе нужно сделать парсер, то воспользуйся специальным инструментом, например, flex/bison.
                                                                        0
                                                                        Очень выразительно, не правда ли?

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


                                                                        Я выразительностью называю возможность выразить в языке вещи, которые мне нужны для решения моей прикладной задачи. Например, создать нечто вроде Boost.MultiIndex. Или описать грамматику посредством Boost.Spirit. Или подготовить регулярное выражение непосредственно в compile-time. Или подготовить в compile-time SQL-выражение с контролем за типом параметров. И т.д., и т.п.


                                                                        Сколько при этом потребуется написать закорючек и насколько эти закорючки будут читабельными (см. ваш пример из Perl-а) — это уже несколько другой вопрос.


                                                                        Так вот, по моему мнению, Go один из самых невыразительных ЯП, созданных за последнее время.


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

                                                                          +3
                                                                          Если под термином «выразительность» понимать ваше определение, от спор не имеет смысла, так как Go точно не обладает «выразительностью».
                                                                            0

                                                                            О том и речь. И именно в таком смысле я отзывался о Go в статье.

                                                                              0
                                                                              Вы просто под выразительностью сразу подразумеваете выразимость идиом программирования на Си++. При таком определении, ни один язык, кроме Си++ выразительным не будет.
                                                                                0
                                                                                При таком определении, ни один язык, кроме Си++ выразительным не будет.

                                                                                Из тех языков, которые хоть как-то в поле моего зрения (а таких немного), есть как минимум D и Rust, оба повыразительнее C++ будут. И это я еще далек от того, что делают на Scala или Haskell.

                                                                                  0

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

                                                                              0

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

                                                                            0
                                                                            Если тебе нужно сделать парсер, то воспользуйся специальным инструментом, например, flex/bison.

                                                                            Особенно весело туда semantic actions встраивать будет. Размазня по куче файлов получится.

                                                      +1
                                                      И уж точно не стоит говорить про "убогость" в выразительном смысле, возможно, вы не освоили, как на нем писать не убого из-за отсутствия привычных инструментов, но не более.

                                                      Интересно, как так получается, что в своё время хаскель я освоил (хотя там привычных по плюсам инструментов ещё меньше, чем в Go) и он не был убогим, какой-нибудь Idris тоже освоил (хотя там привычных инструментов и парадигм ну тоже не так уж много, я бы сказал, что переход Haskell -> Idris такой же сложный, как C++ -> Haskell), и он не убогий, а вот с Go...

                                                        0
                                                        А что с Go? Там просто многие привычные подходы поставлены с ног на голову. Все на С++ привыкли, что берем библиотеку, наследуемся от базового класса и юзаем производный. В Го все иначе. Библиотеки объявляют необходимый им интерфейс, а ты в программе уже пишешь класс (структуру), которая соответствует этому (возможно, не только этому) интерфейсу.
                                                        Да, в Go не хватает дженериков. Из-за этого ряд задач решается неэффективно или муторно.
                                                          0
                                                          Все на С++ привыкли, что берем библиотеку, наследуемся от базового класса и юзаем производный.

                                                          Последний раз так делал в гуях на Qt, при разработке веб-сервисов или числодробилок не делал так ни разу.


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

                                                          Регулярно так делаю на плюсах в высокопроизводительном коде. За счёт шаблонов всё разворачивается и оптимизируется в компилтайме.

                                                        0
                                                        Тот же try хотели добавить, но после внимательного рассмотрения недостатки перевесили, и от фичи отказались.

                                                        Угу! Приходилось видеть путанную лапшу из кода состоящего из сплошных многоэтажных try-catch.
                                                        +3
                                                        Например, в персональный компьютер не воткнешь 8" дисковод. А владельцам ПК не интересно таскать с собой 8" дискеты. Это просто не практично.

                                                        Скорее всего причина была не в этом. Ибо без проблем люди таскали винил на обмен, да и проигрыватель винила будет больше 8-ми дюймового дисковода.
                                                          0

                                                          8" дисковод — это был здоровый, тяжелый и шумный ящик. Представить такой в десктопном корпусе XT-шки начала 1980-х лично мне сложно.


                                                          Будучи студентом несколько лет таскал с собой каждый день по несколько 5.25" дискет. Более-менее безопасно это можно было делать только в специальном кейсе. Небольшой кейс на 3-4 дискеты был по размеру сравним с общей тетрадью на 96 страниц. А обычный пластиковый кейс на 10 дискет по толщине равнялся учебнику объемом в 400-450 страниц и занимал изрядное место в сумке/портфеле/дипломате. Так в таком режиме таскать с собой 8" дискеты вообще не представляю.


                                                          3.5" дискеты в этом плане были намного практичнее, их можно было прямо в карманах носить. Что мы и делали.

                                                            +1
                                                            До массового завоевания рынка десктопными корпусами, там вполне неплохо жили игровые компьютеры (Commodore, Spectrum), для который дисковод поставлялся как отдельное внешнее устройство. Никаких проблем ему быть 8-мидюймовым не мешало.
                                                              +1

                                                              Кроме объема, веса, шума и стоимости.


                                                              Для загрузки информации в какой-нибудь zx spectrum или БК вполне можно было и бобинные магнитофоны использовать, но вот использование касетников почему-то оказалось практичнее.


                                                              Кроме того, IBM Personal Computer — это 1981-й год, IBM XT — 1983-й. Тогда как ZX Spectrum — 1982-й. В области ПК для бизнеса Spectrum-ы, насколько я знаю, погоды не делали.

                                                              +1
                                                              А 3.5" хорошо читались дискеты после карманов? У меня была четкая корреляция — если потаскал неделю вне бокса, шансов на нечитаемость очень много.
                                                                0

                                                                Нормально. Я носил либо в кармане рубашки, либо во внутренних карманах куртки/пиджака. А вот если бы в задний карман джинсов положил бы, то не знаю :)

                                                                +1

                                                                Сравните все три типа дискет:


                                                                image

                                                                  0

                                                                  Э… А в чем смысл вашего комментария? Тем более, что в статье есть аналогичный снимок.

                                                                    0

                                                                    Только в том, что средняя дискета наша отечественная. А так вы правы. Погорячится.

                                                                      +1

                                                                      Мы в свое время отечественные дискеты не жаловали.

                                                                        +1

                                                                        А сейчас отечественные ОС не жалуют. Правда, работающих с дисткетами отечественных ОС я тоже не знал, хотя если ОС ЕС отечестченная ОС, то я ошибаюся.

                                                                  +1

                                                                  А вот такой дисковод для 5.25" дискет кто-нибудь видел:


                                                                  image


                                                                  Очень полезная вещь была в свое время несмотря на всю громоздкость:
                                                                  Симбиоз майнфреймов и ПК. Первый отечественный дисковод, для чтения 5-ти дюймовых дискет для ЕС ЭВМ.

                                                                    0
                                                                    Сурово. Сколько человек нужно было, чтобы его на другое место передвинуть?:)
                                                                      0

                                                                      Это вы еще тогдашних отечественных мышек не видели, наверное:
                                                                      image
                                                                      Еще: https://habr.com/ru/company/dataart/blog/449460/
                                                                      Весила такая, по ощущениям, ближе к килограмму :)

                                                                        0

                                                                        Не только видели, но и до сих пор есть.

                                                                +4
                                                                Усложнение C++ неизбежно. И не только C++

                                                                В далеком 1988 году мне удалось приобрести копию книги Эндрю Таненбаума «Operating Systems: Design and Implementation». И в ней было дано описание языка Си, которое занисало всего десяток страниц (кстати, столько же занимало описание ассемблера). Это очень красиво. И я всегда ставлю в пример именно это описание языка Си. Там не убавить не прибавить. Вообще для усложнения существуют библиотеки.

                                                                  0
                                                                  Вообще для усложнения существуют библиотеки.

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

                                                                  А у плюсов основная проблема в том, что нынешних средств выразительности не было тогда, когда они были больше всего нужны…
                                                                    0
                                                                    Вот еще красивое описание языка www.lua.org/manual/5.3/manual.html#9
                                                                    +5
                                                                    Язык Java появился как результат попытки создать «правильный C++».

                                                                    Я всегда думал, что Java — это «Write once, run everywhere», а не попытка сделать правильный Си++.
                                                                      0
                                                                      Тем не менее, вдохновлялись они в том числе C++, и старались при проектировании избежать его недостатков.
                                                                        0
                                                                        Я всегда думал, что Java — это «Write once, run everywhere», а не попытка сделать правильный Си++.

                                                                        Java появилась как результат попытки написать ПО для какого-то умного бытового девайса на древнем C++ (с учетом того, что Oak project — это район 1988-1989 годов, то речь идет о совсем уж древнем C++). В итоге, как рекламировала сама Sun в то время: они взяли C++ и выбросили оттуда все лишнее и небезопасное. Соответственно, поэтому в свое время перейти с C++ на Java 1.0 было совсем просто.

                                                                          0

                                                                          В правильный C++ входит отсутствие необходимости перекомпиляции под каждую платформу :)

                                                                          +4
                                                                          Однако, нужно принять в рассмотрение еще и такой фактор, постоянно усиливающийся с течением времени, как увеличение объема работы, приходящейся на одного программиста. Грубо говоря, если 25 лет назад один разработчик мог делать средней сложности форму для GUI приложения за один рабочий день, то сейчас такую же форму нужно склепать за два часа. А все остальное время потратить на другие задачи, которые бы 25 лет назад заняли бы еще неделю.


                                                                          Может быть на потоке в сайтостроительной конторе и есть требования про 2 часа на форму. Но вообще хорошая форма пилится долго. Даже дольше чем было, ибо появились такие штуки как:
                                                                          • Бесконечное множество разрешений
                                                                          • Разная ориентация экрана
                                                                          • Специальная мобильная версия
                                                                          • Поддержка слабовидящих
                                                                          • Разная плотность пикселей
                                                                            +2
                                                                            Мне кажется, сравнивать язык с дискетами, например, не совсем корректно. Язык не служит для решения конкретной задачи, как продукты/технологии и не является продуктом потребления (что очень важно).
                                                                            Возможно, для прогнозирования, полезней было бы сравнить развитие языков с развитием технологий в исторической перспективе.
                                                                            Мне кажется, параллель между эволюцией каменного топора в ЧПУ-станок, а далее в необслуживаемые фабрики, прослеживается достаточно легко:
                                                                            1) раньше количество инструментов и задачи, решаемые ими, были малым и простыми;
                                                                            2) потом количество разнотиповых задач вместе со сложностью росли;
                                                                            3) потом местами перешли к мануфактурному производству, а местами технологии не позволяли, и труд там был все еще тяжелым и ручным;
                                                                            4) потом пошли фабрики (мощные компьютеры, способные выполнять любые задачи), производительность труда росла повсеместно (во всех областях появляются новые ЯП), даже там где труд все еще оставался ручным ©, объемы производства росли (объемы передаваемых/обрабатываемых данных, масштаб задач), так как развивалась транспортная сеть (локальные и глобальные сети), связь между центрами добычи ресурсов (сервера), производства (сервера), потребления (PC) усиливалась (рост скоростей обмена данными);
                                                                            5) Появляются новые группы товаров (новые технологии, мобильная разработка, bigdata и т.д. и т.п.), уровень потребления растет беспрерывно (к PC присоединяются телефоны, IoT и прочее), цепи производства могут охватывать всю планету (аутсорс, использование разных языков в одном проекте), растет клиентоориентированность производителя (кроссплатформенность).

                                                                            Довольно слабо связал, но на продумывание всего нужно время, особенно на прогноз.
                                                                              +6
                                                                              В общем и целом ваш набор логических рассуждений и нить повествования не сложилось у меня в то, что «Усложнение Си++ неизбежно». Может быть и неизбежно, но по каким-то другим причинам, не озвученным выше.
                                                                              Как минимум поддержка старого оборудования не требует усложнения языка, в следствии того, что компиляторы для тсраого оборкдования потчи никогда не будут поддерживать новые фичи языка.
                                                                                +18
                                                                                Собственно, убедиться в этом можно посмотрев на язык C. Говно редкое, да и древнее как копролиты мамонта. Но многие продолжают жрать кактус. Причем, немалое их количество — добровольно и с удовольствием.


                                                                                Лол. Ну действительно, если есть язык, который опровергает основной тезис статьи про неизбежный рост сложности активно используемых языков, давайте назовём его говном.
                                                                                  0
                                                                                  Почему вдруг опровергает? C вырос в С++, а С++ вырос в С++11, которому С уже не нужен.
                                                                                    +4
                                                                                    Если быть честный, то с K&R сложность С растёт с каждым стандартом. Понемногу, но растёт.
                                                                                      +2
                                                                                      Ну действительно, если есть язык, который опровергает основной тезис статьи про неизбежный рост сложности

                                                                                      Чем же опровергает? В изначальном C не было, например, const, restrict, типов для комплексных чисел, _Alignas/_Alignof, _Noreturn, _Generic, _Thread_local. И это мы еще не берем разные GNU-тые расширения, которые были добавлены в C-шный диалект от GNU за все это время.

                                                                                        –1
                                                                                        Много ль в C изменилось/добавилось со времён C98?
                                                                                          +1
                                                                                            0

                                                                                            Ну то есть вы теперь говорите что C — вполне себе развивающийся язык? Не видите ли вы здесь противоречия с текстом в статье?

                                                                                              +4

                                                                                              Противоречие в чем?


                                                                                              Язык C подтверждает два момента в статье:


                                                                                              1. Если язык широко используется, то он развивается. Язык C развивается.
                                                                                              2. Если язык широко используется, то он никуда не исчезнет просто так. Язык C никуда не исчезает и даже не собирается, к сожалению.

                                                                                              При всем при этом развитие C не делает его принципиально лучше.

                                                                                                +1
                                                                                                При всем при этом развитие C не делает его принципиально лучше.

                                                                                                Как-то Вы признавались, что опыта с «чистым» C у Вас немного? Откуда такое пренебрежение к языку, по TIOBI обгоняющего C++ почти в 3 раза?
                                                                                                  0
                                                                                                  Как-то Вы признавались, что опыта с «чистым» C у Вас немного?

                                                                                                  А сколько нужно съесть тухлых помидоров, чтобы понять, что это несъедобно? ;)


                                                                                                  Если серьезно, то мне не часто приходится писать на чистом С самому, а вот разбираться с уже написанным на чистом С кодом приходится гораздо чаще, чем хотелось бы. И практически всегда в коде сразу же видны места, которые можно было бы сделать компактнее/понятнее/надежнее, будь это не C, а хотя бы C++.


                                                                                                  Откуда такое пренебрежение к языку, по TIOBI обгоняющего C++ почти в 3 раза?

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

                                                                                                +1
                                                                                                Это не мешает ему быть говном, потому что его таким делают самые базовые концепции, от которых он ну никак не может отойти. Лично я считаю главным недостатком С отсутствие классов, а это фича, которая позволяет писать намного более безопасный (безбажный) код.
                                                                                                  0
                                                                                                  В С можно писать «классоподобно», единственное, насколько я знаю, все методы и члены будут публичными.
                                                                                                    0
                                                                                                    Используйте непрозрачные структуры — все члены станут приватными, да еще и «конструктор» с «деструктором» придется добавить.)))
                                                                                                      –1
                                                                                                      Security through obscurity хреновый вариант, Вы б ещё документацию предложили не писать :) как-то спокойнее поставить //These are private members, please, do not modify them directly Умному достаточно, а излишне самоуверенный всегда грабли найдёт.
                                                                                                        +1

                                                                                                        Что-то я не представляю как можно обеспечить security при доступе к полям структуры, которая лежит в том-же адресном пространстве. Делать для каждой структуры отдельный процесс и доступаться к ней через RPC?

                                                                                                          –1
                                                                                                          Вот такой способ мне и в голову не приходил. Наверняка можно ещё что придумать, например, переписать менеджер памяти… Уточню первоначальное утверждение: в С нельзя сделать приватные члены удобным способом с минимумом накладных расходов нельзя. Вот одно из обсуждений.
                                                                                                            0
                                                                                                            Вы точно знаете, что такое opaque structs? Кроме того, приватность/публичность не имеет никакого отношения к безопасности. Как писал Страутсруп, спецификации доступа для исключения случайных ошибок, а не для защиты от сознательного жульничества.
                                                                                                              0
                                                                                                              Я исхожу из того, что пользователь (возможно, я сам, когда забуду, как оно там работает) может сделать и через какое-то время сделает что-то очень тупое. Значит, ему нужно это или явно запретить в документации, или сделать невозможным. Приватность членов и непрозрачность структур дают достаточно хорошее предупреждение «не лезть».
                                                                                                    0

                                                                                                    1) Фиганул структуру с указателями на функции-методы (первый параметр каждой — self)
                                                                                                    2) Сделал фабричных функций вместо конструкторов/деструкторов
                                                                                                    3) ???
                                                                                                    4) PROFIT


                                                                                                    Единственный существенный минус Си — отсутствие RAII.


                                                                                                    Во всем остальном — это идеальный язык для своей задачи (системное программирование). Ну, может быть Rust когда-нибудь сможет что-то изобразить, но с учетом того, что у него даже ABI не стандартизирован, это еще случится очень не скоро.

                                                                                                      0
                                                                                                      Ну так потому и RAII нет, что классов нет. Поскольку то, что вы описали, не позволяет реализовать RAII, то и ООП я это назвать не могу. Собственно, я сначала хотел написать, что главный недостаток С — отсутствие RAII, но потом понял, что это нужно обобщить до отсутствия классов.
                                                                                                        –1
                                                                                                        Ну… Просто Си не следует рассматривать отдельно от Unix. RAII там есть, просто имеет форму создания процессов. И техника эта богаче ООП по своим выразительным возможностям.
                                                                                                          0

                                                                                                          atexit наше всё!

                                                                                                          0
                                                                                                          А какая связь между RAII и ООП?!
                                                                                                            0

                                                                                                            ООП инкапсулирует полиморфизм внутрь типа, но ведь можно его сделать над типом.


                                                                                                            В данном случае, нам нужно унифицированное поведение


                                                                                                            • при инициализации выполнить один триггер
                                                                                                            • при разрушении — выполнить другой триггер

                                                                                                            В ООП-языках для этого есть спецметоды.
                                                                                                            Ну, давайте сделаем спецфункции, делов-то.


                                                                                                            Даже особо не надо будет вламываться в систему типов сей.
                                                                                                            Введём служебный тип


                                                                                                            struct exit_guard {
                                                                                                              void(*exit_func)(void*);
                                                                                                              void* resource;
                                                                                                            };
                                                                                                            
                                                                                                            #include <beautiful_new_c_std/exit_guard.h>
                                                                                                            .....
                                                                                                            void foo() {
                                                                                                              int fd;
                                                                                                              struct exit_guard fdcloser;
                                                                                                              .....
                                                                                                              fd = open(.....);
                                                                                                              fdcloser.exit_func = (void(*)(void*))close;
                                                                                                              fdcloser.resource = (void*)fd;
                                                                                                              .....
                                                                                                            } /* в этом месте компилятор дёрнет fdcloser.exit_func(fdcloser.resource) */
                                                                                                              0

                                                                                                              В gcc есть расширение для этого.


                                                                                                              void cleanup_file(int *pfd) {
                                                                                                                  close(*pfd);
                                                                                                              }
                                                                                                              
                                                                                                              void foo() {
                                                                                                                  int fd __attribute__ ((__cleanup__(cleanup_file))) = 0;
                                                                                                                  fd = open(...);
                                                                                                                  ...
                                                                                                              }
                                                                                                              +2

                                                                                                              Отсутствие шаблонов — не менее существенный недостаток. Если уж расширить недовольство на классы и шаблоны, можно сказать, что отсутствие в C обобщённого программирования — большой недостаток. Частично это можно закрыть препроцессором, но будет примерно как в Go сейчас: либо копипаста ради едва различающихся типов данных, либо кодогенерация внешними средствами (или препроцессором), либо поголовные void * с кастами (аналог interface {}), да ещё и настоящий тип надо в каком-то виде в структуре хранить, чтобы не кастануть не туда.


                                                                                                              А если вспомнить, что стандартная библиотека, в общем-то, тоже часть языка, то на этом фронте у C вообще полный швах. Никаких коллекций, никаких строк (char* — это беспомощный набор байтов, а не строка, конечно), часть библиотечных функций откровенно дырявые и сохранены ради обратной совместимости. Справедливости ради, некоторые сишные функции не имеют простых и понятных аналогов в C++, например, printf, strtok, strftime. Есть затычки в boost и немного в STL, но они часто неудобные или слишком медленные. Каждый раз диковато выглядит необходимость вручную заводить буферы под текст.


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

                                                                                                                0
                                                                                                                Философия использования Си всё же другая. Она не про то, чтобы вообще писать всё на Си от начала до конца. Она про то, чтобы на Си писать ядро системы, узкоспециализированные утилиты и библиотеки, а более масштабную логику описывать уже на скриптовых языках. Поэтому особо острой необходимости в шаблонах не возникает. Является ли это самым оптимальным методом программирования — не знаю. Но опыт unix показывает, что работает.
                                                                                                  +4
                                                                                                  … посмотрев на язык C. Говно редкое, да и древнее как копролиты мамонта


                                                                                                  … караван идет.
                                                                                                  Даже сказать автору более нечего. Ну ткнуть его еще в «результаты теоритических исследований».
                                                                                                  +4

                                                                                                  "Имели место быть" -> "имели место".

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

                                                                                                    А как уважамый вы предлагаете под микроконтроллеры компактный и эффективный код писать быстро? На ассемблере что-ли?
                                                                                                    А вот выходит новый микроконтроллер, к нему надо разработать компилятор. Что проще компилятор Си или компилятор Си++?
                                                                                                      +15

                                                                                                      Да в общем хорошо читалась статья, пока не появилась строка про то, что С — говно. Как теперь серьёзно относиться к статье — непонятно.

                                                                                                        +2

                                                                                                        До этого в статье много воды. Зачем проводить аналогию с дискетами, а потом говорить что она не аналогия, т.к. куча кода который надо переписывать, — я не понял.

                                                                                                        0
                                                                                                        Что проще компилятор Си или компилятор Си++?
                                                                                                        Сейчас почти без разницы, если производитель использует готовую инфраструктуру проектов типа gcc или clang. К тому же, новые архитектуры процессоров выходят не так часто, а под периферию компилятор адаптировать не нужно.
                                                                                                        В принципе, автор изложил все правильно, и можно было бы поставить плюсик, но сентенция про мамонта все испортила. С другой стороны, мне плюсики недоступны, поэтому и проблемы нет.
                                                                                                          +2
                                                                                                          На Форте
                                                                                                            +3
                                                                                                            Да, упрощение и минимум действительно мощных особенностей языка + метарасширяемость в пределе — это ещё надо прочувствовать в своих разработках.

                                                                                                            P.S. Forth на лурке
                                                                                                            @" Итого, если в LISP скобка — это базовый эзотерический символ, а в прочих языках соблюдается некий баланс, то в Форте вся эзотерика строится на отсутствии скобок в записи выражений. Мегаследствие: все различия глобальных концептов в программировании определяются числом скобок в языке! А не всякими там ООП, замыканиями и прочими коротящими мозги штуками ." :)

                                                                                                            P.P.S. Комментарий к вопросу ниже. (т.к. по карме — 1-ин комментарий в час)
                                                                                                            При чём тут TCL?
                                                                                                            В Форт тоже предостаточно разных реализаций и по разным поводам ООП, но они, обычно, используются в ограниченном круге применений и не возводятся в догму «преклонения»?

                                                                                                            Возможности Форт достаточны, чтобы ещё решать задачи с обязательным привлечением ООП подхода.
                                                                                                              0
                                                                                                              Может, заодно коротенько объясните, зачем в Tcl больше одной объектной системы?
                                                                                                                0
                                                                                                                А какие там объектные системы в TCL есть?
                                                                                                                И насколько объекты из этих двух систем совместимы друг с другом?
                                                                                                                  0
                                                                                                                  Я точно помню, что поддерживаются как жаваподобный ООП, так и прототипное наследование. Что и как работает и насколько совместимо — не в курсе, я мало на тикле писал.
                                                                                                            –1

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


                                                                                                            А вот экосистема, которая сложилась вокруг него такова, что дешевле оставаться в ее рамках, чем пытаться перевести людей на что-то кардинально другое. Вот тот же Rust более чем адекватная замена чистому C. Но пока Rust доедет до этой ниши… И доедет ли вообще.

                                                                                                              +3
                                                                                                              Вот тот же Rust более чем адекватная замена чистому C.

                                                                                                              Пока нет. Пока там нет стандарта, к примеру, в ядрах ОС он точно будет неприменим. Так что ИМХО для таких заявлений нужно подождать стандартизации языка.
                                                                                                                +1
                                                                                                                Пока там нет стандарта, к примеру, в ядрах ОС он точно будет неприменим.

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


                                                                                                                https://lkml.org/lkml/2012/4/12/18


                                                                                                                That said, most of the stuff in C99 are extensions that we used long
                                                                                                                before C99,
                                                                                                                  0
                                                                                                                  Пока нет. Пока там нет стандарта, к примеру, в ядрах ОС он точно будет неприменим.

                                                                                                                  https://github.com/flosse/rust-os-comparison


                                                                                                                  извините

                                                                                                                    +3

                                                                                                                    Нет, серьёзно? Ядро линукса 23 года могло быть скомпилировано только одним компилятором (gcc) со включенными нестандартными расширениями. С какого тут боку наличие стандарта? Что оно дало?

                                                                                                                      +1
                                                                                                                      Нет, серьёзно? Ядро линукса 23 года могло быть скомпилировано только одним компилятором (gcc) со включенными нестандартными расширениями. С какого тут боку наличие стандарта? Что оно дало?

                                                                                                                      Хм… То есть я опять думаю о людях лучше, чем они есть. Печально.
                                                                                                                      А руководствовался я таким рассуждением: ядро ОС, особенно монстра уровня Linux или Windows, не имеет смысла писать на языке без стандарта, так как из оного языка могут быть изъяты фичи, которые используются в том ядре. К слову, использование нестандартных расширений тоже не очень хорошая идея, но если компилятор и ядро делает одно и то же сообщество, то простительно (ну правда, кто в здравом уме удалит из GCC те самые расширения, зная, что их использует ядро Linux).
                                                                                                                      Таким образом наличие стандарта ИМХО гарантирует на достаточно продолжительное время то, что язык не потеряет использованных в проекте фич, поломав авторам всю логику.
                                                                                                                        0

                                                                                                                        Так, а что с UNIX? То, что C в конце-концов стандартизировали, явно не причина его использования в UNIX, а наоборот — следствие его популярности, полученной в том числе и по причине его использования в UNIX.

                                                                                                                          0
                                                                                                                          Не соглашусь. Чем ближе к железу и чем ниже уровнем требуемые абстракции, тем меньше нужды в стандартах и переносимости. Линус как раз активно противодействовал и противодействует попыткам «причесать» код ядра в пользу стандарта и отхода от расширений GCC. И лично я склонен согласиться с его аргументами.
                                                                                                                          Вообще, есть как минимум 3 «подвида» C: прямое взаимодействие с железом (драйверы), базовый низкоуровневый системный софт (ядра ОС и т.д.) и программы более-менее общего назначения. Стандартность и переносимость существенны только в последнем варианте, а его место неуклонно сокращается.
                                                                                                                            0
                                                                                                                            Чем ближе к железу и чем ниже уровнем требуемые абстракции, тем меньше нужды в стандартах и переносимости.

                                                                                                                            Пожалуй, соглашусь с этой мыслью. Но уточню в ответе к 3 «подвидам»:
                                                                                                                            Вообще, есть как минимум 3 «подвида» C: прямое взаимодействие с железом (драйверы), базовый низкоуровневый системный софт (ядра ОС и т.д.) и программы более-менее общего назначения. Стандартность и переносимость существенны только в последнем варианте, а его место неуклонно сокращается.

                                                                                                                            С тем, что в 1 случае слабые требования к стандартности и переносимости, соглашусь. Но это в случае, если проект не предполагает переноса на другое железо.
                                                                                                                            Во 2 случае же всё зависит от сферы применения: в ядре ОС желательно иметь как можно бОльшую долю кода архитектурно-независимой, что всё же налагает какие-то требования.
                                                                                                                              0
                                                                                                                              А как по мне, так архитектурно-независимая ОС — это химера разума. Или причуда бальзаковского возраста. Выбирайте)))
                                                                                                                          0
                                                                                                                          Нет, серьёзно? Ядро линукса 23 года могло быть скомпилировано только одним компилятором (gcc) со включенными нестандартными расширениями. С какого тут боку наличие стандарта? Что оно дало?
                                                                                                                          Оно дало переносимость прикладных приложений, которые появились позже, на линухе свет клином не сошелся — есть еще Солярис, хБСД и AIX, не считая сонма менее распространенных.
                                                                                                                          И АФАИК, тсс тоже тестировался на компиляции ядра линуха, с теми же расширениями
                                                                                                                            0
                                                                                                                            Нет, серьёзно? Ядро линукса 23 года могло быть скомпилировано только одним компилятором (gcc) со включенными нестандартными расширениями. С какого тут боку наличие стандарта? Что оно дало?

                                                                                                                            так оно бы и еще 50 лет одним gcc компилировалось, если бы не стандарт. Вы вообще много знаете языков с хотя бы двумя равносильными компиляторами/интерпретаторами/вм? Зато 11! компиляторов с++ полностью поддерживают с++11.

                                                                                                                            Есть конечно у стандартизации и недостатки, в основном — замедление развития языка. Впрочем, без стандарта с++ наделал бы куда больше детских ошибок.
                                                                                                                              0
                                                                                                                              Зато 11! компиляторов с++ полностью поддерживают с++11.

                                                                                                                              Спустя 8 лет после выхода стандарта. Это успех.


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

                                                                                                                          +3
                                                                                                                          Напильник и молоток тоже устарели, ведь есть же многофункциональные комплексы, которые по программе сразу сделают все что хочешь… Но как-то грустно, когда их нет под рукой.
                                                                                                                            0
                                                                                                                            Напильник и молоток тоже устарели

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

                                                                                                                              +2
                                                                                                                              Аналогично и с «С», но вот eao197 думает иначе :)
                                                                                                                                –3

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


                                                                                                                                И то, что для С в каких-то нишах нет адекватной замены сейчас — это вовсе не хорошо, это печально. Так что я не радуюсь тому факту, что С "живее всех живых".


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

                                                                                                                                  +4
                                                                                                                                  Как сказал Френсис Бэкон: «Хромой калека, ковыляющий по верной дороге, обгонит всадника на горячем коне, несущегося по ложному пути.».
                                                                                                                                  Во многих случаях C до сих пор понятнее и более предсказуем, чем C++, причем чем «продвинутей» C++ — тем его отставание больше.
                                                                                                                                  Да, в процентном отношении эти применения составляют долю не большую, чем фундамент составляет в общем объеме небоскреба. Но это фундамент.
                                                                                                                                  Проявляя неуважение к C Вы не увеличите уважение к C++ и другим языкам. Только снизите доверие к Вашим рассуждениям.
                                                                                                                                    0

                                                                                                                                    У меня нет цели добавить уважения к C++. Тем более, что C++ я уже наелся досыта и не против бы сменить его на что-то более вменяемое. Так что могу сказать, что C++ не меньшее говно, чем C, но возможностей там сильно побольше, что делает C++ (для меня лично) предпочтительнее. А почему все еще остаюсь в C++ — это тема отдельного разговора.


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


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


                                                                                                                                    Поэтому как раз можно понять стенания о том, что C++ стал еще сложнее и "тяжелее". Но эти стенания издают люди, которые не отдают себе отчета о том, что такое положение вещей объективно и, как по мне, неизбежно. Об этом и статья.

                                                                                                                                      +1
                                                                                                                                      Тем более, что C++ я уже наелся досыта и не против бы сменить его на что-то более вменяемое. Так что могу сказать, что C++ не меньшее говно, чем C, но возможностей там сильно побольше, что делает C++ (для меня лично) предпочтительнее. А почему все еще остаюсь в C++ — это тема отдельного разговора.
                                                                                                                                      Просто в некоторых достаточно широких областях не на что, чего уж темнить =)
                                                                                                                                        0
                                                                                                                                        Просто в некоторых достаточно широких областях не на что

                                                                                                                                        Собственно, такая же история, как и с C, Fortran, Cobol, Java, ...


                                                                                                                                        Но ведь всегда есть возможность сменить область...

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

                                                                                                                                      В 1968, возможно, и не был. Но вот в начале 1990-х лично было непонятно, чем C лучше какого-нибудь Turbo Pascal и Modula-2. Ну, за исключением того, что в мире Unix-ов и системного программирования вообще он тогда стал де-факто стандартом.

                                                                                                                                        +3
                                                                                                                                        1. Он был экономичнее по ресурсам и пошустрее. Собственно, до сих пор по этим параметрам могут конкурировать только асм, форт, С++ в очень прямых руках и в отдельных задачах фортран.
                                                                                                                                        2. Под него были программисты и инструменты
                                                                                                                                        3. На нём уже куча всего была написана
                                                                                                                                        K&R объясняют, зачем С в 70е, а Страуструп — зачем он в начале 90х
                                                                                                                                          +1
                                                                                                                                          1. Он был экономичнее по ресурсам и пошустрее.

                                                                                                                                          Не думаю. Если в Паскале отключались встроенные проверки (посредством директив в коде, как в случае с Turbo Pascal-ем), то скорость и ресурсоемкость была такой же. В то время было много сравнений производительности кода на С и на Pascal.


                                                                                                                                          Другое дело, что для одних и тех же операций в Pascal-е нужно было написать несколько больше строк кода. Классический пример, от которого срывало крышу — это что-то типа такого: while(*p++ == *q++). После Pascal-я казалось верхом выразительности.

                                                                                                                                          +3
                                                                                                                                          в начале 1990-х лично было непонятно, чем C лучше какого-нибудь Turbo Pascal и Modula-2

                                                                                                                                          СКОРОСТЬ!
                                                                                                                                          Много ты знаешь игрушек написанных на Турбо-Паскале?
                                                                                                                                          А на мёртворождённой Модуле?
                                                                                                                                          Wolfenstein 3D — на C написан, и шустро бегал.
                                                                                                                                          А на Паскале или Модуле было бы — пошаговое слайдшоу.
                                                                                                                                          Сам я многие годы писал на Дельфи и с Паскалем тоже знаком, и я знаю что скорость работы программы к их достоиноствам не относится.

                                                                                                                                          Другое преимущество C, используемое и поныне — это возможность запустить на микроконтроллере, когда ресурсов мало. Например, памяти всего-то 64k, нет, не 640k, а именно 64k или ещё меньше.
                                                                                                                                          И это преимущество C — живо до сих пор!
                                                                                                                                          Так как, когда памяти хотя бы мегабайты, то C++ благодаря ООП получается всё же удобнее, чем просто C. А когда памяти мало, то C позволяет достичь большей оптимизации.
                                                                                                                                            +2
                                                                                                                                            А на мёртворождённой Модуле?

                                                                                                                                            На "мертворожденной" Модуле в свое время было написано много встраиваемого ПО и ПО для управления оборудованием. Где к быстродействию, ресурсоемкости и предсказуемости требования вполне себе. По отзывам тех, кто использовал Modula-2, использовать ее было гораздо удобнее и надежнее, чем С.


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


                                                                                                                                            А на Паскале или Модуле было бы — пошаговое слайдшоу.

                                                                                                                                            В расчетных задачах Turbo Pascal при отключенных проверках индексации не уступал Turbo C в свое время.


                                                                                                                                            И это преимущество C — живо до сих пор!

                                                                                                                                            Я начинал с машин у которых было 64K памяти. Программы на Turbo Pascal 3.0 там вполне себе работали. Так что 64K это еще вполне себе ничего. И Modula-2, и Ada там бы себя вполне хорошо чувствовали бы.

                                                                                                                                              0
                                                                                                                                              А на чём эта Модула крутилась?
                                                                                                                                              Так её и не увидел её ни разу живьём, хотя про неё часто писали.
                                                                                                                                                0

                                                                                                                                                Да на чем угодно. Я ее видел и под MS-DOS, и под Windows.


                                                                                                                                                Вот здесь есть список: https://freepages.modula2.org/m2in1.html


                                                                                                                                                И в англоязычной wiki: https://en.wikipedia.org/wiki/Modula-2#Compilers
                                                                                                                                                Там же, в английской wiki, есть немного про использование Modula-2, но что-то совсем скупо.

                                                                                                                                                  0
                                                                                                                                                  Это сейчас есть интернет.
                                                                                                                                                  А в 90-е годы, когда Модула была интересна, ни разу её не видел. :(
                                                                                                                                                    0

                                                                                                                                                    Тем не менее, он был.

                                                                                                                                              +1
                                                                                                                                              Wolfenstein 3D — на C написан, и шустро бегал.
                                                                                                                                              А на Паскале или Модуле было бы — пошаговое слайдшоу.
                                                                                                                                              Сам я многие годы писал на Дельфи и с Паскалем тоже знаком, и я знаю что скорость работы программы к их достоиноствам не относится.
                                                                                                                                              В Паскале есть всего одна особенность (вложенные процедуры/функции), которая может оказать незначительное влияние на скорость выполнения. В остальном, языки отличаются лишь синтаксисом, описывающим идентичные сущности. А медленным Паскаль/Дельфи были лишь потому, что оптимизация генерируемого кода была принесена в жертву скорости компиляции.
                                                                                                                                  +2
                                                                                                                                  за пределами определенных прикладных ниш он вообще мало кому нужен

                                                                                                                                  все языки за рамками своих ниш никому не нужны.
                                                                                                                                    +1
                                                                                                                                    Вот тот же Rust более чем адекватная замена чистому C.

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

                                                                                                                                      Я вот тоже жду статей с реальным промышленным опытом rust в командах. Какова цена поддержки? Какова цена ввода нового человека в команду? Насколько оправдан overhead на этапе разработки в реальных задачах? В каких оправдан, а в каких нет?

                                                                                                                                    0

                                                                                                                                    С нуля никто компиляторы не пишет, если, допустим, в GCC нужно добавить поддержку новой серии мк, то пишут для него Backend и он одинаковый для С и С++.

                                                                                                                                      0

                                                                                                                                      Скорее всего, эта цитата вброс такой. В проектах Gnome и в GTK+ используется Си, который отличается от "университетской копролитной сишки" так же, как Spring Framework от Java 3, потому что инструменты не сидят на месте, а обрастают функционалом и удобством. Правда, для новых приложений пишут на других языках, например Vala. В других "больших" проектах происходит то же самое, независимо от языка.

                                                                                                                                        0
                                                                                                                                        В проектах Gnome и в GTK+ используется Си, который отличается от "университетской копролитной сишки" так же, как Spring Framework от Java 3

                                                                                                                                        Принципиально лучше только вот она не становится. Скажем, в Ada со временем добавили поддержку ООП. В C++, Eiffel, Java, C# со временем добавили шаблоны/генерики, что дало языкам принципиально новые возможности. В C# завезли LINQ и различные фичи для поддержки этого самого LINQ.


                                                                                                                                        А чистый C как был примитивным языком, в котором было нельзя сказать что вот этот float у меня обозначает температуру, а вот этот — давление. И нельзя до сих пор. Каст из void* к любому другому типу указателя без проблем. Из средств отчистки ресурсов либо goto cleanup, либо GNU-тый __attribute__(__cleanup__) (но тогда и про чистый С говорить как-то не приходится).

                                                                                                                                          0

                                                                                                                                          Ради справедливости, есть GObject https://habr.com/ru/post/348204/ хотя согласен, что в языке есть фундаментальные проблемы, не решающиеся никаким новым стандартом.


                                                                                                                                          UPD. Не заметил ремарки про "чистый" Си. Ну ради бога, кто еще в современном мире пишет на чистом языке из коробки, если только коробка не содержит в себе "нечисть" в виде 100500+ встроенных библиотек.

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

                                                                                                                                            О том и речь. Эти проблемы известны давно, создавались языки, которые должны были стать (и становились) более безопасными, хотя и предназначенными для этой же ниши (Modula-2, Ada, тот же C++, отчасти). Но традиции Unix-ового хакерства все перевесили. Так что адекватной замены чистому C для тех ниш, в которых C традиционно применяется, практически нет. Даже когда вместо C используют C++, то это как замена шила на мыло. А Rust-у еще предстоит пройти большой путь.


                                                                                                                                            Но все это не отменяет того факта, что C слишком старый и небезопасный язык, лишенный многих выразительных возможностей.

                                                                                                                                            –2
                                                                                                                                            А си и не для того чтобы «вот этот float у меня обозначает температуру, а вот этот — давление», скорее для того чтобы быстро достать и перемножить миллионы флоатов без лишнего оверхеда на всякие ненужные структуры. Умно составленная программа и сама разберет — что из флоатов температура, что давление.
                                                                                                                                              +1

                                                                                                                                              Этого было достаточно в 1970-е. Но потом придумали как сделать так, чтобы в компайл-тайм проверять, смешиваются ли разные float-ы или нет. Без каких-либо накладных расходов в рантайм вообще. И сделать это можно, как минимум, несколькими способами.

                                                                                                                                          0
                                                                                                                                          Компактный и эффективный код под микроконтроллеры быстро (на сколько это возможно) пишется на Аде.

                                                                                                                                            0

                                                                                                                                            Если есть промежуточный язык, то какая разница?
                                                                                                                                            Фронтенд компилирует хоть с окамла, а дальше бэкенд с IL на целевую платформу.

                                                                                                                                            +5
                                                                                                                                            Проблема в том, что постоянно усложняющийся язык рискует рухнуть под собственной тяжестью. Его не только тяжело учить, но под него все тяжелее писать компиляторы, требуются разные костыли вроде IDE, линтеров и прочей обвязки.

                                                                                                                                            Затем по мере усложнения языка в нем начинают заводиться монстры, включая явные логические противоречия. Со временем дойдет и до чего-то типа геделевской неразрешимости.
                                                                                                                                              +2
                                                                                                                                              В целом умозаключения интересные, весьма даже, да только есть проблема — программирование сложных математических моделей (матмоделей) для инженерных расчетов. Эта область крайне сильно сейчас хромает, держась руками либо за мамонтов (Fortran, Pascal), либо постепенно переходя в новую область (тот же Python) с недостатком в скорости исполнения (я не о BigData). Да, в целом существуют и разрабатываются легковесные матмодели, которые можно легко использовать на Matlab или Python, да вот если вопрос стоит в объединении конструкции (3D) — прочности (к примеру конечно-элементный анализ) — аэродинамики — динамики — кинематики — энергоустановки в единый цикл проектного поиска то сложность подобного решения увеличивается экспоненциально! И тут уже в принципе нет такого удобного языка программирования, который бы отвечал удобностью, высокой скоростью выполнения расчета, надежностью конечного расчета, возможностью накопления большой базы данных моделей, которые бы в последствии не устарели в случае перехода к новой парадигме программирования или в принципе потенциальной смене языка… В этом случае постоянно пытаться изучать разные языки весьма неприятная необходимость, при которой всю базу придется переписывать заново или хоть как-то интегрировать через костыли… Нужен принципиально иной подход.
                                                                                                                                                0
                                                                                                                                                >> Нужен принципиально иной подход.

                                                                                                                                                Так фортран всё ещё живой — осваивайте, программируйте.

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

                                                                                                                                                  В вопросах объединения можно ещё вспомнить моделику (https://en.m.https://en.wikipedia.org/wiki/Modelica)

                                                                                                                                                  +4
                                                                                                                                                  Не могу сказать конкретно про C++… но вот есть три примерно сопоставимых языка — Smalltalk, Python и JavaScript… один (условно говоря) «мёртв» и «не развивается», другие два «живые» и «развиваются», и, по моему нескромному мнению, первый лучше и всегда будет лучше двух других, сколько бы чего в те ни напихали. Первый близок к совершенству, два других (по ср