Comments 98
В случае C, C++ и Rust что сравнивается? Компиляторы?
Я это к тому, что разница должна быть небольшой между ними, поскольку они довольно таки низкоуровневые и если компилировать одним llvm, то результат должен быть +/- одинаковым.
Мое нескромное мнение: языки C и C++ должны быть "убиты". Т.е. заменены там, где это возможно, более подходящими альтренативами. Лично мне кажется, что, по крайней мере, стандарты C++ слишком перегружены. Я вижу, как разработчики языка кайфуют от своего дела, но это очень напоминает швейцарский нож: вроде и все есть, а вот отвертку (или вставить нужное) я лучше отдельную возьму
статя так ржаво жoнглирует кофе и змеем, чтобы не отвечать на вопрос про D kоторый заменяет всё остальное а еschё программирует html
D умер под весом эффекта второй системы в исполнении собственного автора.
Насчёт умер, не стал бы утверждать. Да, не на хайапе, но в целом развивается, есть сообщество живое. Состояние — бери и пользуйся. Делал несколько небольших проектов для себя, получил удовольствие. Просто всё шикарно.
Выскажу непопулярное мнение: тот же раст при всех его несомненных концептуальных достоинствах имеет уж больно наркоманский синтаксис. На вкус и цвет..., но видеть это ежедневно перед глазами не очень бы хотелось.
Тем не менее на крестах, из-за его гибкости, можно описать абсолютно любое поведение, до самых мелочей. Нужно ли оно в коде? Ну...... А вот при написании всяких библиотек это просто сверх инструмент.
К сожалению, если нужен низкоуровневый доступ к аппаратным возможностям, то альтернативой им является только ассемблер.
Вроде бы с наличием LLVM — куча языков. Чуть ли не Котлин.
Как Вы представляете себе LLVM на MK? Если для старших Cortex-M или даже Xtensa (ESP8266/ESP32) он еще применим, пусть и ценой падения производительности, то для для восьмибитных МК, которые повтыканы в почти любой современный бытовой прибор - вообще никак.
Как только начинается embeded - С/C++ лидируют с отрывом.
Если для МК есть gcc, то в чём проблема сделать бэк для LLVM? Ну кроме традиций, привычек и устоявшихся практик? И с чего он вызовет падение производительности?
в чём проблема сделать бэк для LLVM
В этом как раз проблемы нет. Для Cortex-M и даже для Xtensa ведь уже сделали.
И с чего он вызовет падение производительности?
С того, что IR в LLVM подразумевает, как минимум, полностью 32-х битную архитектуру. И если на Cortex-M мы замечаем падение производительности только если шина или переферия у нас менее, чем 32-х битная, то если и архитектура CPU 16-ти или 8-ми битная, то вообще швах.
Как бы программист не старался в исходнике использовать типы uint8/uint16, в IR они уже превратились в i32 и информация о том, что при генерации машинного кода интересны только младшие 8 или 16 бит - увы, утеряна.
Если коротко, то LLVM хорош до тех пор, пока возможности целевой архитектуры превосходят возможности IR. Как только это оказывается не так - подход GCC/SDCC сразу выигрывает.
Как бы программист не старался в исходнике использовать типы uint8/uint16, в IR они уже превратились в i32 и информация о том, что при генерации машинного кода интересны только младшие 8 или 16 бит — увы, утеряна.
Не теряется. Упоминания i32
в IR — лишь следствие usual arithmetic conversions из C.
Не совсем понял, что вас смущает. В промежуточном коде подобная оптимизация возможно и преждевременна. Мало ли какая там арифметика на целевой платформе потом будет (может там троичный процессор?). При дальнейшей компиляции в код целевой платформы соптимизирует (или нет?)
Как человек, работавший почти 20 лет с C++ и с C, могу сказать: эти языки содержат столько разных неочевидных особенностей и так обрастают ими со временем, что подавляющее большинство пишущих на них людей знают их недостаточно хорошо и время от времени вставляют в код конструкции, точной семантики которых не понимают. В большинстве проектов больших команд можно найти в коде именно языковые ошибки, когда код написан "в лоб", но делает немного не то, что задумано, и правильно работает лишь чудом (обычно речь об UB, которое случайно скомпилировалось "как надо", либо о правильной работе кода только в подмножестве всех возможных вариантов). Так что современный C++ и современный C можно смело относить к языкам, слишком сложным, чтобы простой смертный мог их полностью и со всеми нюансами выучить. Что делает их в том числе опасными.
Технически, с точки зрения того, как код компилируется, единственным языком, претендующим на замену C, является Rust. Все остальные языки, такие как Go или Kotlin, изначально более высокоуровневые и конкурируют скорее с Java.
Что касается ООП, то разработчики Rust, будучи людьми, очень хорошо знающими C++, имели веские причины сделать язык без классов. С формально-математической точки зрения такие концепции ООП, как наследование, имеют очень странные и неочевидные свойства. Что приводит все к той же проблеме: люди часто неверно используют ООП и делают на нем очень странные вещи. При этом, имея в языке алгебраические типы данных, можно делать все то же самое, что делается и в ООП, но легче научить человека не лажать.
Судьбу C++ довольно легко предсказать: в скором будущем он превратится в язык, на котором все еще будет много писаться, но под который будет очень сложно и дорого искать квалифицированных специалистов. Сейчас Java стремительно становится таким языком, и уже давно такими стали FORTRAN и COBOL. Причем как минимум фортран (с коболом не работал, не знаю) до сих пор нельзя ничем заменить - это единственный вообще язык, в котором стандарт достаточно четко оговаривает, как именно должны вычисляться выражения с плавающей запятой. Из-за чего числодробильный код, если его перевести с фортрана на какой угодно другой язык, зачастую начинает неправильно считать. Поэтому на фортране сейчас пишется до фига и более, любой код численного моделирования взять, какой-нибудь расчет прочности - там фортран, и код это свежий, активно развивается. А поскольку фортран почти никто не знает, то те немногие, кто его все-таки учат, остаются востребованными, и язык живет.
COBOL заменить той же Java или другим языком JVM — формально просто. В самом коболе нет ничего такого уникального. Более того кобол разрабатывался так, чтобы менеджер по продажам глядя на код понимал что происходит (та самая буковка "B").
Но проблема в том, любая реально работающая программа на коболе по сути написана не на коболе, а на особом мета-языке. Который, несмотря на некоторую стандартизацию, всё же различается между фирмами. И потому не то что менеджер — бывалый программист с 50-ти летним стажем не всегда разберётся.
Это как если бы не было С++, а вместо этого на С в каждой конторе писали бы в своём понимании классов и ООП (иногда такое и происходит — видел пару раз).
Проблема в том, что не считая вакханалии с C++14 и далее, в целом C++ довольно консервативный язык, переживший десятилетия с достаточно скромными изменениями и хорошей обратной совместимостью. Его монстральность -- это следствие не только проектных решений, но и банального возраста, а жизнь показывает, что другие языки выдерживают испытание временем даже хуже.
В этом смысле любой язык старше 10-15 лет показывает свой тип накапливания энтропии. Java и C# аккумулируют новые средства как не в себя, причём C# ещё и вводит кучу новых ключевых слов и конструкций просто ради syntactic surgar по велению левой пятки. Везде появляются и типизированные контейнеры, и лямбды, и асинхронные операции, и чёрт ещё знает что. Для Java бонусом идёт зоопарк систем сборки и графические библиотеки (AWT/Swing/JavaFX/etc.) Python плюёт на обратную совместимость, из-за чего приходится держать на машине все версии, начиная, наверно, с 3.6 (а ещё 2.7 впридачу).
В языках помоложе порог вхождения ниже, но и чего-то неизбежно не хватает. Ну а дальше юзеры ноют, почему в языке X это есть, а у нас нет, и ещё через десять лет наш язык тоже постепенно превращается в X. Так что в этом контексте C++ ещё не самый плохой вариант, и будет интересно посмотреть, во что превратятся за ближайшие годы его конкуренты.
А вообще... кто нас спрашивает-то? Вот решил Джобс, что на iPhone все будут писать на Objective-C. И всё, как миленькие бросились писать на Objective-C. Потом объявили переход на Swift, и не стало никакого Objective-C. Сик транзит, как говорится.
Да, с накоплением фич это действительно так. Но сказывается и то, кто именно разрабатывает язык. Я слышал от знакомых математиков ругань в адрес комитета C++, что те, кто придумал добавить в язык концепты, изобрели деревянный велосипед и не разбираются в теории типов и заодно в теории категорий. Очень похожая ситуация с ООП, когда в базовых учебниках представляют наследование классов как что-то вроде получения подмножества множества, а математически это ни фига не так и имеет вообще другие свойства. ООП в его Java- или C++-виде разработано наивно, и при глубоком копании там вылезают математические противоречия.
Среди новых языков есть много таких же наивных (D, Kotlin), а есть попытки математизировать подход и сделать "как теория велит" (Rust). Насколько там удастся придерживаться теории, покажет время, но пока получается неплохо.
Всякие вещи вроде лямбд на самом деле очень любит компилятор, а не пользователи. Дело в том, что чем императивнее код, тем труднее его оптимизировать, а для чисто функционального кода оптимизатор написать легче всего. В этом основная причина того, почему "громоздкие" языки нередко обходят C на benchmark game. Оптимизатор компилятора умеет писать код лучше человека, и характерное для C "разжевывание" алгоритма ему только мешает. Тот же алгоритм на шаблонах C++, на Rust, на Haskell, на чем угодно, развязывает компилятору руки, машинный код получается компактнее и изящнее. Дальше уже вопрос, справится ли человек с таким языком. Писать на шаблонах C++ очень трудно, писать то же самое на Haskell на порядок легче, на Rust примерно так же. На данный момент у среднего программиста код на Rust будет получаться лучше, чем на C++ (если честно, я вообще не доверяю коду на C++, написанному средними программистами, потому что за 20 лет уже насмотрелся, ЧТО там бывает).
Вместо C++ может быть любой язык на самом деле.
Любой код пишется в системе некоторых допущений относительно внешнего мира.
Языки все-таки очень разные по сложности освоения. И по вероятности ошибок. На C++ легко сделать ошибку даже в Hello World. На Фортране замена десятичной точки на запятую в корне меняет смысл строки, при этом и до, и после замены строка синтаксически верна и компилируется. На Питоне легко налажать с алиасингом объектов в массивах, но таких пакостей, как в Фортране, нет как класса. На Rust на этапе компиляции лезут даже некоторые архитектурные и логические ошибки, когда компилятор замечает, что не все варианты исполнения рассмотрены или что иногда объект уничтожается раньше, чем предполагал программист. И еще разная сложность маскировки ошибок. На C++ я легко напишу код намеренно с багом, и искать этот баг придется очень долго, без дебаггера большинство людей не увидит. На каком-нибудь Go или Rust так не получится, странная конструкция сразу бросится в глаза.
А критика концептов с точки зрения математиков есть где-то в виде текста? Очень интересно.
К сожалению, не знаю. Самому интересно. Критиковавший человек специализируется как раз на языках и компиляторах, а критика была в духе ":facepalm: ну как так можно-то, тут люди диссертации пишут на тему того, как типы в языке работать должны, а эти слоны в посудной лавке взяли и сделали все поперек учебников". Но в любом случае имелось в виду soundness системы типов.
до него два единственных стандарта — C++98/03 и C++11.
Дело не в формальном стандарте, у Питона вообще нет "стандарта", была некая ad hoc реализация автора, и это и был "стандарт", и ничего. "Стандарт" C++ описывался в книге Страуструпа The C++ Programming Language, и по ней и определялось, что в языке, а что нет. И по изданиям видно, что эволюция языка до C++11 была достаточно скромной, а расширение шло в основном за счёт стандартной библиотеки. Соответственно, если язык фактически в ходу с середины 80-х, оттуда и отсчитываем.
Не уверен, что это хорошо.
А я же немного другую тему обсуждаю: если вы любите изменения, но не любите монструозность C++, то будьте готовы, что ваш любимый язык NN трёх лет от роду ещё через 15 лет будет точно так же монструозен. И да, в нём с самого начала будут лямбды, а через 15 лет прикрутят сбоку то, что будет модно через 15 лет.
> Просто, похоже, авторам C++ не повезло разложить язык по очень кривому и неортогональному базису
мыслите правильно, но требуемая ортогональность также связана с возможностями используемой грамматики (сравните с грамматиками van Wijngaarden для определения ALGOL 68), с учетом того что С++ начинался как препроцессор для C, вероятно таки ожидания оправдал,
хотя по большому счету возможно сложнее, например автор Fortran John Backus считал узким местом языков высокого уровня саму архитектуру von Neumann, см выдержку из его статьи 1979 года -
поэтому говорить о какой-либо обратной совместимости языка до более-менее появления соответствующих хоть какому-то единому стандарту (будь то хоть святые писания Страуструпа) реализаций нельзя, потому что обратной совместимости не бывает без простой совместимости, а её не было
Я вполне понимаю эту логику, но мне кажется, что с такой меркой подходить к реальному миру просто непродуктивно. Первый стандарт языка С -- это ANSI 1989, и если мы реально будем отсчитывать историю C от 1989 года, то на чём же тогда UNIX написан был? Да, костыльность старого кода C++ очевидна, но тем не менее, тут вопрос с чем мы сравниваем -- с гипотетическим идеалом или с реальными production-level языками того же времени и ниши.
Мой любимый язык — хаскель, ему 30 лет, первый стандарт вышел в том же 98-м.
Страуструп на эту тему высказался: языки делятся на те, которые все ругают, и на которых никто не пишет. Это ни в коем случае не в пику Хаскеля, но надо понимать, что он живёт в условиях "ниже радара" широкой публики, а это совсем не та модель бытования, которую обсуждают в рамках разговора "чего бы такого изучить, чтобы через 30 лет оставалось актуально". Мне, положим, FORTH нравится, он сразу вышел хорошо, там и менять ничего не нужно.
Насколько несовместимы были между собой разные версии C до 89-го?
По правде говоря, не знаю. Между первым изданием K&R и стандартом ANSI прошло 10 лет. Мы видим крайние точки -- в них языки уже достаточно сильно расходятся (сам язык C, впрочем, небольшой), а что за "релизы" были в промежутке, сказать не могу.
Начинать теперь говорить, что это из-за существенно более низкой доли языка — подгон решения под ответ.
Критика принимается. Но всё же стоит отметить, что весь этот вал изменений в C++ -- это не плод личного желания Страуструпа или узкого круга ценителей, а тонны разнородных proposal'ов с самых разных концов индустрии. Собор vs базар, короче говоря.
Я вполне готов допустить, что нишевый язык для ценителей может развиваться долго и гармонично, но при этом, вероятно, и останется нишевым.
уж поверьте человеку, потратившему пару календарных месяцев на портирование кода с gcc 6 на gcc 8),
Да я верю, но вы сравниваете с гипотетическим идеалом, а по факту, например, хоть какая-то совместимость C++ со старым C являлась одним из важных факторов его популярности, ведь так же. Мы же берём лучшее из имеющегося, а не то, чего хотим в теории.
А где тут собор, а где — базар? Потому что в случае плюсов все эти пропозалы проходят через весьма централизованный комитет
Ну, исходная метафора Рэймонда тоже хромает, так что чего придираться к словам. Но если угодно, сообщество Хаскела -- это "прихожане", которые строят "собор", имея некое общее представление. А сообщество C++ -- это "базар" из разнородных участников, и наличие "дирекции" на базаре не делает его собором.
Ну да, для не-нишевости нам не хватает… чего? UB из всех щелей, наверное.
Ну это же не ко мне вопрос, чего Хаскелу не хватает. Я всего лишь ссылаюсь на некую наблюдаемую реальность.
Вы осознаёте, что вас тезис становится всё менее проверяемым в лучшем случае, а в худшем — всё более невалидным?
Мой тезис -- язык C++ обратно совместим и кросс-платформен (вот это не упомянуто раньше, но не менее важно). Просто я использую это в относительном смысле: обратно совместим не по сравнению с идеалом, а по сравнению с конкурентами. И тезис этот идеально проверяем: мы можем обсудить конкурентов (особенно на момент взлёта популярности C++, т.е. где-нибудь начало 90-х).
Чуваки, которые пилят пропозалы по более адекватной работе с рекордами, и чуваки, пилящие линейные типы — совершенно разные люди, друг друга даже особо не знающие
Опять же, это чуваки из условно одной тусовки. Нет такого, что один пишет для банка, другой для микроконтроллера, третий для автопилота, четвёртый для операционной системы, а пятый для компьютерной игры. То есть (см. выше) всё относительно, это "одна церковь", раз уж собор, а знать прихожанам друг друга и незачем.
Как это сделать объективно?
Ну для начала надо решить, с чем сравнивать, а потом уже определимся как. То есть прыгаем в условный 1995 год и смотрим, что у нас есть, например, для разработки банального GUI архиватора, чтобы работал под Wintel, Mac (PowerPC), а версия командной строки ещё и на UNIX-like сервере. Как-то не помню, чтобы в этом контексте обсуждался Fortran. Вот C -- да, конечно, с точки зрения совместимости и кроссплатформенности на голову надёжнее C++.
Почему? Один пишет опердни в ретейлере, другой — для веба, третий — компиляторы, четвёртый — вообще криптобро.
Ну это всё условно железо типа "серверный бэкэнд". Давайте так, у одного мобильная игра, у другого PlayStation, у третьего GUI desktop app по типу MS Office, у четвёртого Ардуино. Система может быть realtime, с чёткими таймингами, например. Покажите хотя бы одну игру на Хаскеле.
В 95-м как раз появилась java, и awt там уже было.
Не, ну это уже игры. Пусть будет 94-й год. Да даже 95-й, надо было быть фанбоем, чтобы бросаться на новомодную технологию с неясными перспективами.
Задачи-то разные, контексты разные и требования разные.
Это так, но всё равно в рамках некоего пузыря. Как в футураме, пусть вас не смущает идентичность их ДНК, эти кандидаты в главном отличаются.
Ну опять это игра в слова. Да, конечно, кто сомневается, что на тьюринг-полном языке можно написать шашки. Реальные проблемы же на другом уровне начинаются.
А так-то можно хоть под ембеддед писать, вот.
Ну это уже другой язык, пусть даже и основан на Haskell. Так-то можно сказать, что Ada -- то C, потому что компилятор GNAT реально транслирует в C и вызывает GCC.
Исходный посыл же не в том, что теоретически возможно, а что невозможно, а в том, где путь наименьшего сопротивления.
был
#ifdef
.
Да. Это и есть кроссплатформенная разработка, потому что платформы разные. Альтернатива -- писать под единую виртуальную платформу типа Java, где #ifdef просто пишет кто-то другой (автор JVM).
смотрите: C++ — тоже в рамках некоего пузыря. Никто не пишет веб-фронтенды на C++, почти никто не пишет перекладывание жсонов а-ля го/питон/nodejs,
Я думаю, нет никакого сомнения, что это прекрасно можно делать на плюсах. Но авторам такого софта не нужны декларируемые ценности плюсов, поэтому они выбирают другой язык со своими преимуществами, более нужными там, логично.
Да и даже если социальные, то перспективы плюсов в середине 90-х были, скажем так, очень туманны, с такой-то кучей несовместимых реализаций.
Ну, тезис не меняется, просто такого рода дискуссии всегда опираются на некий подразумеваемый неявный базис. Исходный тезис был в том, что selling point языков C/C++ является обратная совместимость и кроссплатформенность, а монстральность C++ -- неизбежное следствие его возраста и популярности. Если на это ответить, что существует язык Х, который силами узкого круга любителей развивается over 9000 лет без монстральности, а десяток студентов продемонстрировали возможность портировать Doom и шашки, что я могу на это ответить?
По факту мы видим, что в своей нише "туманные перспективы" остаются туманными по сей день. Даже если вы пишете игру под айфон на Юнити (C#), под капотом работает транслятор в C++ и далее в native code. Я не знаю, почему авторы Unity не выбрали для этой цели Haskell или Rust, но, вероятно, у них были на это причины. Возможно, эти причины носят социальный характер. Вероятно, за пределами proof of concept проектов всё уже не так просто, другого объяснения у меня нет. Ну или все вокруг идиоты и не лечатся.
А иметь несколько разных кодовых баз — это всё ещё кроссплатформенная разработка или уже нет?
Да неважно, как для себя решите, так и считайте. Чем больше удастся переиспользовать, тем лучше. А всё переиспользовать всё равно не удастся. Вас же не смущает, что для каждого человеческого языка идёт отдельный файл локализации. That's life. Даже в Java есть проблемы с правами к доступа к файлам и правилам именования, например, т.к. эта система в Win и *nix работает по-разному.
, если разные платформы предоставляют более-менее одни и те же фичи.
Вот всё в эти "более-менее" и упирается. Зачем человечеству разные платформы, если фичи одни и те же? Выбираем исходя из отличий, а не из сходств...
Вы так говорите, как будто это что-то плохое или как будто это делает такую альтернативу менее честной и менее предпочтительной.
Не, я так не считаю, конечно. Более того, именно так и рассуждали авторы Java или .NET CLR.
не подтверждает их представленность в Комитете. Короче, опять подмена тезиса.
Тезис в том, что фичи C++ не всем нужны. Если они вам не нужны, вы не пользуетесь C++ и не участвуете в Комитете, логично. Это, безусловно, делает Комитет пузырём, но мы тут сравниваем размеры пузырей, а не сам факт пузыристости.
то лично я бы ответил, что у узкого круга любителей хаскеля получается лучше, чем у широкого круга любителей в Комитете C++.
Да ради бога, в чём спор? У нас есть рациональные аргументы, которые мы можем вытаскивать как карты из колоды на стол до бесконечности. А есть эмпирическая реальность, разложить по полочкам которую слишком сложно, не погружаясь в детали, но хотя бы можно её описать.
Вернёмся к примеру Unity. Базовый язык там C#, и изначально кроссплатформенность работала путём компиляции в IL и запуске под Mono на каждой поддерживаемой платформе, живи радуйся. Теперь же обычно исходят из того, что рано или поздно всё равно придется переключиться на IL2CPP бэкэнд по тем или иным причинам. Аналогично, я не готов выкатить список причин того, почему что-то не делается на Хаскелле, хотя могло бы, но, видимо, проверять эти причины на своей шкуре широкие массы разработчиков не готовы.
Вы считаете, что объективных причин тому нет, а всё упирается в косность и консерватизм? Возможно. Но доказать или опровергнуть это даже не знаю как.
В языках помоложе порог вхождения ниже, но и чего-то неизбежно не хватает.
7 лет уже на Elixir пишу backend и даже не могу придумать, чего там может не хватать.
Разве что места в Top-10 рейтинга самых популярных языков)
Ну вы ж понимаете, это аргумент, с которым сложно спорить. Чак Мур пишет, что ему языка FORTH хватает на всё про всё уже несколько десятков лет. Видимо, всё же есть нюансы.
FORTH не назвать языком помоложе)
А так по факту, программируя на Elixir, можно ужаснуться, как другие языки с трудом внедряют то, что тебе уже многие годы доступно из коробки. Типа pattern matching, который в сильно урезанном виде запихивают сейчас во все mainstream-языки. Или вытесняющая многозадачность для легковесных процессов, которую недавно наконец добавили в Go.
А вот чего в mainstream пока не завезли вообще ни в каком виде, так это:
изолированные области памяти для легковесных процессов (до сих пор у всех одна большая куча на все потоки)
метапрограммирование на базе AST
pipe-оператор
Глядишь ещё лет через 10-20, mainstream дойдёт до такой роскоши.
А что у вас в качестве IDE? Уже много лет присматриваюсь к Elixir, но хочется как-то прямо чтоб с комфортом)
Да тоже самое, что и в большинстве языков - есть реализация LSP, которая прикручивается куда угодно через готовые плагины.
Для фанатов IntelliJ тоже плагин есть: https://github.com/KronicDeth/intellij-elixir
Странно что никто не говорит того же о питоне, который на 5 лет старше Джава, и такой зоопарк разных подходов, что приходится изучать питон и все сопутствующие инструменты чтобы просто пользоваться продуктами на питоне.
Я не программирую на питон, но когда очередная штука на питоне не работает ни по инструкции, ни перебором минорных версий питона, приходится все же запускать в дебагере и пытаться понять как же её запустить ) а иногда даже писать автору, потому что не хватает знаний понять баг это или ты просто не умеешь его готовить.
Как раз не странно: дело в том, что Python - высокоуровневый язык, не компилируемый и вообще почти как бейсик, поэтому те, кого не устраивает Python, просто быстро уходят на что-нибудь другое. У Python все преимущества языка синтаксические, а технических нет. Более того, очень многие компоненты Python написаны не на самом Python, а на других языках, и я не про компилятор. Всякие NumPy и иже с ними. Python по построению не универсален, даже при написании просто математики без всякого доступа к железу и системных вызовов используются библиотеки, написанные не на Python.
Напротив, C и C++ до сих пор на некоторых платформах безальтернативны в том смысле, что альтернатива - ассемблер. Другие языки на них не умеют обращаться к платформе иначе, чем через написанные на C или C++ библиотеки. Приходится маяться с C, несмотря на все его недостатки.
Тем не менее для него недавно сделали и компилятор
Другие языки на них не умеют обращаться к платформе иначе, чем через написанные на C или C++ библиотеки
Тут скорее дело уровне доступа к железу. Сейчас ОС сильно ограничивает низкоуровневый прямой доступ к железу - к его нативным командам. Разрешая его только драйверам (и ядру). Поэтому при проектировании языком прикладного уровня сейчас попросту не заморачиваются над этим низкоуровневым доступам к ресурсам и командам компьютера - всё сводится к вызовам функций из готовых библиотекам уровня ядра ОС (которые и взаимодействуют с железом напрямую или через драйверы).
Дополнительный нюанс тут ещё есть организации вызова функций по адресу - там испокон веков сложилась целая чехарда из разных форматов (соглашений) этих вызовов - но на низком уровне устаканился Си формат "cdecl" - надо сказать, что он далеко не самый удачный, но вот так сложилось, что на низком уровне взаимодействия подпрограмм используется именно он. Более прикладные ЯП используют другой формат вызова - хотя, у многих ЯП это можно менять.
То же касается и работы с памятью - более прикладные ЯП имеют менеджер памяти не совместимый прослойкой уровня железа.
А ещё на низком уровне порой делают вставки кода прямо на ассемблере (язык Си это позволяет, а вот более прикладные современные ЯП сейчас уже это не позволяют делать)
Ещё важно то - что драйверы и библиотеки уровня ядра стараются писать как можно более компактными, а более прикладные ЯП сейчас тянут за собой даже в программу "Hello world" много доп библиотек и зависимостей. А ядру и драйверам ОС ещё и выделят более высокий приоритет выполнения
Поэтому работу с железом правильно выносить на уровень драйверов, которые писать на ЯП, наиболее приземлённом к уровню железа - а это Си. Но Rust с его менеджером памяти уровня компиляции тут может попробовать потеснить Си - но пока это он ещё не готов сделать.
Ещё в последнее время ЯП C# очень углубился в низкоуровневое программирование и сейчас во многом пытается тут конкурировать с ЯП С++. В C#11 уже почти не осталось проблем с низкоуровневым взаимодействием в "небезопасном" режиме. Драйверы на нём, конечно писать, наверное не стоит. А вот прослойку ПО напрямую взаимодействующую с драйверами или с ядром ОС - думаю вполне можно.
Скорее всего по тем же стопам пойдёт ЯП Kotlin Native - но пока в этом плане от сильно отстаёт от C#
Я бы не сказал, что языки C и С++ безальтернативны - как раз в области emperative native вполне живы ещё и некоторые старички, в лице различных диалектов object pascal (и даже visual basic 6), так и новички в лице rust, go, kotlin native, вот новый mojo появился (на основе синтаксиса python), и другие - сектор native не стоит на месте, но в силу развития кросс-платформенности, многопоточности, сложных GUI (сконцентрированном в прикладном уровне) сейчас тут уже нет такого высокого ажиотажа!
Но если говорить именно о системной разработке, и разработке драйверов - то да - тут пока С и C++ безальтернативны - и подвинуть их тут будет очень сложно - в силу достаточно узкой области применения, высокой консервативности разработчиков в ней и фактическая высокая сложность писать кросс-платформенные, многопоточные приложения, со красивым современным GUI, (независимо от ЯП, а зависимо от низкоуровневых аппаратных возможностей и библиотек) - не даёт другим ЯП тут каким-либо весомых преимущество. Разве что Rust в его стремлении сократить число ошибок в низкоуровневой работе с памятью - но он получился достаточно сложным в освоении даже для С++ ников в первую очередь из-за высокой непохожести синтаксических и семантических подходов - переучитываться сложно и пока не понятно зачем!
Вы почти подтвердили мои слова. Вся проблема многих языков, в том числе и современных т.к. ноги растут из Си и Си-подобных языков, в их слабой эргономике и в ошибочном принципе построения языка. Это как в шутке мыши кололись, плакали, но продолжали есть кактус. Вот за это появилось много подколок в сторону Си. Ими попросту сложно пользоваться надо блин привыкать. Из-за этого и повышенная сложность подготовки и стоимость этой подготовки которая является определяющей в нашем мире. Поэтому как ни прискорбно Си и иже с ними со временем канет в лету или большую часть кода будет писать ИИ.
А с наследование то что не так? Это всего лишь таблица виртуальных функций. Что в ней не очевидного?
ооо - там много нюансов.
Это и конфликты при пересечении идентификаторов. И проблемы с полями. И проблемы с виртуальных функций и конструкторов. И проблемы вариантности приведения типов. И проблемы доступности членов...
Проблема замусоривания базового класса.
Если в модуле A есть несколько наследников базового класса, и в модуле B мы хотим некоего полиморфного поведения для этих наследников, мы вынуждены объявить соответствующий абстрактный метод в базовом классе в модуле A, тем самым перенося часть специфичного для B кода в A. Дальше если нам нужно полиморфное поведение для этих же классов в C, в A едет часть кода из C. В итоге имеем размытую границу между модулями и сильную связанность модулей.
Любое вменяемое решение этой проблемы сводится к имитации средств функционального программирования.
Похоже что автор оригинального текста совершенно не следит за текущими трендами, и есть намного лучше статьи, которые стоит переводить, например: https://verdagon.dev/blog/when-to-use-memory-safe-part-2
Есть очень много проектов, включая от крупных корпораций, которые работают над болячками текущих ЯП, и думаю, мы увидим ещё много чего интересного. И анализировать будущее по поисковым запросам, это вообще последнее дело, потому что профессионалы вообще могут не использовать гуглы и stack overflow, а просто читать документацию (!!!).
Пишу программу на С++, которая должна собираться и Студией и gcc. Таки о каких стандартах ви мне говорите? В них такие базовые вещи, как литерал, ведут себя по разному. std::unique_ptr пришлось по всей программе перепроверять - ведёт себя по разному. strncpy в студии агрессивно deprecated, а в gcc не имеет альтернативы, если не ставить библиотеку специально для него.
"И каждый уже десять лет учит роли, о которых лет десять как стоит забыть" -- Гребенщиков.
Так, а вы можете поподробнее рассказать об этих отличиях?
Хорошо.
Первое: Я подзабыл, что где. Суть: в одном компиляторе, если исходник в UTF-8, то и литерал будет в UTF-8 и прекрасно используется, например, в Qt. Во втором литерал будет низведён до ASCII путём замены всего остального на знаки ???. Чтобы этого не было, надо литерал начинать с флага u.
Второе: Студия позволяет писать так:
// kot.h:
class Kot {
class MyahkoyePuzo;
std::unique_ptr<MyahkoePuzo> puzo {nullptr};
}
В gcc же иногда нельзя использовать инициализатор {nullptr}
в этом месте, а иногда можно. Когда нельзя - надо очищать указатель в конструкторе. По какому фактору можно/нельзя я так и не разобрался.
Третье: Функция strcpy копирует массив байт от начала и до обеда нуля. Она старинная. С ней можно круто пролететь, если злоумышленник умудрится подсунуть в неё строку, не кончающуюся нулём. Тогда функция радостно сделает дамп памяти программы до ближайшего нуля. Поэтому Студия подсвечивает ворнингом каждое использование данной функции, и говорит заменить на изобретённую M$-ом функцию strncpy, которая умеет принимать органичение по длинне. А в gcc нет strncpy, есть только strlcpy, да и тот в библиотеке совместимости с BSD которая по умолчанию не стоит.
100 джунов учат Pythoin по ютюбу и гуглу
Три С программера пишут драйвер для девайса
Два сеньор бэкендера делают серьезную многопоточную систему на Java
Вот вам и вышеприведенные результаты популярности в поисковиках
Суета сует
Критерий стравнения язиков программирования по "энергетической эффективности", это более чем странный критерий сравнения. Тем более, что получить количественвенную оценку языка вряд ли получится. (можно оценить конкретное решение, но это будет оценка алгоритма, но не самого языка)
Да и не только энергетическая эффективность. Для многих языков ( Perl, PHP, JavaScript ) задача "нарисовать фрактал Мандельброта в bmp файл" выглядит… странновато. А, например, задача "одновременный вcтречный запрос из симметричных потоков" — так вообще невыполнима (классические JavaScript и Python)
Я бы напомнил некоторые мысли.
Мысль #1: Производительность -это не характеристика языка программирования, а характеристика конкретного приложения, написанного конкретным человеком. Это существенная метрика, но не единственная и не всегда самая важная.
Мысль #2: Языки программирования служат для общения между программистами. И тут мысль #3 играет существенную роль.
Мысль #3: Популярность языков программирования содержит иррациональную составляющую. Я бы назвал это модой.
Мысль #4: Оценить долгосрочные перспективы в таких обстоятельствах затруднительно.
1) Язык программирования - инструмент. Каждый инструмент лучше подходит для своей задачи. Когда требуется производительный код, то инструмент нужно подбирать соответствующий.
2) Языки программирования служат в первую очередь для общения между программистом и машиной.
3) Содержит иррациональную составляющую, но она далеко не самая определяющая. Есть еще заложенные при проектировании свойства и поддержка крупных компаний.
4) Предсказание будущего вообще занятие крайне неблагодарное.
Рассуждения о будущем языке программирования на примере анализа языков программирования из прошлого (ну тут только Swift, Kortlin TypeScript, Dart и с натяжкой Go можно считать современными ЯП - остальные - это всё уже старье - даже Rust - хотя да, пожалуй его сбрасывать со счетов пока не стоит - в силу оригинальной модели управления памятью - но, я всё-таки склонен считать его проходным языком - эдаким первопроходцем нового подхода - и за ним придёт другой похожий ЯП, а то и не один). Но если здраво судить - то все причисленные мной выше ЯП - это всё примерно об одном и том же - семейства императивных языков программирования, с единой базой с корнями растущим из языка Си (и немного из Pascal), и просто построенные на разных механизмах управления памятью. Немного особняком стоит только Python (хотя это уже достаточно старый ЯП, но популярность у него резко возросла лишь в последние десятилетие) - может быть в этом (в изяществе и простоте его достаточно современно синтаксиса и хорошей системе библиотек) и заключается текущая популярность ЯП. Но.... его кросс-платформенность, скорее кросс-применимость пока очень ограничены, что не позволяет ему претендовать на место главного ЯП XXI века, и мне кажется, эти ограничения так и останутся - тут сильно мешает отуствие строгой типизации (хотя через декораторы её и можно ОЧЕНЬ НЕУДОБНО делать - но в целом она отсутствует) - это было и плюсом и минусом данного ЯП - с моей точки зрения сейчас это даже больше минус, сдерживающий дальнейшее развитие ЯП (по сути он уже достиг почти всего, что можно было бы достичь в его структуре); ну разве что многопоточному подходу не хватает достаточного изящества (в основном за зачёт легковесных квазипотоков и гетерегенной архитектуры выполнения) - что тоже очень сильно дальше будет сдерживать развитие данного ЯП в стремительно развивающейся многопоточной среде выполнения современного оборудования (но это не означает, что ЯП Python не сможет это преодолеть).
Но, всё же. Правильно-таки не пытаться смешивать друг с другом типизированные строго компилируемые ЯП и интерпретируемые (в т.ч. с виртуальной машиной) - в будущем разделение области применения этих ЯП будет только возрастать, и они заведомо буду решать разные задачи. Те блоки - где критически важна будет производительность - будут программироваться на ЯП, максимально близких к машинному коду - таких как С и C++, хотя Rust-подобные ЯП со временем могу существенно потеснить Си-подобные ЯП, т.к. при схожей сложности программирования и производительности (особенно в сравнении с С++) Rust код выходит куда более надёжным (на нетривиальных программах).
Отдельное место займут языки условно-прикладного уровня - такие как C#, Kotlin, Swift, и, вероятно, Python - с менеджером памяти разрабатывать ПО будет куда эффективнее (и достаточно надёжно), а обширные библиотеки в купе с развитыми компиляторами (трансляторами кода) дают этим ЯП хороший задел для быстрого написания относительно небольших кросс-платформенных программ и библиотек. Всего, что обладает достаточно фиксированным набором заранее определённой функциональности, требует высокой надёжности, и эффективности.
Но, всё же, ключевую роль в ЯП будущего должны занять ЯП нового поколения - 5-го, выросшего на ныне ещё плохо развитом 4-ом поколении ЯП прикладного уровня (хотя кто-то, я и в том числе к 4-том поколения как раз бы отнёс все эти выше перечисленные ЯП с расширенным управлением памяти и кросс-платформенностью: как C#, Kotlin).
Суть ЯП 5-го поколения - высокий уровень абстракции и декларирования намерений (и высокое сочетания различных парадигм программирования, так что их уже трудно будет по ним разделять). Текст на языках 5-го поколения это в большей степени декларирование того что надо сделать, а не как это надо сделать - т.е. больше по сути просто расширенное декларативное описание постановки задачи (хотя в нём может быть и много более более детальных нюансов - по необходимости, когда нужно акцентировать решение постановки задачи на применения заданных подходов; в т.ч. может применяться ограниченно и императивное, функциональное, объектное и аспектное программирование - опять же по необходимости).
После постановки задачи её уже далее будет решать, условно, искусственный интеллект, с подключённой базой наработок (знаний) - эдакий продвинутый ChatGPT, специально заточенный под решение задач определённого синтаксиса с подключёнными теми или иными пакетами базы знаний (как сервисами, вероятно за отдельную плату).
ИИ будет анализировать постановку задачи, собирать статистику из среды её применения и автоматически генерировать итоговый код (с усиленным применением готовых библиотек, которые будут создаваться, в т.ч. на ЯП более низкого уровня). Этот код будет автоматически тестироваться и и автоматически прогоняться по прикладным тестам (на реальных или условно реальных данных и профилях интерактивной работы пользователя).
Периодически такой код будет автоматически переанализироваться (по актуальной статистике его выполнения и пересобираться по необходимости - все нюансы буду автоматически отправляться в базу знаний).
Периодически сгенерированный код будет отдельно подвергаться внешнему аудиту, по результату которых в исходную постановку могут вноситься уточняющие коррективы, которые так же буду анализироваться и отправляться в базу знаний (чтобы в дальнейшем автоматически уметь их использовать).
Чтобы понять что такое ЯП 5-го поколения можно взглянуть на языки семейства SQL (или NoSQL) - это, конечно не 5-ое поколение, но идеологически они наиболее близки к нему по принципу формирования.
И да, ЯП 5-го поколения должны изначально синтаксически строиться так, чтобы код постановки задачи изначально формировался таким образом, чтобы его легко можно было подвернуть автоматический декомпозиции на предмет распределённого параллельного выполнения. Но при этом этот ЯП должен быть максимально упрощённым для выделения параллельных блоков. Более того, давать возможность (соответствующим отдельным синтаксисом) для ИИ самому решать как распараллелить указанный блок кода (ну или оставить его как есть) - тут ведь ещё ИИ будет опираться на среду выполнения - если в ней нет лишних ресурсов параллелизма, то и распараллеливать нет смысла; так же ИИ будет опираться на статистику профилирования - попробовав прогнать несколько версий кода (с разной стратегий распараллеливания) и выбрав наиболее оптимальную; более того, ИИ в динамике выполнения может менять стратеги распараллеливания. В этом вся мощь ЯП 5-го поколения - кросс-платформенности и динамическая адаптация под среду выполнения! ЯПА 5-го поколения может генерировать по одной и той же постановке задачи совершенно разный код для разных условий применения, при этом перебирая сотни разных вариантов его исполнения, ориентируясь на конкретную статистику реальной среды приложения.
Само собой ЯП 5-го поколения будет и создавать подробный аналитический фидбэк программисту, по анализу поставной кода и анализу его выполнения (в т.ч. предлагаю внести правки в исходную постановку - если узрит там какие-то проблемы; при этом заранее эти правки ИИ сможет опробовать прогнав тесты и собрав статистку, чтобы не быть голословным).
Вот таким должен быть язык программирования будущего - но, это скорее уже вторая половина XXI века, хотя по сути, в предлагаемой идеи нет ничего того, что нельзя было бы сделать уже сейчас - но всё в совокупности, включая натаскивание базы знаний, требует достаточно много ресурсов на разработку, и несёт в себе много революционных концепций в структуре организации как программирования так и дальнейшего практического применения.
А Вы тут заладили Rust или Python буду языками программирования.... и те и другие будут - но у них будет своя ниша, а над ними появится куда более продвинутый ЯП, на котором в основном и будут решать прикладные задачи!
Prolog умер мертворожденным.
Императивность для актуального языка — обязательна. Т.к. подавляющее большинство решаемых элементарных задач (возьми то, сделай с ним это, положи сюда) — императивны. Реальность "императивна"! (хотя и не все религии/космологические модели с этим согласятся)
Prolog умер мертворожденным
Пролог безусловно декларативный ЯП, но я заведомо не стал его приводить, так как он по сути однопарадигменный ЯП - логический - а я сразу объявил, что ЯП 5-го поколения должен быть непросто мультипарадигменным, а в нём явно не должно быть ярковыраженной ориентированности на какую-то одну парадигму. Усоовно он должен быть настолько же императивным, насколько и функциональным, но не только. И логические конструкции а-ля пролог в нём вполне себе тоже могут иметь место быть
Реальность "императивна"!
Я бы с Вами поспорил - но мне лень (хоть я и бесспорный адепт именно императивного программирования). Просто императивное программирование втундычевают со школьных азов и оно сейчас наиболее распространено в практически применении. Да и императивные ЯП на данный момент более изящны синтаксически. Но это не более чем сложившаяся условность. Да и сейчас эпохи гибридизации. Так что на том же F# можно создавать программы не хуже чем на C# (хоть стиль и не будет чисто функциональным, как и на том же C# современный синтаксис, со времён появления лямбд, уже далёк от чисто императивного).
Но вот SQL - это более императивный ЯП или функциональный? Хотя бы классический ANSI диалект
SQL - декларативный, т.е вид языковой конструкции не определяет очерёдность выполнения её инструкций, а просто описывает что вы хотите получить в итоге
Так я и ставлю SQL как пример декларативного ЯП (хоть и не 5-го поколения, хотя вроде бы как SQL сейчас относят к языкам программирования 4-го поколения).
Но в конце своего комментария я спросил: SQL больше императивный или функциональный (ведь ЯП может быть декларативным, но при этом иметь черты другой парадигмы) - но это скорее стёб, чем вопрос, требующий ответа
От порядка вызова функций в аргументах, и от их значений порядок инструкций в f не изменится, так что нет. Не делает.
Более того как бы компилятор это не наоптимизировал, при каждом запуске бинарника поведение будет таким же, т. е детерменированным.
отвечу так - для декларативного ЯП 5-го поколения эта очерёдность не должна иметь никакой роли! Функции не должны иметь побочных эффектов. Но если такие функции (с соответствующей пометкой) будут иметь побочные эффекты то компилятор должен чётко определить - есть ли взаимный эффект (есть ли хоть один шанс того, что перестановка местами функций изменит результат) - если такое возможно с ненулевой строго математической вероятностью - то такой код не должен компилироваться, и сразу должен быть предложены варианты рефакторинга, для достижение явной определённости последовательности выбора (в т.ч. и вариант с хинтами - декорированием вызова функций-аргументов атрибутами с явным порядок вычисления). Но допустим и вариант, когда в данном файле/модуле/приложении будет явным образом задан атрибут указующий компилятору на порядок вычисления функций при выявлении такой неоднозначности с побочными эффектами. Но вообще таких ситуаций алгоритмах на ЯП 5-го поколения практически не должно быть - всё-таки функции должны быть без побочек. Изменения состояний - это уже должны быть "скажем" команды (ну я себе так это представляю) - которые не должны в своём синтаксисе применения иметь неоднозначной последовательности вызова, либо явно должно быть программистом указано - что последовательность вызова не имеет значения. А так в общем случае декларативный язык программирования 5-го поколения, как уже написал ранее, должен осознанно и оптимально стремиться к распараллеливанию выполнения - и в указанном Вами примере если функции без пробочки, допускающей взаимное влияние - то они вообще могут быть выполнены в параллельных потоках (если оценка эффективности такой реализации будет выше, чем последовательное выполнение). И как уже сказал ранее - компилятор может по-разному принимать такое решение в разных конкретных ситуациях и даже динамически потом перекомпилировать код. Да что там перекомпилировать - в относительно простых случаях ветвления реализаций алгоритма при отсутствии явных перекосов в преимущество какой-то конкретной реализации - компилятор может сразу сгенерировать все варианты (если их не очень много) и все строить в исполняемый код, а потом в динамике отслеживать и оценивать эффективность каждого их них и динамически переключаться исполнение на наиболее эффективный для данного случая - в основном этот выбор может завесеть от каких-либо входных данных (например от их объёма) и текущих условий исполнения (например от нагрузки на менеджер потоков). Это и есть ключевое преимущество ЯП 5-го поколения. Мало кто даже из гуру программистов будет стараться писать такой вот код с несколькими вариантами выполнения (хотя да - в редких случаях, требующих особой оптимизации такое делают - но уж очень не часто, а компилятор автоматически такое может делать достаточно часто - ему это как "раз плюнуть", и даже "не раз, а много раз")
Если сделать язык декларативным и с высоким уровнем абстракции (а я вас удивлю, но такие языки создавались уже лет пятьдесят и более назад), то я гарантирую вам, что появятся сотни мануалов и статей в гугле, как заставить программу выполняться определенным образом - сиречь, КАК программа должна выполняться. Да-да, императивное программирование.
Любая декларативность в языке приводит к тому, что необходимо знать, КАК будет выполняться вычисления и КАК заставить "декларативную" программу выполняться определенным образом. Любые декларативные фишки порождают необходимость иметь специалистов, которые знают, как система рабоает под капотом. Любимые вопросы на собеседованиях - КАК работает система, которая есть "декларативная" и как заставить ее считать определенным образом.
Спринг - декларативная. Любимый вопрос на собеседованиях - как работает под капотом этот спринг.
Все классы коллекций что в Джаве что в Шарпе - основное стремление сделать программирование декларативным, и основной вопрос - КАК работает хеш-мап Джаве, к примеру.
Джава-аннотации - декларативные. Вопрос - как они работаю? Как заставить их работать нужным образом?
Стримы - та-же фигня. Как написать так, чтобы работало наиболее эффективным образом?
Попишите пет-проекты на Прологе и вы шарахаться будете от декларативного программирования.
(а я вас удивлю, но такие языки создавались уже лет пятьдесят и более назад)
Я и не утверждал иного (хотя если у Вас есть примеры таких ЯП, я бы бы рад, если бы Вы поделились). Я просто прогнозирую, что именно таков будет ЯП будущего. Но 5-е поколение ему придаёт ИИ анализ, динамическая база знаний и динамическая пересборка под динамически меняющуюся среду выполнения и накопленную статистику.
Ну а высокий уровень абстрагирования и готовности к параллелизму тоже должны быть поставлены во главу угла - ЯП должен сразу под это проектироваться, но при этом оставаться достаточно простым в освоении (хотя бы поэтапно).
как заставить программу выполняться определенным образом
На первых порах таковое вполне может быть. Но тут во вторую главу угла должна ставиться идея адаптируемости, как самого ЯП (в его развитии), так и умного смарт компилятора - чтобы свести такие ситуации к минимуму. Ведь в итоге должна получиться не просто "тупая" обёртка фреймворка по трансляции одного API в другой (на примере нынешних ORM DB, или трансляции, скажем TypeScript в JavaScript) - это должна быть аналитическая система с глубоким смысловым анализатором, которая условно "реально" должна понимать, что от неё хотят и осмысленно обращаться к базе знаний за поиском подходящих паттернов решений тех или иных подзадач. И тут очень много будет зависит от качества входного синтаксиса API и качества соответвующей ему системы знаний. Ну а почти все шероховатости, когда будет требоваться тонкая настройка как раз должны со временем нивелироваться пополнением этой базы знаний или модификацией синтаксиса входного API.
А в остальном - уж лучше ИИ транслятор скажет программисту где и в чём он его не до конца понял (по возможности сразу предложив несколько вариантов интерпретации, с необходимыми поправками-уточнениями для исходного кода - программисту, в общем случае, просто нужно будет одним кликом выбрать нужный вариант), чем будет генерировать какой-то популярный, но не верный для текущего случая код.
Причём анализ можно делать прямо в процессе набора кода - учитывая и предыдущий код и стиль программирования данного программиста - заранее предлагать сделать те или иные уточнения, которые программист может принимать или отвергать - и это всё тоже будет сохраняться в персональный профиль программиста и конкретного проекта. По сути таким путём уже работают AI-помощники по набору кода - тот же Copilot - думаю именно из них далее и будет вырастать прогнозируемая мной система декларативного программирования - все предпосылки уже есть.
Любая декларативность в языке приводит к тому, что необходимо знать, КАК будет выполняться вычисления и КАК заставить "декларативную" программу выполняться определенным образом
Вот этого как раз принципиально хотелось бы избежать (хотя я тут сам себе буду сейчас противоречить). Это ключевая цель - написанная исходная логика должна быть асимптотически блико 100% однозначной к получаемому результату. Если есть заметное противоречие - то ИИ компилятор сразу об этом должен доложить. Но это не означает одно единственное решение - только один результат - а вот множество решений может выбирать компилятор (из описанных мной ранее соображений). Но программист исходя из своих соображений может его особыми синтаксическими хинтами ограничивать в этом выборе или задавать повышенные весовые приоритеты для каких-то стратегий - вот тут да - уже нужно будет разбираться в том, какие решения могут быть на выходе и почему одни неочевидно могут быть лучше других. Но это не обязательно делать рядовому программисту - такое углубление - это рост квалификации программиста. Зачастую, как выше писал, уже уровень внешнего аудита - с привлечение особых специалистов; либо для особых случаев да - при приёме на работу сразу нужно будет предъявлять такие требования. Как выше написал - ИИ трансляция тут должна быть полностью прозрачная для анализа (можно даже готовить особый отладочный результирующий код - чтобы его проще было анализировать для понимания выбранной ИИ стратегии решения).
Спринг - декларативная. Любимый вопрос на собеседованиях - как работает под капотом этот спринг.
По идеи этот вопрос должен быть не уместным в такой формулировке для ЯП 5-го уровня. Так как система подразумевает динамическую адаптацию под условия выполнения. И, во-первых, сама должна выбирать наиболее оптимальные пути решения (чтобы программисту не пришлось углубляться), либо - программист "условно не должен знать" как оно работает, но должен уметь это выяснить на конкретном примере и системе исполнения. И уметь заставить ИИ сгенерировать другие решения, оценить их производительность, и уметь задать хинты для выбора нужного вида решения. Но тут нет ничего трансцендентного. Но это уже требования к программисту определённого уровня квалификации (скорее по алгоритмам той или иной прикладной области - т.е. по стратегиям решений, а не по тому как работает ЯП с ИИ компиляцией) - это лишь подчёркивает то, что роль квалификации программистов с приходом ЯП 5-го уровня по-прежнему будет важна, но вот мат ожидание этой квалификации будет больше смещаться в меньшую сторону т.к. со временем ИИ и без такого анализа научится сам подбирать наиболее оптимальный алгоритм персонально для каждого отдельного случая применения. А для остального - будет проводиться плановый периодический сторонний аудит с приглашением более продвинутых программистов-аналитиков. В итоге на рядовом исполнении будет заметная экономия на специалистах.
основной вопрос - КАК работает хеш-мап Джаве, к примеру.
Для ЯП 5-го поколения таковой вопрос тоже навряд ли должен быть уместным (если от программиста, как написал выше, не требуется глубокое понимание готового кода, хотя хоть какое-то - требоваться должно). Для исходного API скорее коллекции должны быть разделены только по функциональному признаку, чем по вопросам оптимизации. Это уже ИИ компилятор должен сам решить какая в итоге фактическая реализация будет более оптимальной. А при анализе кода выдавать статистический профайлинг - где будет видно сколько времени уходит на те или иные операции - а если тут же будут предложены другие варианты реализации (с таким же профайлингном) - то программисту и без деталей в реализации фактических коллекций будет видно что и где быстрее или медленнее - и если надо, он сможет хинтами пометить коллекцию в исходном коде - как предпочитающую ту или иную реализацию. Но со временем в динамике ситуация может измениться и ИИ может дополнительно рапортовать обратной связью программисту о возникшей потенциальном просадке производительности в таком захинтованном коде - он сможет провести повторный анализ и может выбрать другую коллекцию или убрать лишний хинт, дав ИИ больше свободы (тем более, с уже куда более широкой накопленной статистикой реального приложения, и с паттернами из базы знаний)
Джава-аннотации - декларативные. Вопрос - как они работаю? Как заставить их работать нужным образом?
Это вообще не надо сюда приплетать. Java не декларативный ЯП, без ИИ анализа - это как сравнивать телегу из каменного века и современный автомобиль с автопилотом. Вроде бы колёса и там и там есть, вроде бы едет - а делает всё по-разному и с разной степенью свободы. Впрочем современные автомобильные автопилоты ещё тоже не доросли до "условно" 5-го поколения ЯП (по поколениям развития автопилотов у них вроде бы 2-3-тье поколение: продолжительное автономное вождение, под чётким контролем водителя; но даже в таком случае водителю же не требуется разбираться в том как принимает те или иные решение ИИ автопилота, но правила вождения пока знать надо; на 5-уровне ИИ автопилот будет полностью автономным, хотя я бы всё-таки поставил это на 6-ой уровень, а тогда будет чёткое соответствие с развитым ИИ 5-го поколения и 5-ым уровнем автономного вождения(ныне 4-й): полный автопилот при определённых условиях и размеченной дороге).
Попишите пет-проекты на Прологе и вы шарахаться будете от декларативного программирования.
Спасибо. В институте уже проходил, и даже потом курсовую писал на тему "Экспертной системы" совсем не на прологе (ну это уже другой курс и другая тема были, там ЯП не ограничивали), а на императивном языке (хот я многие писали, кстати, на функциональном, а кто-то и на прологе).
Я совсем не такой декларативный ЯП имею в виду. Напротив, его синтаксис должен быть достаточно свободным. Вот тот же SQL я не зря привёл в пример. Можно же не зацикливаться на ANSI SQL а рассмотреть Transact-SQL или PL/SQL - конечно кто-то скажет что это уже во многом императивный стиль и я с этим не буду спорить. Но суть тут в другом - тут изначально идёт некий посыл того "что надо сделать", с, пока ещё возможно большой, долей того "как это сделать" - но это, всё-таки, не ЯП 5-го поколения ещё. Просто я не хочу загонять декларативный синтаксис в узкие рамки. Просто он не должен исполняться как написан - с прямой трансляцией. Он должен быть разобран ИИ транслятором, должна быть понята логика, должны быть проведены соответствующие аналитические "запросы" к базе знаний и к среде исполнения, собрана статистика, подготовлено несколько решений, проведены профилированные тесты (и тесты надёжности, которые так же должны быть автоматически подготовлены) - и только потом выбрана та или иная реализация для финальной трансляции
Коли будет угодно писать императивно - пишите, функционально - пишите - логически - пишите (в рамках широкого, но всё ;t определённого синтаксиса исходного API) - одну и ту же логику можно описать по-разному - в итоге всё-равно она будет преобразовано в какое-то более-менее единое промежуточное "логическое" дерево трансляции (или несколько вариаций деревьев).
Вот только от ООП парадигмы вряд ли тут удастся далеко уйти - всё-таки на ООП строить каркас гибридных многопарадигменных ЯП проще. И оперировать ИИ транслятору с объектами-сущностями тоже будет проще. Да и как я уже говорил в самом начале - нужно повышать уровень абстракций - а тут уже хорошо проявляется себя АОП - а оно базируется на ООП.
Но для проведения высокого уровня декомпозируемости кода (хотя бы для целей распараллеливания) нужно будет достигать высокого уровня идеологии как ООП так и функциональных подходов. Так что на привычное сейчас ООП императивное программирование такой ЯП навряд будет похож. А вот идеи из эликсира, смалтока и java spring AspectJ, могут быть очень даже востребованы
Это уже ИИ компилятор должен сам решить какая в итоге фактическая реализация будет более оптимальной
Это невозможно в общем случае, потому что определяется свойствами данных в рантайме. Ну или замените компилятор на JIT хотя бы.
свойствами данных в рантайме
Я уже несколько раз об этом написал - неужели никак не дойдёт - что ЯП 5-го поколения это ЯП с компиляцией под среду исполнения - я не говорю слово "рантайм" - чтобы не сужать все способы ибо одним рантаймом такой подход не ограничивается - но можно и в "рантайм" - и я об этом я тоже упоминал, говоря о динамической перекомпиляции. Всё условно говоря так же (но более продвинуто) как происходит с запросами в СУБД - когда строятся планы исполнения запросов. Но всё же - я больше за использование статических анализаторов и компиляторов - это первичное, динамика - это уже вторичное.
Но если говорить о статике - то не может быть такого, чтобы ПО на ЯП 5+ просто взять и запустить. Оно обязательно должно пройти процесс развёртки под среду выполнения - с её анализом и адаптации программы под неё (но, в принципе, я не исключая и запуск по дефолту - но это наврядли будет оптимально). Серьёзное ПО так не может поставляться без соответствующего базового сопровождения со стороны программистов поставщика, и последующего сопровождения со стороны программистов потребителя. Но это всё условность - думаю, со временем AI развёртка освоится так, чтобы свести такое сопровождение к минимум.
компилятор на JIT хотя бы
Чем JIT не компилятор, я это и не исключал? Но.... всё-таки каждый раз при старте всё перекомпилировать - тоже не вариант! Я за гибридизацию - компиляция при развёртке (deploy) приложения - т.е. что-то типа AOT-компиляции из промежуточного кода, но с предварительным анализом среды исполнения, с кешированием в файлах скомпилированных блоков кода. А затем периодический мониторинг: сбор статистики и профилирование - и перекомпиляция при достижении заданной вероятности улучшения отдельных блоков кода с последующим их фактическим тестированием и если улучшение статистически значимо - установкой как основновных блоков. Возможно даже "параллельная" установка нескольких разных версий одного блока и выработка критериев ветвления - при каких условиях использовать ту или иную реализацию - по сути это всё может напоминать самообучающуюся нейросеть, которая сама себя перестраивает. Это и есть AI-компиляция и исполнение - как ключевая особенность именно языков программирования 5-го поколения.
Мне кажется, Вы один в один переписали проспект из японского проекта "Компьютеров пятого поколения" 1980-х годов. Нет?
Про компьютеры 5-го поколения безусловно читал, и безусловно опирался на эти материалы. Развитие компьютеров всегда неуклонно связано с развитием систем управления этими компьютерами, в т.ч. языков программирования. Но информации о будущих компьютерах и языках очень и очень мало. По сути, о ЯП 5-го поколения очень нет вообще чёткого представления (про 4-ое то всё очень размыто, как и про 3-тье - есть разные мнения какие ЯП по каким признакам относить к 4-ому поколению, или оставить пока в 3-тьем или говорить о 3+ поколении - я бы вот, всякие C#, Java, Kotlin и т.п. отнёс бы к ЯП 4-го поколения - но сдвинул бы дальнейшую нумерацию на 1; тогда ЯП с AI надо уже относить к 6 поколению, в 4 - некое переходное поколения ЯП с акцентом на Low-Code (это если обобщая): тут и уже и продвинутое визуальное программирование, и всякие хитрые разметки и кодогенерация, и продвинутая помощь IDE в наборе и анализе программного кода, и декларативные замашки - хотя во многом всё это уже есть, да хоть в C# и его платформе Dot NET - тогда может и не надо ничего сдвигать - и указанные ЯП сейчас в активной стадии перехода от поколения 3++++ к 4-ому поколению без появления нового ЯП).
Сами поколения приписываются не на перёд, а постфактум - вот сформируются (и в одночасье поколения не сменяются - это длительный процесс и чем выше поколение - тем это требует существенно больше времени и сам переход всё более размытый - когда очень сложно сказать мы ещё имеем дело со старым или уже с новым поколением. Вот сейчас такой процесс и происходит с ЯП, появившимися в XXI веке - вроде бы их ещё создавали по лекалам 3-его поколения, но сейчас они уже во всю замахиваются критерии, присущие на 4-ому (хоть и нет даже чётких критериев для описания этого 4-го поколения).
А я вот - уже пытаюсь описывать язык программирования 5-го поколения - причём задаю ему вполне конкретные критерии соответствия. Ну вот такой вот я пророк фантазёр. Просто у меня есть своё виденье этого, пока ещё не очень близкого будущего (конец XXI), но оно основано на тенденциях настоящего. И в целом, я не думаю, что я предлагаю что-то уж больно трансцендентное - я не прогнозирую инструменты ИИ, которые по взмаху волшебной палочки буду делать всё - хотя нынешнее развитие ChatGPT уже многим вскружило голову, что такое будущее уже не за горами. И я считаю что в той или иной мере всё, что я прогнозирую уже можно было бы разрабатывать прямо сейчас - и где-то к середине века уже предоставить вполне революционную рабочую и достаточно продвинутую для коммерческой эксплуатации версию ЯП 5-го поколения (а до этого представляя постепенно отдельные составные блоки в виде отдельных инструментов и в разной степени развития). Но всё же - именно более-менее продвинутый и в полной мере качественно соответствующий всем критериям (хоть это и большая условность) ЯП 5-го поколения должен появиться где-то к концу XXI века, и вряд ли раньше (а то и в начале XXII века), но может появиться и существенно раньше.
Кстати, ранее о компьютерах следующего поколения говорили, что это будут уже квантовые. Но вот квантовые компьютеры придумали уже достаточно давно, но развиваются они пока очень медленно (хотя за последние лет 10 прорыв был очень значимый, но до этого буксовали очень долго, да и сейчас - это пока больше дорогая игрушка). Но квантовые компьютеры не просто сложны в построении и программировании, их очень сложно вывести в сектор массового потребления. Скорее всего они так и останутся - отдельными вспомогательными числодробилками. А основные вычисления пока так и останутся на микропроцессорах - которые перейдут к чиплетам и всё больше и больше вычислений будет уходить в распределённые облачные системы. Которые, видимо, и стоит воспринимать как компьютеры следующего поколения - когда условно рядовые вычисления будут распределяться на тысячи, десятки тысяч, сотни тысяч ядер (или APU или ещё какой термин поточнее возникнет - т.е. не только на ядрах процессора, но и на дополнительных вычислительных юнитах).
К облачной гетерогенной архитектору вычислительных систем мы уже переходим. Вот куда более интересным будет последующее поколение компьютеров - когда-то давно (следующими за квантовыми компьютерами) их называли Телепатические компьютеры - системы, которые работают на опережение, предугадывая то, что от них будут запрашивать пользователи - и сразу выдавать уже готовые результаты. Таким компьютерами понадобятся, вероятно, ещё более продвинутые ЯП уже 6-го поколения, где формирование программы будет идти по такому же принципу - система будет стараться, с близкой к 100% точностью, угадать, какая задача перед ней ставится, как её эффективно выполнить, и наперёд будет предлагать пути решения, с готовыми результатами и всевозможными оценками эффективности. Но это уже совсем другая история... навряд-ли она случится даже в XXII веке, хотя, кто знает....
И 6-е поколение ЯП, скорее всего, станет уже последним (или предпоследним) - далее развивать программирование уже не будет смысла - компьютеры уже всё настолько освоят, что научатся взаимодействовать как с людьми, так и с друг другом, так и с окружающим миров без каких-то человеко-удобных программ. Но это уже прогноз на несколько столетий вперёд - скептический или наоборот недальновидный прогноз - это лишь покажет время....
В python типизация строгая. Другое дело, что она динамическая. Хоть это и интерпретатор. Нестрогая типизация присутствует в С. Который как раз компилятор.
нужен новый параметр скорость работы программиста :-)
по этому параметру выйграют:
1. 1С Предприятие
2. Python (подходит только для маленьких скриптов)
3. Golang
У пунктов (1) и (2) есть большие ограничения использования,
поэтому выйграет пункт (3) Golang :-)
Хм... критерий правильный (с уточнением - при требовании к высоконадёжному коду), но на мой ваши примеры всё-таки не очень верны:
1С Предприятие 8 - по большей части это не столько ЯП, сколько фреймворк (такой комплексный - содержащий и среду исполнения к различным платформам). Вот только уж больно ограниченный (по функциональности - уловно с большими трудностями по рашиоению функциональных возможностей и интеграции) - да, ля ряда задач подходит хорошо (особенно базирующихся на кроссплатформенном UI но если не требуются какие-то хитрые изыски и анимация - увы UI тут уже сильно устарел и не расширяется никак, кроме как через переход на JavaScript с полным отказом от внутренней реализации), но наш влево-шаг в право - и будут большие проблемы! А Сам ЯП устарел лет на 10 как минимум (а то и на все 20), современные паттерны и тенденции в разработке к 1С Предприятие почти не применимы - значит его эффективность уже весьма сомнительна. Как и есть проблемы с надёжностью и масштабируемостью. В общем - это своё болото. Как мне кажется - большой выигрышь будет только на малых и средних проектах (и тут всё зависит от того насколько они попадут в прокрустово ложе ограничений). На больших - будет полный аутсайдинг. Про BigData и говорить нечего. Ну и применение 1С Предприятие 8 сопряжено с большими расходами на лицензирование платформы - что перекрывает очень большую сферу возможностей его применения!
Python - очень даже активно применяется далеко не на маленьких скриптах - сейчас ЯП (и его среда исполнения) развился очень сильно, и активно занимает как раз область серьёзного алгоритмического анализа данных. Но тут на руку играет хорошая интеграция с Си библиотеками и хорошие фремйорки. Недотки тут больше в области пользовательского взаимодействия. Тут даже на Бигдата уже давно замахиваются. Но в качестве более широкого прикладного применения Python пока не очень широко развит (хоть и стал самым популярным ЯП) - даже в игрушках, где он ранее практически доминировал, как ЯП внутреннего скриптинга, его сейчас активно повыжимали (тот же ЯП Lua или JavaScrtipt)
Golang - на мой взгляд ну уж больно синтаксически корявый ЯП, опять же с рядом ограниченных возможностей применения. Но это лишь моё личное мнение. Он ещё как-то может конкурировать с JavaScipt (Node.js) и c Java EE - в качестве ЯП для основы микросервисов. Но не более того. И уж тем более сомнительно выглядит скорость разработки на данном ЯП (вне указанного сценария). пользовательский UI Golang - это опять печалька.
В лидерах по скорости разработки пока Python, JavaScript и, наверное Java или C#. Но Kotlin стремится потеснить как-минимум JavaScript и Java. Микросервисы, я бы всё-таки не стал разрабатывать на Golang - а если бы и стал - то только API - далее уже переходил бы к библиотекам на более вразумительных ЯП - лично мне нравится C# и Коtlin, но и Python с его специфическими библиотеками списывать со счетов не стоит. Для критично высокоскоростных вычислений - писать библиотеки на C/C++/Rust ТОЛЬКО по реальной необходимости! Хотя со временем, может и Native Kotlin тут сможет потеснить (хотя вряд ли)
Измерение сферического коня вакуумным интерферометром.
Интересно, если бы энергоэффективность учитывала количество энергии затраченной мозгом для написания бенчмарков, то как бы выглядели таблицы? А если бы время было бы временем написания всех бенчмарков? Почему в исследовании языков игнорируются значимые для бизнеса свойства технологий? Тайм ту маркет, стоимость рабочей силы, обьем задач которые можно решить на условную 1000$ вложенную в зарплаты?
Очень круто написано, мне понравилась точка зрения в статье. А споры на тему языков всегда были и остаются, тут уже ничего не поделать.
Rust нов лишь на фоне C и C++. Он вышел в июле 2010 года
Rust 2010 года практически не имеет ничего общего с тем, что есть сейчас. И даже сейчас, когда есть три редакции (2015, 2018 и 2022) и стабильно обновляющийся стабильный релиз 1.x, Rust всё ещё не является вполне законченным языком и существенное количество базовых вещей в стабильной ветке существует только в виде временных затычек (например macro-by-example), многие нишевые, но жизненно необходимые фичи есть только в nightly (например bare metal приложения).
Язык(и) программирования будущего