БудДен писал(а): ↑05.01.21 21:42
ситуации неопределённого поведения. Например, в Go постановлено, что неинициализированные переменные забиты нулями. В других языках (к сожалению, и в Обероне) они забиты мусором. Соответственно, в голанге такой класс ошибок, как "мусор в памяти" возникнуть либо не может, либо нужны какие-то особые условия для его возникновения. Самый крайний пример - это арифметика. Поскольку в Си не заданы ни размеры в прошлом популярных типов, таких как int, ни поведение при переполнении, сложно написать даже калькулятор. В той же Java заданы и размеры типов, и правила поведения при переполнении.
Потому, как принудительная инициализация по стандарту тратит исполнительное время приложения впустую. Особенно, если, скажем, структура создаётся как буфер, а потому после инициализации предстоит побайтовое копирование данных в неё. Насколько это влияет на скорость исполнения, могу сказать как в недавнем прошлом разработчик ГИС. Влияет, и ещё как. Мешает проходить временной норматив обработки, заложенный в ТЗ.
БудДен писал(а): ↑05.01.21 21:42
сила типизации. В Си привычно используется void *, некоторые вещи без него сделать просто нельзя. Возникает целый класс ошибок. В Голенге этого нет. В Обероне, в общем-то тоже очень мало, хотя фактически в реализациях оберона зачастую это есть.
Универсальный указатель — проблема? Это тогда надо менять архитектуру самих ЭВМ, чтобы избавиться от его применения.
БудДен писал(а): ↑05.01.21 21:42
перегрузка операций. Всем известна проблема JavaScript, что "2"+2="22". Перегрузка операций, или просто чрезмерно гибкое определение операций снижает надёжность языка, поскольку она обезоруживает статическую типизацию, об этом написано и в учебниках
Перегрузка операторов — великая способность языков, без которой ими невозможно адекватно пользоваться. Не стоит их примешивать к "динамическим типам".
БудДен писал(а): ↑05.01.21 21:42
адресная арифметика и указатели. В Си, по сути дела, нет массивов. Там есть указатели. Массивы возникают уже на уровне логики программы. Значит, нет способа гарантированно защититься от выхода за пределы массива т.п. В Обероне есть массивы, поэтому там категорически менее вероятна ошибка выхода за пределы массива.
Т.е., контейнеры массивов запихнули в парадигму языка, лишив программиста права на свободное приведение типа этого указателя. "Замечательно"...
БудДен писал(а): ↑05.01.21 21:42
автоматическое управление памятью. Недаром Basic, Python, Java и Go нашли своё место под солнцем - благодаря сборке мусора они резко снижают проблемы с висячими указателями.
И благодаря этой же "сборке мусора" мне приходится минимум раз в неделю перезагружать коммуникатор. Не зря старательно обхожу стороной языки программирования с этим чудовищным механизмом. К тому же, если сборщик мусора — такая замечательная идея, так почему же тогда "не взлетел" язык D? Уж насколько гибкая и красивая парадигма, а сообщество его на заметило. Может дело не в сборщике мусора, а в количестве вливаемых денег в "раскрутку" языка?
БудДен писал(а): ↑05.01.21 21:42
примитивы синхронизации. Некоторые из них, как утверждается, более надёжны, чем другие, хотя тут я не рискну особо выступать
Они просто имеют разную применимость в разных ситуациях. Проблема "владения" таким примитивам свойственна вообще всем языкам.
БудДен писал(а): ↑05.01.21 21:42
мутабельность/иммутабельность. Иммутабельные данные при умеренном применении делают программу более надёжной. К сожалению, в Обероне с этим плохо.
Обычная константность. Ничего нового.
БудДен писал(а): ↑05.01.21 21:42
уровень сложности языка. Он не должен быть чрезмерным. С++ давно вышел за рамки разумного.
Смотря что называть "сложностью". Писать код в Ассемблере — тоже сложно. C++ пытаются сохранять обратно-совместимым с языком Си, что ему и вредит. Это два языка, но сообщество этого понимать не желает. А излишняя "простота" часто именуется термином "дубовость", что само по себе усложняет программирование на таком языке. Это как взять пятипальцевый аккорд шестиструнной гитары на балалайке. В C++ нет устаканенного подхода к стандартным библиотекам, это есть. Тут надо наводить порядок. Парадигма RAII в C++ мешает применять VLA в языке Си. А всё потому, что в C++ не внесли возможностей нормально работать с массивами, не убивая правила типизации. Вот такие недоработки и ведут к усложению. Зачастую "сложность" языка — это либо его ограничения, либо неспособность его понять.
БудДен писал(а): ↑05.01.21 21:42
неявное определение сущностей. В Баш есть ужасное правило, по которому любая переменная существует (его можно отменить, но на практике этим никто не пользуется).
Там не совсем так. Есть unset, который "убивает" переменную. В целом каждая переменная BASH носит строковой тип. А всё потому, что BASH — никогда не был и не становился языком программирования. Это — командный интерпретатор рабочей среды. Он лишь управляет вызовом других программ или команд. А куда большая проблема — отсутствие полноценной реализации функционала BASH в самих языках программирования. Всё, конечно, можно сделать, но где внятные стандартные библиотеки-то?