Обновить
Комментарии 592

Радоваться или бояться? А то Майкрософт, помнится, любила java и Интернет...

А с джавой или интернетом разве что-то случилось?

С джавой случился C#. И, кажется, это даже неплохо.

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

Именно благодаря C# с джавой всё хорошо. Всё дело в том, что Java очень неповоротлива в плане добавления нового функционала, а C# её расшевелил. Конкуренция всегда идёт на пользу обеим сторонам.

Так, а при чём здесь? Вы про джаву или JVM? Я не сведущ в джаве, но судя по релиз ноутам последних версий, язык, как-то не очень в последнее время развивается, сравнивая с шарпом. (Может я что-то пропустил). А вот Котлин прекрасен, здесь нечего добавить.
Вы что-то пропустили. В последнее время (после появления нового релизного цикла) java развивается очень быстро. Застой был до java 9.

Так этот цикл и ускорение выпусков и пришло в Java благодаря наличию конкуренции в лице C#.

Наверное, не только C#, но и Kotlin.
Значит пропустил. Ну, это отлично. Здоровая конкуренция еще никому не вредила.
Если бессмысленное напихивание несвязных уродливых фичей называть развитием, то да…
Если records, sealed classes, project loom, начала паттерн матчинга — это бессмысленное напихивание несвязных уродливых фичей, то да…

В общем-то именно, что да, потому что они как бы сверху приделываются бантиком, поэтому они получаются слишком частными и хрупкими.
Вот например records. Пришлось аж целое новое ключевое слово вводить, в то время как в Rust это просто частный случай обычной структуры, на которую просто добавили некоторые дополнительные derive'ы.

Да, я именно это и имею в виду, спасибо.
Sealed классы без smart cast-ов будут выглядеть уродско. Новый instanceOf тут не замена, имхо, получается ужасный код.
Лямбды имеют уродский синтаксис, да ещё и _ запрещено. И похерили проверяемые исключения.
switch-expression сделали «чтобы был», добавив отдельный кусок синтаксиса для него.

Видимо языки мейнстримные нужно как и президентов, иногда менять

> Менять
> Как президентов


Да ну, бред какой-то.


</sarcasm>

Читаю комментарий и не знаю, о шарпы Вы или о джаве)

Я не вижу проблемы в большом количестве сахара и не вижу большой проблемы в том, что код может стать короче. Разумеется, что иногда это ведёт к удару по производительности, но никто не заставляет использовать сахар. На том же шарпе, условно, можно писать как на си даже без вызовов (практически) к ГК. Главное, чтобы вы понимали, как этот сахар работает.
Более того. Если вы мего-зануда и не хотите чтобы кто-то использовал в вашем коде определённые вещи — уделите полчаса и напишите анализатор (имеется в виду выбросить ошибку или ворнинг).

Правда, для тех кто начинает сейчас только изучать шарп… это наверное катастрофа. Куча всего. Почему это можно сделать 10 разными способами?

Верно. Не скажу, что это выглядит супер… но, порой приходилось юзать.
Java в последнее время начала догонять Котлин по сахару, насколько это возможно, разумеется
и близко не стоит. Котлин продуманный язык, в отличие от.
С Java случились несовместимые расширения в Microsoft JVM. Потом суд, развод и никакой любви.
С Интернетом случился Internet Explorer.
Кто сказал, что здесь история не повторится? NIH-синдром

P.S.Кроме MS JVM еще был J#.
«Чукча — писатель, чукча не читатель». Ссылка «тухлая» — December 2, 2019
И проект «Verona» о котором вы нам по секрету поведали, то о нем Левик говорит в своем видео, которое указано. И там он говорит, что не знает статуса и планов этого эксперимента. Но Verona лежит на гитхаб-е — да.
Ссылка «тухлая» — December 2, 2019
Так это всего полгода назад.
Они по-другому никогда и не делали. Всё своё.

С java случился эпичный батл в суде, после чего Sun запретило MS делать свою JVM (которая отличалась от задаваемых Sun стандартов)… собственно тогда Sun вообще задалась вопросом более жёсткого контроля выпускаемых JVM. Впрочем я бы сказал что в данном случае это успех, а вот если бы Sun потупило ещё пару лет, то проблем в Java было бы столько же, сколько было в вебе с ie6 в эпоху chrome-ff-ie8. А так поимело проблем ограниченное количество java-девелоперов + некоторая часть кода внезапно превратилась в тыкву.

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


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

Это вы про C#? Вот там уж точно всё, как вы описали: язык придуман в Microsoft, реализаций не то одна, не то полторы, на других платформах всё грустно…

Срочно все забываем C#!

C# был официально выпущен Microsoft в комплекте со средствами разработки и фреймворками. Что выпущено ими по Rust? Предлагаете считать заявление какого-то подметайла официальной позицией Microsoft? Тогда что за язык Verona? Я запутался: что мне выбирать для проекта следующего космического корабля: Rust или Verona?

Наверное пишете с компьютера под Singularity? Когда собираетесь переходить с IronRuby на Rust?

Rust — прекрасный язык, но ИМХО проблема Микрософт далеко не в безопасности языка. Безопасный язык не поможет против удаления файлов пользователя, бесконечного цикла перезагрузок при включенном fast boot. Он бессилен против бесконечных усилий отделов по перестановке кнопочек и добавлений «крутейших новых эмодзи». Если сокращения тестов и тестировщиков продолжатся, если не будет как-то переделана политика одобрения новых релизов — язык, даже самый крутой, не поможет.

Но зато это прекрасно поможет самому расту еще больше утвирдиться а мире

А при чем тут это, если весь пост, по сути, о безопасной работе с памятью в rust и C/C++? Проблема МС тут именно в безопасности языка и их статистика CVE соответствует показателям других, у кого много C/C++ кода. Инструмент стал помехой и пришло время его сменить.
их статистика CVE соответствует показателям других
А где можно посмотреть это статистику «других»?
А то обсасывается одна цифра из одного источника, как я вижу.
Для таких вещей есть гугл
гугл (хром) www.techspot.com/news/85368-google-70-percent-serious-security-bugs-memory-safety.html
эпл langui.sh/2019/07/23/apple-memory-safety
Точно помню похожую статистику про адоб

Думаю, если покопаться в базе CVE, то можно и самому собрать такие данные по кому угодно.
НЛО прилетело и опубликовало эту надпись здесь
Теоретически — часть тестов можно убрать потому, что язык всё-таки безопасный и не допускает некоторых видов ошибок.
Однако, как Вы верно заметили — ошибок «удаление файлов пользователя» и «бесконечного цикла перезагрузок» ни один язык программирования (по кр.мере, из известных мне) устранить не может.

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

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

в которых можно доказать отсутствие такого поведения


Погодите-погодите! Вы не приведете пример, как доказать отсутствие бесконечных перезагрузок и удаления лишних файлов, случаем?
Либо все, либо ничего — обыкновенная припадочная философия © Макаренко…

Тут, знаете ли, «поля этой книги слишком узки»…

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

Но какие-то более простые вещи — вполне возможно.

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

как доказать отсутствие бесконечных перезагрузок

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


удаления лишних файлов

Тут уже сложнее, сначала надо определить, что такое лишний файл.


Естественно, всё это требует полной формализации вообще всей системы, относиться к ОС как к некоему внешнему миру, корректность которого мы принимаем за аксиому, больше не получится.

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

Отсутствие «бесконечного цикла перезагрузок» надо доказывать не для каждой отдельной программы, а для совокупности программ, запускающихся при загрузке. А это уже на порядок сложнее.
Хуже того: нигде нет гарантии, что набор программ, запускающихся при загрузке, будет нужным: м.б. так, что часть программ от новой версии, а часть от старой; или вообще каким-то образом туда влезло что-то постороннее. Как Вы понимаете, количество вариантов растёт экспоненциально, сложность доказательства становится непомерной.

Частично помогает строгая изоляция программ — когда каждая программа имеет строго свою функцию и не может сделать ничего за её пределами. Но разделение функций — это вопрос не к языку программирования, а к архитектуре. В Windows — архитектура такова, что доказать можно лишь отсутствие изоляции. Хуже того — архитектура PC-совместимого компьютера такова, что до момента загрузки ядра операционки изоляция в принципе невозможна; а реально — изоляция становится возможной существенно позже загрузки и инициализации ядра. Так что доказуемая надёжность системы на ранних этапах старта — на данный момент в принципе недостижима.
Ну и до кучи: строгая изоляция программ обязательно понижает эффективность работы.
Ну, можно доказать, что программа никогда не удаляет файлы пользователя.

Отлично, с этим критерием уже можно работать.


Если сигнатура функции удаления выглядит как что-то в духе


superCoolDelete : (path : FilePath) -> Not (UserFile path) -> Eff [Delete] ()

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


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


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

Я бы начал с того, что пользовательская программа не должна приводить к перезагрузке компьютера (в самом деле, зачем?).


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

Вопрос в том, сколько из этих вариантов на самом деле достаточно уникальны.


Так-то и количество вариантов чисел для утверждения (a + b) + c = a + (b + c), гм, большое, но доказать это свойство можно парой строк.

Я бы начал с того, что пользовательская программа не должна приводить к перезагрузке компьютера (в самом деле, зачем?).

А halt и shutdown это пользовательские программы? А когда кнопочка в «меню пуск» посылает сигнал системе о перезагрузке, это пользовательская программа? Я думаю да. Как без них то перезагрузить, питание дернуть?
В нормально организованной системе (без известных костылей) программы halt и shutdown, разумеется, не было бы пользовательскими, а были бы частью системы. А уже кнопочка выключения могла бы посылать «запрос на перезагрузку» привилигерованной части системы — и та осуществляла бы перезагрузку с учётом опрделеённых правил и гарантий.

Впрочем это всё — разговоры «в пользу бедных». Почему ваш телефон, с вероятностью 99%, поддерживает вывод данных на консоль через serial port? Потому что когда-то давно к компьютерам присоеденили телетайп, а потом… эта — работает не трогай…

Никакой язык это не изменит…
А уже кнопочка выключения могла бы посылать «запрос на перезагрузку» привилигерованной части

картошка — картофель
как не назови, сигнал или непосредственный вызов кода, а пользовательский софт инициализирует перезагрузку.
чтобы написать спецификацию ОС которая не будет косячить, надо придумать все возможные косяки.
Возьмем
superCoolDelete: (path: FilePath) -> Not (UserFile path) -> Eff [Delete] ()

*Интересное наблюдение, недавно 0xd34df00d'у скинули кусок кода, так он прокоментировал типа «я не совсем понимаю, потомучто не знаю язык», зато сам как не кусок кода, идрис, который никто не знает.
Вернемся к коду. Немножко изменим задачу, «защитить от случайного удаления файлов». Вспомним нвидиа и их скрипт который вместо
rm -rf /var/bla/bla/bla
сделал
rm -rf /var /bla/bla/bla.
От такого можно защитить? Например как? создать специальную rm1, которая примет только 1 аргумент? Больше вариантов не знаю. Но ведь чтобы это создать, надо сначала натолкнуться на такую проблему и понять что она имеет место быть.
Тут вы упираетесь в самую большую проблему любых тестов и любой типизации: вы можете защититься от известных проблем… но как защититься от неизвестных?
как не назови, сигнал или непосредственный вызов кода, а пользовательский софт инициализирует перезагрузку.

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


чтобы написать спецификацию ОС которая не будет косячить, надо придумать все возможные косяки.

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


*Интересное наблюдение, недавно 0xd34df00d'у скинули кусок кода, так он прокоментировал типа «я не совсем понимаю, потомучто не знаю язык», зато сам как не кусок кода, идрис, который никто не знает.

Извините, что не расписал подробнее, что там происходит. Я с радостью отвечу (и стараюсь отвечать) на вопросы по тому типу.


От такого можно защитить? Например как?

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

Если сигнатура функции удаления выглядит как что-то в духе
superCoolDelete : (path : FilePath) -> Not (UserFile path) -> Eff [Delete] ()

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

Я бы начал с того, что пользовательская программа не должна приводить к перезагрузке компьютера (в самом деле, зачем?).
Вообще-то, программа shutdown — вполне пользовательская.

Или вот вариант, практиковавшийся в старых Windows (в W'XP точно, в остальных я не уверен; может, и сейчас есть): В ходе загрузки было обнаружено повреждение файловой системы. После исправления сбоев — система перезагружается, загрузка стартует заново.
Аналогично — система установки обновлений в Windows после установки некоторых обновлений (видимо, тех, которые затрагивают ядро и системные процессы) перезагружает систему.

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

Так-то и количество вариантов чисел для утверждения
(a + b) + c = a + (b + c)
, гм, большое, но доказать это свойство можно парой строк.
Ну, я с радостью посмотрю доказательство. Я-то всегда считал, что это — базовая аксиома алгебры.

Описанное Вами утверждение — достаточно простое в силу простоты составляющих его элементов и малого числа элементов в утверждении. Тогда как типичные программы содержат огромное количество простых элементов.
Например, какая-то программа Икс создаёт текстовый файл; а программа Игрек запускает shell и передаёт ему этот файл в качестве скрипта. Теперь надо доказать, что в скрипте не м.б. команды удаления файла с путём юзерского каталога. Я боюсь, тут мы попадаем на нереальную задачу, ибо shell явно не входит в число языков, комплментарных к доказующим системам.

Вы абсолютно правы, произвольный скрипт на шелле типизировать трудновато (Райс не даёт). Это значит, что в такой верифицированной системе не будет шелла, или будет какой-то ограниченный типизированный шелл (как turtle, но более выразительный, скажем?).


В ходе загрузки было обнаружено повреждение файловой системы. После исправления сбоев — система перезагружается, загрузка стартует заново.

Прекрасный пример! Тут как раз такая уменьшающаяся мера очень легко придумывается: для программы исправления сбоев ФС выглядит разумным требование, что после её работы число сбоев меньше, чем до её работы (либо программа не может ничего починить, и тогда тоже можно обсудить, что делать). Тогда в предположении, что железо не сыпется и никто не тыкается паяльником в работающую машину, что-то тоже можно гарантировать.


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

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


Я-то всегда считал, что это — базовая аксиома алгебры.

Это зависит от того, что именно вы делаете.


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


Если вы определяете понятие натуральных чисел (через Пеано, например), или каких-то более сложных объектов типа целых чисел, рациональных чисел и так далее, то это снова не аксиома, а теорема, которую требуется доказать. Вероятно, можно построить не избыточную аксиоматику чисел, где это аксиома, а не доказываемая теорема, но зачем так делать, непонятно.


Ну, я с радостью посмотрю доказательство.

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


Вы можете определить натуральные числа как


data Nat : Type where
  Z : Nat
  S : Nat -> Nat

То, как работают CoC/CIC-подобные системы типов, гарантирует, что это определение эквивалентно аксиоматике Пеано (в частности, соответствующие аскиомы становятся теоремами, которые можно доказать).


Тогда операция сложения является производной операцией и определяется рекурсией, например, по первому слагаемому:


(+) : Nat -> Nat -> Nat
(+) Z y = y
(+) (S x) y = S (x + y)

Тогда доказательство ассоциативности происходит по индукции, двумя ветвями: базовый случай, когда первое слагаемое равно нулю (тогда всё тривиально из определения сложения), и индуктивный случай, когда можно воспользоваться доказанным фактом для предыдущего значения:


plusAssoc : (n, m, k : Nat) -> n + (m + k) = (n + m) + k
plusAssoc Z m k = Refl
plusAssoc (S n) m k = cong $ plusAssoc n m k

В частности, во втором случае нам нужно доказать S n + (m + k) = (S n + m) + k, что автоматически упрощается за счёт определения операции + (индукция идёт по тому же члену, по которому идёт рекурсия в операции сложения, неспроста) сначала в S (n + (m + k)) = (S (n + m)) + k, а потом в S (n + (m + k)) = S ((n + m)) + k). «Предположение индукции» даёт нам доказательство (n + (m + k)) = ((n + m) + k), а cong позволяет заключить, что если a = b, то f a = f b для любых f, a, b (применяя одну и ту же функцию к равным аргументам, мы получим равные значения).


Описанное Вами утверждение — достаточно простое в силу простоты составляющих его элементов и малого числа элементов в утверждении.

Важно, что все возможные состояния перечислять не нужно.

В интересное время мы живем, некоторые идеи стали насаждать в головы настолько агрессивное, безапелляционно и грубо.
Посмотрел на биографию Ryan Levick:
I’m a developer advocate working in Berlin, Germany. I joined Microsoft via the acquisition of Wunderlist. I’ve spent my career building apps on the server and client side and exploring a wide range of open source technologies with a particular focus on functional programming.
Skills:
* Rust, JavaScript/TypeScript, Elm, Elixir
* Functional programming
* Software architecture
* Software Education

И меня смутило несколько аспектов:
  • Он инженер, разработчик, который был включен в микрософт поглощением другой компании заявляет от лица всей микрософт что будут использовать Раст?
  • В его профиле кроме раст JavaScript/TypeScript, Elm, Elixir больше ничего нет, он действительно может что-то с чем то сравнивать?

Я понимаю, что молодому языку нужно пробивать себе дорогу в жизни, но тоньше работать надо, если людей долбить по голове будет просто секта. Если люди реально увидят пользу и захотят — будет новый С.
Например — хочу я микроконтроллер на Риск5 и раст, все что у меня есть это россыпь GitHub репозиториев, бол-во устаревший, а другие как конструкторы. Код который будет генерировать компилятор должен быть надежный, я не могу потратить время отлаживая еще и генерируемый ассемблер.
В общем что я хочу сказать текущему тренду на «вдалбливание, что раст могуч» — чтоб он действительно таковым стал уйдут годы и годы, мы состаримся, а потом он либо тихо умрет, либо так же тихо станет стандартом де-факто, но ни в 1 сценарии он не станет стандартом только потому что пользователей активно убеждают.
Я понимаю, что молодому языку нужно пробивать себе дорогу в жизни, но тоньше работать надо, если людей долбить по голове будет просто секта.

Что у нас там с сектой любителей картофеля? Картофель в России внедрялся давлением сверху, без особой тонкости, если что.


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

К чему может привести ставка на один картофель на все случаи жизни, вам могут рассказать ирландцы середины 19 века :) А вообще согласен с предыдущим оратором насчёт попыток агрессивного вдалбливания.

Здесь аналогия работает скорее не в пользу C (и классическое: картошка не при чём, это неправильные ирландцы). Но я имел в виду то, что к сектантству такие ситуации имеют мало отношения, хотя многим почему-то хочется видеть это именно так.

Ну это не я приравнял раст к картошке, а вы :) Вообще я уже давно говорю о том, что агрессивные попытки продвижения раста с помощью полуправдивых тезисов скорее отталкивают от языка, чем привлекают. Вот и в этой статье встречаются утверждения типа «но даже здесь небезопасные части заключены в безопасный API». А ведь это в лучшем случае wishful thinking, а в худшем — недобросовестная пропаганда. Если бы наружу unsafe-кода всегда торчал один только гарантированно безопасный API, то не было бы вот такого, например, или такого (и это только из свежего). Далее, в статье создается впечатление (не знаю, умышленно или нет), что статический анализ нужен только в C/C++, а в Rust достаточно одного лишь компилятора, но как-то умалчивается про утилиты типа clippy, а также про попытки реализации «более глубокой» верификации unsafe-кусков в рамках того же RustBelt, необходимость в которой, судя по вышеприведенным уязвимостям, очевидно, тоже имеется. Ну и зачем это? Складывается негативное впечатление именно такого рода, что в лице «продвигателей» раста имеешь дело с фанатиками, которые готовы при случае может и не то чтобы приврать, но тенденциозно осветить — точно. Меньше пафоса и пропаганды, и люди, может, активнее потянутся.

Ну не знаю. Если один инструмент позволяет совершить 10 ошибок на N строк кода, а другой — только 1, то очевидно нужно выбирать второй. При этом никто не говорит, что вот совсем никаких ошибок не будет, это скорее всего невозможно. Но значительно уменьшить их количество вполне реально.


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

Ну вот когда тот же Lau или я «узнают подробности», не только о плюсах, но и о минусах (ничего не дается бесплатно, те же граждане из RustBelt честно пишут, что «Unfortunately, none of Rust's safety claims have been formally investigated, and it is not at all clear that they hold. To rule out data races and other common programming errors, Rust's core type system prohibits the aliasing of mutable state, but this is too restrictive for implementing some low-level data structures», да и не только low-level тащем-та, весь дырявый unsafe-код из всех этих rustsec advisories тоже написан не от хорошей жизни, а в попытках создать что-то работающее в условиях, когда safe rust не позволяет этого сделать из-за ограничений дизайна), то как раз и создается то самое впечатление «чем больше вижу нечистоплотной рекламы, тем меньше шансов, что лично я к нему обращу свой взор».
Граждане RustBelt часть работы уже давно провели plv.mpi-sws.org/rustbelt/popl18/paper.pdf

Ну и давайте до абсурда не доводить. У нас с одной стороны есть C/C++, которые вообще ничего не дают в плане безопасности. С другой у нас есть rust, который даже без формальной верификации чисто технически способен предотвращать кучу ошибок. Мы же не требуем формальной верификации о статических анализаторов, виртуальных машин со сборщиками мусора и прочими штуками, которые мы считаем безопасным. Умозрительно нам понятно, что они достаточно безопасны. Как бы, это уже огромный шаг вперед и этого достаточно, чтобы задуматься о переходе. Формальная верификация я даже не знаю кому реально нужна, если даже ядро ОС пишут без всяких верификаций и строгих стандартов кодирования. Отрасли, где на кону жизни людей, может быть повременят, хотя даже там используются все теже С/С++, обложенные кучей костылей, чтобы сделать их безопаснее.
К сожалению, «способен предотвращать кучу ошибок», которые относятся к одному типу (
Не к одному. Раст предотвращает гонки данных, выходы за границы, висячие указатели, use-after-free и наверняка кучу еще других категорий ошибок.
Этого типа достаточно, чтобы исчезло подавляющее большинство CVE, которые обычно приводят или прямо к RCE, или повышению привилегий.
Выходы за границы, контроль указателей, use-after-free, double-free, NPE — один класс(тип) ошибок.

Гонки данных, как недавно было продемонстрировано — не предотвращает. Ну или точнее, может и предотвращает для хелловорлдов, но не на реальных применениях (где мешает дизайн Раста).
Вы что-то сами себе придумали (кстати, говоря уже далеко не первый раз). Pin там как раз и есть для того чтобы через типы запретить некорректные операции по работе с памятью во время await'ов.
Не согласен. Посмотрев исходники и советы общества — и считаю, что это работает так:
1. Pin держит для текущего потока указатель (ссылку), чтобы OB его не переместил (move, consume) или не удалил по концу лайфтайма
2. Pin через unsafe отдает сырой указатель (ссылку) другому потоку или кому угодно, что тот с ним работал. Но ОВ второго потока ни сном ни духом про соперника.

Итого это не заслуга языка, а простой костыль, аналогичный Memory.Pin в C#
1. Pin держит для текущего потока указатель (ссылку), чтобы OB его не переместил (move, consume) или не удалил по концу лайфтайма

Нет же. Pin оборачивает некий указатель на объект. Сам Pin можно перемещать, он требуется для того, чтобы через указатель нельзя было вытащить данные за указателем (при помощи, например, std::mem::swap). Это позволяет сохранять стабильный адрес объекта в памяти и, как следствие, хранить в объекте ссылки на себя.
Для неудаления в конце времени жизни тоже есть тип, но это другой тип, ManuallyDrop, и он нужен совсем для других вещей.


2. Pin через unsafe отдает сырой указатель (ссылку) другому потоку или кому угодно, что тот с ним работал. Но ОВ второго потока ни сном ни духом про соперника.

Потоки тут не при чём. Pin может отдавать мутабельную ссылку на внутренности, и эта операция unsafe из-за того, что при этом можно вытащить объект из-за ссылки и потенциально инвалидировать самоссылающиеся объекты. Временем жизни Pin никак не управляет.


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

И я про то. Pin обходит OB для содержащегося указателя (кроме умеющих в Unpin, как я понял).

Но вопрос был в том, что Раст предотвращает Датарейс, но если используем Pin — то нет.
И я про то. Pin обходит OB для содержащегося указателя (кроме умеющих в Unpin, как я понял).


Pin обходит правила владения не больше чем Box. Вы же не будите, что из-за Box в расте возникают датарейсы?
Я был неправ, но и Вы тоже. Просто у Pin есть разные специализации трейтов для &T и для &mut T.
Из документации этого не видно — но по факу Pin(&T) не умеет в as_mut().
В итоге, читая доку, я был обманут.

Итоговый результат в этом треде — Раст предотвращает гонку данных между потоками. Но цена этого — вы не можете использовать общие данные между потоками в safe Rust. Никак!

Вообще-то видно:
image


P: DerefMut означает, что можно получить мутабельную ссылку на содержимое P, что неверно, если P=&T. В этом можно убедиться, посмотрев реализации трейта DerefMut. DerefMut для &T там явно запрещён:
impl<'_, T> !DerefMut for &'_ T

Без синхронизации — действительно не можете и это хорошо. А если у вас данные Sync — шарьте сколько угодно.


Из документации этого не видно

Как же это не видно. Видите, какое ограничение на параметр P? Что-то, что может дать мутабельную ссылку. Просто для новичка возможно это не слишком очевидно, так ведь и Pin не новичкам нужен.

В документации это прекрасно видно, метод as_mut присутствует только в impl-блоке для тех P, которые реализуют DerefMut: https://doc.rust-lang.org/std/pin/struct.Pin.html#method.as_mut


Но цена этого — вы не можете использовать общие данные между потоками в safe Rust.

Это совершенно не верно. Как минимум можно использовать безопасные примитивы синхронизации. Также и без них можно шарить между потоками объект по статической ссылке.


Ну а если вы подразумеваете, что в конечном итоге все равно где-то "под капотом" будет вызываться unsafe — то да, без этого не обойдется ни одна сколь-либо значимая операция. Я не могу взять объект из Vec по индексу или проитерироваться по массиву с тем, чтобы не стриггерить какой-нибудь unsafe-код. Ну и что с того?

Ну так DerefMut реализуют все примитивы.
Это совершенно не верно. Как минимум можно использовать безопасные примитивы синхронизации. Также и без них можно шарить между потоками объект по статической ссылке.
Можно пример?
2. Pin через unsafe отдает сырой указатель (ссылку) другому потоку или кому угодно, что тот с ним работал. Но ОВ второго потока ни сном ни духом про соперника.


Ну вот опять вы придумываете.

Pin, как и другие смарт-поинтеры раста, не нарушает гарантии, которые предоставляет раст для своего safe подмножества и не передает никакие указатели в другие потоки сам по себе.

Конечно, другие потоки сами виноватые — сами попросили
    pub fn as_mut(&mut self) -> Pin<&mut P::Target> {
        // SAFETY: see documentation on this function
        unsafe { Pin::new_unchecked(&mut *self.pointer) }
    }

Кек. Если у вас на руках есть &mut-ссылка, то у вас уже заведомо доступ к Pin есть только из одного потока. Это на этапе компиляции проверяется.

Я ж этот пример из async/await принес…

И? В каждый момент времени с конкретной футурой всё равно максимум один поток работает.

Да, у меня не получилось опасно расшарить содержимое Pin на два потока — хотя он и отдает внутреннюю ссылку, но сам объект Pin под контролем ОВ.
Ну? Вы ведь даже скопировали нужный комментарий вместе с кодом. Нужно посмотреть документацию

For correctness, Pin

relies on the implementations of Deref and DerefMut not to move out of their self parameter, and only ever to return a pointer to pinned data when they are called on a pinned pointer.

Это точно полный и окончательный фикс? Я не вижу как он может предовратить имплементацию DerefMut, перемещающую self куда-нибудь. Или, например, меняющую местами две части self, которые отдаются в норме только через Pin (structured pinning это называется, кажется).

Я не вижу как он может предовратить имплементацию DerefMut


Как-то так

Вообще, вопросы, связанные с Unsoundness для Pin действительно не простые. Если вы не согласны с фиксом, то думаю, гораздо продуктивнее будет написать сразу в указанную вами issue.
Я читал доку, а там не всё.

Кстати, на моей [длинной] памяти это первый язык, нарушающий правило — хороший код — самодокументированный.

В Расте комментарии документирования превышают код втрое

Из того, что в std Rust хорошо все задокументировано, как вы делаете вывод, что код там не самодокументированный? По-вашему в дополнении к самодокументированному коду невозможно написать хорошую документацию?

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

А вот комментарии к Pin, которых я вдоволь начитался вчера, доставляют
  • Notice that this guarantee does *not* mean that memory does not leak!
  • The following implementations aren't derived in order to avoid soundness issues..
  • this method is safe because..(много повторений)
  • This constructor is unsafe because we cannot guarantee that...
  • This function is unsafe. You must guarantee...(несколько шт)
  • we just need to take care not to allow such impls to land in std

Но главное, что работает :troll:
Отрасли, где на кону жизни людей, может быть повременят, хотя даже там используются все теже С/С++, обложенные кучей костылей, чтобы сделать их безопаснее.
Нет. В ядерной энергетике и авиации используют Ada, Ravenscar profile, SPARK. С программами на С/С++ предпочитают дела не иметь.
Работаю в авиации, разрабатываю ПО по DO-178C/B на С++.
Также, например, safety-critical ПО на недавно отшумевшем Crew Dragon написано на С++. Так что, мне кажется, вы слишком категоричны.

Разве в таких случаях не используют сильно ограниченное подмножество языка, запрещают некоторые конструкции (рекурсию, бесконечные циклы) и снижают динамическое выделение памяти к абсолютному минимуму? Или для C++ какие-то из требований MISRA C можно ослабить?

Есть Misra C++, а для авиа — вообще свой стандарт (не помню). Для автопрома есть AUTOSAR, для встройки — тоже ESCR.

Конечно, это все наборы запретов.
Мед сектор, хирургия, мало-инвазивные операции — С микроконтроллепры и драйвера, С++ обвязка повыше.
С/С++ это индустриальный стандарт сейчас и уже давно.
Список CVE Microsoft
www.cvedetails.com/vulnerability-list/vendor_id-26/Microsoft.html
и список CVE в The RustSec Advisory Database
rustsec.org/advisories

как бы намекает, и на данный момент не идет ни в какое сравнение.
Ошибок «не может не быть», но если кому-то хочется их много, то это дело «хозяйское», насильно мил не будешь…
Объем кода, написанного на Rust и на всем остальном, тоже не идет ни в какое сравнение, зачем же передергивать так откровенно? Вот это и называется «попытка продвижения с помощью полуправдивых тезисов»… Не делайте так. Пока все, что можно здесь утверждать — это то, что в коде на Rust вполне себе существуют все те же самые классы ошибок, что и в коде на C/C++, просто потенциальные места их возникновения пытаются обозначить флажками, что, как видно, далеко не всегда помогает, учитывая ограниченность дизайна safe Rust и кунштюки, на которые идут (возможно, вынужденно) некоторые разработчики на Rust.

P.S. Тезис «Rust выбирают „любимой женой“ ПЯТЫЙ год подряд» тоже как бы… такой. Я, например, ни разу не голосовал там ни за какой язык, мне есть, чем заняться кроме этого, а представители пресловутой Rust Evangelism Strike Force просто более организованны и активны в этом плане, ходят строго в ногу, долбят одни и те же сомнительные тезисы из статьи в статью пополам с маркетинговым булшитом в стиле «a fundamental break in the history of technology», и что с того? Да ничего.

Ладно, не интересно, все это уже жевано-пережевано уже много раз, принимать участие в дальнейшей дискуссии на эту тему никакого желания у меня нет, я уже наперед знаю все аргументы всех сторон :)
ограниченность дизайна safe Rust

Для обеспечения доказуемой корректности программы можно или ограничить возможности языка или обязать программиста писать доказательства вручную. В Rust выбрали первый вариант. Вряд ли это можно назвать ограничением дизайна языка.


Есть ограничения текущей реализации borrow checker, которая не пропускает некоторые корректные программы, это — да.

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

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

Передергивание — это высказанное тут, «да я помню как в 90-х агрессивно толкали java, а сейчас еще похлеще...». Я начал с Явой в 2000-2001 тогда и интернет был — так себе, не то что сейчас, так чтобы «агрессивно рекламировать» (как утверждается в комментах) было не очень то и легко. И поднялась Java в основном на адаптации в сервер-сайд-е.

Вот тут не то что передергивание, а откровенное вранье — кто ж там вас проверит как было в 90-х?? В 1995 — FIDO net был еще вполне живой и бодрый, я то помню, а инет могли позволить себе далеко не везде.

Так что зря тут была написана откровенная ложь, относительно «рекламирования» и аппелирование о «какой то там не доказательности».
… просто потенциальные места их возникновения пытаются обозначить флажками..

Еще одно ложное утверждение.
Я бы даже добавил так.
Эти агрессивные сторонники Rust дошли до того, что ПЯТЫЙ год подряд на StackOverflow выбирают его в «любимые языки». Вот где источник максимальной агрессии! Тут уже никак не поспорить…
Знаете — это даже не смешно. Да, Rust пятый год подряд «любимый язык StackOverflow». Но взаправду считаете, что на StackOverflow так мало голосующих, что горсточка любителей Rust может всё испортить?

Может вы ещё и верите в том, что что Путин за $100'000 Трампа президентом сделал?
Не, там у голосующих уровень агрессии гораздо выше, чем на жалкие 100К за Трампа (хотя а не знаю).
Возможно сравнивать картофель+крестьян против технологии и инженеров не совсем корректно.
Плюс картофель свою нишу действительно завоевал и не только в России, не будь он выгодным для людей на деле, он бы тихо скончался на обочине истории.
Я вам приведу пример — еще года 3 назад когда меня стали со всех сторон бомбардировать статьями какой прекрасный язык Раст, я честно пошел и изучил предмет.
Но в изучаемом материале было больше паблик-релэйшиншип и рекламы нежели инженирии.
Одно заявление, что Мозилла доверяет расту, но тихо умалчивая, что в ее же недрах его и сделали — стоит многого и показывает какими приемами готовы пользоваться люди продвигающие Раст в массы.
Я желаю Расту удачи, но чем больше вижу нечистоплотной рекламы, тем меньше шансов, что лично я к нему обращу свой взор. Потому что если меня пытаются дурить вот здесь — то где еще и сколько мне это будет стоить когда мой микроконтроллер в поле перестанет работать?
Но в изучаемом материале было больше паблик-релэйшиншип и рекламы нежели инженирии.

О каких материале речь? В своё время, изучал язык по раст-буку, rust by example и растономикону. В первом ещё можно найти признаки рекламы, но с другой стороны, мало какая книга о языке обойдётся без хвалебных эпитетов. Растономикон так вообще состоит чисто из технических подробностей.

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

Ну, вообще-то изначально Rust был проектом Грейдона Хоара, и разрабатывался несколько лет перед тем, как его разработку начала спонсировать Mozilla.

А вы уже забыли, как пиарили Java, когда оно только родилось на свет? Тогда эта технология находилась на зачаточном уровне, да и мощности железа были слабоваты. Тогдашняя древняя JVM была тормознутым лагуче-падучим монстроподобным угрёбищем. Даже просто запустить jar-приложение было той ещё задачей! До сих пор помню то первобытное шаманство с подбором версий JRE и их настройкой. Даже была такая расхожая шутка: мол, Java — по-настоящему кроссплатформенная технология, абсолютно везде НЕ работает совершенно одинаково.
В общем, по тем временам всё выглядело настолько убого, что пользоваться этим дерьмом мог либо мазохист, либо сумасшедший.
Но как же её пиарили! Java представлялась чуть ли не как новый виток развития ни много ни мало человеческой цивилизации! Пиар настолько зашкаливал, что за свою жизнь я потом всего однажды встречал нечто подобное (и это был момент выхода первой книги про Гарри Поттера). Право же, реклама Rust и рядом не стоит с тем уровнем упоротости и агрессивности, с которым продвигалась Java в середине 90-х.
Я даже помню реакцию небезызвестного Спольски на все это пиар-безумие:

And don’t even remind me of the fertilizer George Gilder spread about Java:

A fundamental break in the history of technology…

That’s one sure tip-off to the fact that you’re being assaulted by an Architecture Astronaut: the incredible amount of bombast; the heroic, utopian grandiloquence; the boastfulness; the complete lack of reality. And people buy it! The business press goes wild!

Говоря по правде, Java в своё время была действительно прорывом. Особенно, когда вышел Hotspot, тогда и произошла смена парадигм, C++ начал стремительно вытесняться из бизнес-сектора.

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

JavaStation ведь в Sun на полном серьёзе разрабатывали.

И, потом, не в HotSpot дело. Что там у нас было актально, когда вокруг Java хайп начался? Pentium на 120MHz да MicroSPARC на 100Mhz?

Ну с эмулятором MicroSPARC я не знаю, но точный эмулятор Pentium на 120Mhz найти не проблема.

Можете взять любые свои HotSpot'ы и убедиться что на том железе, вокруг которого разводили хайп — Java, по прежнему, практически невозможно использовать.

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

P.S. Правда по итогу компания, которая это всё затеяла в надежде, что ей удастся сделать самые быстрые процы и заработать за счёт Java-тормозов кучу денег — сделать этого не смогла и, в конечном итоге, сгинула… но то такое: карма — страшная вещь…

Дело было именно в Hotspot, и в удобстве разработки для серверов. Я в соседнем сообщении писал, что тот факт, что разрабатывать можно было на относительно слабых машинках (как правило Win 95 и позже 2k), а запускать на самых настоящих серверах, при этом не тормозя эти самые сервера -- вот это и обеспечило стремительное вытеснение C++.
Даже сейчас писать кроссплатформенный C++ трудновато, а тогда у тебя максимум была ACE, wxWidgets и крутись как хочешь, никаких бустов. Ошибки, связанные с различием между разработческим и прод окружениями были нормой, и они зачастую были весьма нетривиальны.

И появились шутки вроде «если бы в Java была действительно корректно реализована сборка мусора, большинство программ удаляли бы себя сразу после запуска» :) Ну так-то да, у Java, безусловно, есть ряд плюсов по сравнению с C++, которые делают ее минусы не столь важными в определенных областях, с этим трудно спорить. Но, честно говоря, на момент ее появления чисто технически «прорывом» она не была, даже, я бы сказал, наоборот. Технология сборки мусора на тот момент была вполне известна, технология bytecode VM тоже (еще с 70-х годов), синтаксис Sun в значительной степени позаимствовал у тогдашнего C++ (хорошенько его обкорнав, по их собственному заявлению «While Java superficially like C and C++, Java gained its simplicity from thesystematic removal of features from its predecessors»). Да, потом, когда ее основательно допилили, добавили реально работающий JIT и так далее (да и параметры доступного железа подросли, куда ж без этого, ага) в определенных областях и задачах за нее ухватились. Но пушили-то ее «будь здоров» со всеми полагающимися баззвордами еще задолго до этого.

А я не зря упомянул Hotspot, до него к Java относились с большим пренебрежением, видя насколько сильно падала производительность. А с ним у многих сразу многие увидели, что на этом можно делать проекты.
Да, и GC, и JIT компиляция, и VM были известны до этого, но предоставить всё это в одной удобной упаковке, с хорошей стандартной библиотекой, при этом разрабатывать можно было на относительно слабых машинках (как правило тогда сидели под виндой), а запускать на самых настоящих серверах — вот это всё впервые дала Java.

Да, похоже вы правы. Linux-сервера и возможность не мучиться с «самыми настоящими серверами» — это уже середина-конец нулевых, к этому поменту Java уже укоренилась достаточно сильно для того, чтобы её так просто нельзя было выкинуть…

То есть затея Sun, в принципе, удалась, просто к 10м годам большие сервера тупо «выдохлись»: люди научились в распределённые системы, стала важна не просто максимальная скорость, а «скорость на доллар» — а по этому показателю «настоящие сервера» никогда и близко не приближались к x86…

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


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


"Стандартом де-факто" стать не так просто и далеко не всегда на это влияют чисто технические причины. Возьмём, к примеру, swift — язык неплохой, но если бы он не был официальным языком для яблочных платформ, то какая у него была бы доля? Или тот же С#. Или даже котлин — за ним не стоит мега-корпорация со своей платформой, но когда к языку сразу прилагается отличная ИДЕ, то это тоже намного облегчает порог входа.


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


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

Подозреваю, что кому попало делать заявления от лица компании не разрешают.

Подозреваю, что кому попало делать заявления от лица компании не разрешают.

В рамках грустного юмора: зато кто попало считает себя вправе делать заявления от лица компании.
Кажется, в статье описан не такой случай, просто грустное наблюдение.
Я вижу проблему с пиаром, когда продажники и прочие активисты делают заявление А я воспринимаю это как рекламу и не более, то что нужно еще 10 раз проверить. Когда инженеры, которые по определению должны оперировать фактами и цифрами транслируют то же заявление А, безапелляционно заявляя о безопасности я первым делом думаю «вау, это реально круто».
Но спустя несколько месяцев и пару книжек я понимаю что у этого заявления А должен был быть мелкий шрифт о котором забыли (не просто напечатали мелким, но нарочно забыли — мы же не будем на каждом углу об этом говорить как заявили выше), то у меня появляется чувство что что-то пошло не так и доверие которое было вначале падает до отрицательных величин.
А далее происходит еще интереснее трансформации — инженеры которые говорят о прогрессивности раста мной начинают восприниматься как продажники, а не как инженеры, а чем больше повторяется тезис А, тем больше напоминает секту.
Сколько было этих статей про безопасность, о скорости, о красоте и прочем. Там ведь даже мелкого шрифта не было, а ведь это не рекламные брошюры это материалы для инженеров.
Послушайте оригинальное видео, чтобы оставить свои надуманные инсинуации.
В видео с которого была написана оригинальная статья — там все сказано Левиком.
И в свете этого ваши крайне надуманные глупости выглядять слегка убого, видно что вы не пытались и не будете его слушать. Более того, Левик в конце отвечает на задаваемые в чате вопросы.
Ей богу, ваши потуги выглядят совсем «не в тему».
Т.е. вы отрицаете, что у раста есть агрессивное продвижение, которое идет в разрез с принципами инженерного подхода?
Понимаете… вы пытаетесь утверждать то, о чем Левик не говорит. И ваши голословные утверждения тоже «идут в разрез с принципами инженерного подхода», а Левик говорит о вещах которые точно знает, может утверждать и может себе позволить говорить.
Небезопасный код в Rust почти всегда является подмножеством большего объема безопасного кода.

В исходнике:
Unsafe Rust code is almost always a subset of a larger body of safe code.

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

Correctness в переводе — безошибочность, правильность.

Они быстрые, только с ассемблером между кодом и самой машиной.
It is fast, with the only assembly between the code and the machine itself.
Совсем плохой перевод.
Прямая речь, живая, заранее не писанная и заранее продуманная. Так что… как он сказал — так и сказал. Не вижу проблемы, это «живая речь» в видео-конференции, с неоконченными или не до конца завершенными предложениями, не всегда «синтаксически правильными» и т.д… Общая мысль и смысл его утверждений, предположений от этого не меняется, то что он ХОТЕЛ сказать, он СКАЗАЛ.
А тут масса народу развела «песню АНЫКАНА про агрессивную рекламу» — у таких все в порядке с логикой или видят только «заговор» ??? :)))

А можно озвучить эти самые "принципы инженерного подхода"? Как вообще связаны эти две штуки: "инженерный подход" и "агрессивное продвижение"?


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


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

Самое большое «припекание» — у фанатов всяких F# и Haskell. Которые просто вне себя от бешенства, когда Rust продвигают как «безопасный» язык — хотя это «нифига не так» (библиотеки полны unwrap и unsafe… какой же это, нафиг, безопасный язык?).

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

Ну вот так же, как и фанаты OpenBSD, на самом деле. Если что-то повышает безопасность и этого у вас в операционке нету — то там «не безопасность, а дерьмо».

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

Что-то вы в каком то другом мире живете, основное припекание я видел от людей с Си++ головного мозга. Хаскелисты вообще выше всего этого, как мне кажется.

Ну «царей сишечки» я вообще выношу за скобки: если человек невменяем, то с ним что-либо обсуждать бессмысленно.

А как раз людей, умеющих в C++, типа 0xd34df00d а Rust особо и не напрягает…

С одной стороны, от заголовка этой статьи лично мне немножко припекло (раст и безопасные системы? они там слышали про коки-агды-идрисы?). С другой стороны. с допиской во втором-третьем абзаце о производительных и низкоуровневых системах это начинает иметь какой-то смысл.

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


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

У Раста много хороших сторон, но вот макросы — непонятно зачем второй язык, и с модульностью я, например, что то не понимаю — в каком, ска файле искать тот или иной трейт для типа!? Теряю много времени просто на поиск исходника.
Файловая и именная иерархия Явы и прочих более удобна.
в каком, ска файле искать тот или иной трейт для типа!?

Либо там, где объявлен трейт, либо там, где объявлен тип, разве нет? Это в хаскеле вы можете orphan-инстансы объявлять и ограничиться ворнингом, а в расте вроде как вообще нельзя так делать.

Нет, к сожалению.

Предлагаю засечь время чтобы найти описание (повторить мой пусть)
heapless::consts::U9
Время засёк?

Теоретиков много.

IDE открывать было лень, поэтому пользовался гитхабом и кликами. Заняло с минуту. Зашёл в heapless/lib.rs увидел, что consts — это реимпорт из typenum/consts.
И прямо в доке typenum/consts второй строкой написано, что эти константы генерятся во время билда, так что в исходниках их нет, есть только кодогенерация. Ну и в целом описание этих констант там прямо в доке.
В расте я новичок, если что — опыта на 2 kloc + активное чтение статей и чужого кода.


В общем, не знаю, к чему именно у вас претензии — если к кодогенерации, то смысла не вижу. А если к тому, что для typenum она вообще нужна, то тут да, проблема молодости языка присутствует. Const generics в разработке, и с ними весь этот бойлерплейт вроде можно будет выкинуть.


Если говорить чуть глобальнее касательно вашего вопроса "непонятно что где искать", то я в целом могу согласиться, мне тоже порой непривычно что операция A над B может быть реализована за счёт импорта трейта C, потому что там дженерик хитрый. Мне кажется, это дело привычки, и то что раст не очень дружелюбен к новичку — довольно известная тема.


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

т.е так и не нашел. не ОК, а я предлагал таки найти…
и это не кодогенерация

Наверное, я не очень понимаю, что значит "найти". Найти вот это https://docs.rs/heapless/0.5.5/heapless/consts/type.U9.html или вот это https://docs.rs/typenum/1.12.0/typenum/consts/type.U9.html (что в общем-то одно и тоже)? Или найти как с этим работать (т.е. почитать доку к typenum)? Или что-то ещё?

Найти в исходниках heapless описание типа.

А какую Вам информацию дало найденное описание? =)

typenum тут ни при делах

Боюсь, я не согласен с тем, что это не кодогенерация (т.к. противоположное написано прямо в документации), да и вот та самая строка файла генератора, где создаётся определение типа https://github.com/paholg/typenum/blob/master/build/main.rs#L168
С другой стороны я также не понимаю, что не так с моим ответом, т.к. определение типа я вам нашёл прямо в doc.rs (а куда ещё идти за этим если не туда?)


type U9 = UInt<UInt<UInt<UInt<UTerm, B1>, B0>, B0>, B1>;

Собирать локально heapless и делать скриншот из сгенерированного файла мне пожалуй не хочется.


Возможно мы с вами просто говорим на разных языках, но я искренне не понимаю ваших выводов.

Еще раз. Я просил код из heapless::, НЕ из typenum — там совсем другое

И раз: https://github.com/japaric/heapless/blob/master/src/lib.rs#L79


pub use generic_array::typenum::{consts, PowerOfTwo};

И два: https://github.com/fizyk20/generic-array/blob/master/src/lib.rs#L78


pub extern crate typenum;

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

Приношу некоторые извинения — на больную голову я неверно поставил задачу ;-(

В общем искать надо мне было не U9, а String<U9>. и с большим трудом обнаружил, что это формируется макросом.
Ниже на 2 строки
macro_rules! impl_from_num {
    ($num:ty, $size:ty) => {
        impl<N> From<$num> for String<N>
Правда, я не понял, каким образом, без явного его вызова формируется нужный мне String<U9>

Этот макрос в самой heapless раскрывается в такую конструкцию:


impl<N> From<u8> for String<N>
    where
    N: ArrayLength<u8> + IsGreaterOrEqual<U4, Output = True>,
{
    fn from(s: u8) -> Self {
        let mut new = String::new();
        write!(&mut new, "{}", s).unwrap();
        new
    }
}

(и аналогично для других пар, перечисленных ниже). Далее, при наличии реализации From for U, автоматически генерируется реализация Into в обратную сторону. Как следствие, в Вашем коде можно написать:

let num: u8 = ... // как-то получили число
let string: String<N> = num.into();
Знаете — у нас в репозитории и половину классов в проекте на C++ найти нельзя. Потому что кодогенерация. Это точно проблема C++? Как решать предлагаете?

P.S. Кстрати предложенное вам решение: ткнуть в IDE и посмотреть — отлично работает и в C++ и в Rust. Да, оно приведёт вас куда-то в недра сгенерированного файла, но займёт это меньше секунды в обоих случаях.
только это не кодогенерация, это макрос, как выяснилось
Еще один. heapless::

Я так понимаю, утро вечера мудренее, надо переносить.

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

Ну, справедливости ради, с реэкспортами это действительно не всегда тривиально — в примере выше попасть из документации к heapless в документацию к typenum мне, например, не удалось.

Реэкспорты идут в паре с пространствами имён всегда. Даже если вот прям сразу после появления их нету — их через несколько лет добавляют.

А жить без пространств имён… как в С… не знаю — это лекарство, которое хуже болезни IMO…
У Раста много хороших сторон, но вот макросы — непонятно зачем второй язык, и с модульностью я, например, что то не понимаю — в каком, ска файле искать тот или иной трейт для типа!? Теряю много времени просто на поиск исходника.

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


Файловая и именная иерархия Явы и прочих более удобна.

Не уверен. Собственно, главное, что нужно понять в системе модулей Rust — это то, что объявление модуля располагается не в самом модуле, а в родительском модуле. Это позволяет построить всё дерево DAG модулей, имея доступ только к корневому модулю, вне зависимости от того, как они реально располагаются в файловой структуре. И не надо по файлу на модуль делать.

Хотелось бы понять основополагающий принцип.

Локально я и grep'ом поищу, хотя кстати иногда не сработает — макросы.
А что вас смущает? Выстрелит идея, отлично, не выстрелит, уволят и скажут, что к самому майкрософту он отношения не имеет и от лица всей компании заявлений делать не мог.
я тоже хочу микроконтроллер на RISC-V и Rust. точнее, хотел когда-то.
а прямо сейчас у меня есть и риск5 контроллеры разных моделей и пишу нативный код для них на расте. инструментов для разработки уже достаточно.
бывает, что подглядываю в исходники на Си, но это касается только переписывания драйверов подключаемых устройств и пробелов в их документации.
Он инженер, разработчик, который был включен в микрософт поглощением другой компании заявляет от лица всей микрософт что будут использовать Раст?
Да, представьте себе. Иногда бывает полезно смотреть не только вглубь, но и, собственно, на поверхность предмета тоже.

Вы тут покопали и установили, что, исходя из опыта человека, он однозначно пропогандировал бы Rust — независимо от того, где он работал бы. И это — полезна информация.

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

А этого человека не только не уволили, но поставили на должность «developer advocate» (да-да, представьте себе — это оффициальное название должности).

Что это говорит нам о позиции Microsoft в отношении Rust?

В его профиле кроме раст JavaScript/TypeScript, Elm, Elixir больше ничего нет, он действительно может что-то с чем то сравнивать?
А почему он дожен что-то с чем-то сравнивать? Задача «developer advocate» — не сравнивать что-то с чем-то объективно. Задача developer advocate — продвигать ту технологию, которую скажут (как правило он должен в эту технологию ещё и сам верить, иначе продвигать плохо получается, но это, строго говоря, не обязательно). А вот продвигать только те технологии, в которые верит нанявшая тебя компания — это обязательно.

Тут как с рекламным агенством: если рекламный агент говорит «наши кроссовки — самые лучшие в мире», то он лично, может быть, так и не склонен считать… но компания, которая его наняла — так считает точно (ну или, как минимум, хочет, чтобы вы так считали). И даже неважно — где он до этого работал и что он рекламировал.

В общем что я хочу сказать текущему тренду на «вдалбливание, что раст могуч» — чтоб он действительно таковым стал уйдут годы и годы, мы состаримся, а потом он либо тихо умрет, либо так же тихо станет стандартом де-факто, но ни в 1 сценарии он не станет стандартом только потому что пользователей активно убеждают.
Действительно — активное убеждение не может быть единственным фактором. Очевидно что будут применены и другие.
Микрософт иногда страдает множественными личностями которые противоречат друг другу.
Вот поэтому я и говорю о том что евангелисты раста не ведут себя как инженеры, а ведут себя как рекламщики-продажники
While researching Rust, we found some issues that gave and continue to give us pause. Some of these concerns include how to regulate the usage of the “unsafe” superset of Rust at scale, lack of first-class interoperability with C++, and interoperability with existing Microsoft tooling. We’ll be blogging about many of these in the future as they do pose challenges for adoption at the scale of Microsoft, and we want to involve the Rust and wider software communities in helping us find solutions that work for everyone.


msrc-blog.microsoft.com/2019/07/22/why-rust-for-safe-systems-programming

Это было меньше года назад, не думаю что вдруг все описанные проблемы исчезли.
Вы не поверите, StackOverflow тоже похоже продались и ведут себя как продажники, может даже за процент, увы — это мир чистогана и «великой руки рынка, т.е. жиза».
stackoverflow.blog/2020/06/05/why-the-developers-who-use-rust-love-it-so-much

While some languages just add polish and ease to existing concepts, several users feel that Rust is actually doing new things with a programming language. And it’s not doing new things just to be showy; they feel these design choices solve hard problems with modern programming.
Эта статья классический пример паблик-релэйшеншипс, а вы уже явно переходите в агрессивный стиль общения, который сообществу раст и ставится в вину. В погоне за популярностью в ход идут любые методы.
Поймите, эта технология может стать мэйнстримом, но будет это через годы и годы, если вообще будет. Те войны что ведете вы сейчас вообще бессмысленны.
Мы технари, хотим фактов, открытости и без передергивания, пожалуйста если вы один из нас — уважайте это.
Я тоже не вижу у вас инженерного подхода… говорить о том, чего не удалось лично прослушать в видео. Извините — мне тоже надоело, так что это взаимно. :)
Статья написана по видео? В нем все высказано…
Еще ранее меня спросили — какие материалы, я даже вступать в эту дискуссию не хочу, потому что нужно потратить месяцы и годы своей жизни, чтоб понять — с тобой не были честны, я уже это время потратил.
И вот сегодня я потратил еще 44 минуты своей жизни на очередной пиар.
В этом видео (ОТ ИНЖЕНЕРА) единственные цифры это сколько денег стоит то и то и красивые графики которые можно рисовать пачками при продаже чего угодно нового, будь то процессор или машина, убеждая наивных покупателей почему им стоит потратить свои деньги.
Расчет Раст сообщества прост — пока он сообразит у него уже весь тулчейн на нем, уже часть кода переписано и жалко все это бросать и вот новый боец в строю.
Вы апеллируете к видео — я его посмотрел, это очередная рекламная брошюра занимающая 44 минуты!!! Карл, 44 минуты рекламы!
Я больше ни 1 материала в своей жизни по расту не прочитаю, вот никогда. Когда станет стандартом де факто — тогда и приходите. До тех пор ни секунды своего времени.
Я больше ни 1 материала в своей жизни по расту не прочитаю, вот никогда. Когда станет стандартом де факто — тогда и приходите. До тех пор ни секунды своего времени.
Знаете вы мне напоминаете одного моего знакомого — бывшего Delphi-программиста. Он вот так же выступал, когда в конце прошлого века начала «активно насаждаться» Java (а до того — C++). Так и остался со своим Pascal (а потом, соответственно — Delphi).

Когда он обратился ко мне лет 5 назад за советом «что теперь-то делать, когда его знания Delphi 7 больше не ценят»… я ответил, что, как бы, решать нужно было в 90е годы, в крайнем случае в нулевые… а сейчас — поезд ушёл.

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

Да, Rust дошёл до той стадии, когда важны (и нужны) не только технические статьи и видео, но и вот такие вот тоже.

Потому что 90% программистов вообще пофигу на чём и как программировать — они не умеют программировать ни на каком. Но и те 10%, кому не всё равно, и тот 1%, который реально крутые вещи создают — они оттуда же вырастают.

Расчет Раст сообщества прост — пока он сообразит у него уже весь тулчейн на нем, уже часть кода переписано и жалко все это бросать и вот новый боец в строю.
Только это не «расчет Раст сообщества» — все популярные языки становятся популярными по этой вот схеме. Техническое совершенство вас в Top10 не выведет. Можете у фанатов Haskell спросить…

Чаще всего языки через какую то нишу выстреливают, вот как пример котлин и андроид или свифт и ios.
Да даже python и data science.


Когда он обратился ко мне лет 5 назад за советом «что теперь-то делать, когда его знания Delphi 7 больше не ценят»… я ответил, что, как бы, решать нужно было в 90е годы, в крайнем случае в нулевые… а сейчас — поезд ушёл.

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

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

Ну вот почему «столбовая линия» ALGOL 58 ⇒ ALGOL 60 ⇒ ALGOL 60 ⇒ ALGOL W Pascal ⇒ Modula-2 ⇒ Modula-3 ⇒ Operon (бывшая весьма популярной в 60е-70е и даже в 80е годы) вдруг «иссхола» и оказалась вытеснена «внебрачным потомком» того же ALGOL, изменившися почти до неузнаваемости и его имитаторов (C/C++/Java/PHP)?

Там же нет ничего вот принципиально, радикально нового!

Так ведь мог бы уйти в сишники, куда уж честнее то.

Как я понял C и C++ насаждали так же агрессиивно в конце 80х — начале 90х, как в конце оных же насаждали Java.

Так что если исходить из позиции «мне говорят неправду, потому я никогда на этом языке ничего писать не буду» он тоже «некошерен».
Т.е. теперь в ход пошел страх «а в будущем вы будете не удел» :) Очень мило, правда, никакого сарказма и иронии.
Когда за плечами уже много всяких технологий, уже видел как одни поднимались, другие умирали — не очень страшно. И да, когда то тоже была делфи, потом были другие языки, это всего лишь технологии.
Прочитайте внимательно мои комментарии — я уже изучил технологию, разочаровался. И да, меня не пугает изучение нового даже если я проморгал и это мэйнстрим :) За всеми белками не угонишься.
Прочитайте внимательно мои комментарии — я уже изучил технологию, разочаровался.
Я больше ни 1 материала в своей жизни по расту не прочитаю, вот никогда.

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

"Тебе не придётся читать документацию по Rust, если ты будешь знать Rust" :-)


(картинка_с_умным_негром.jpg)

Я больше ни 1 материала в своей жизни по расту не прочитаю, вот никогда. Когда станет стандартом де факто — тогда и приходите.

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


Ну и я хоть и относительно доволен растом, но по сторонам посматриваю. И даже не потому, что боюсь пропустить становление "нового стандарта", а потому что интересно же! И про свежие стандарты плюсов читаю по той же причине.

Старые фишки бы сначала до ума довели, а то трэш какой-то.


Самое смешное, что clang 9 генерит нормальный код, а потом вы свой clang апгрейдите, и всё.


Ещё если добавить alignas(16), то gcc тоже генерит нормальный код, но я не понимаю, почему для x86_64 это важно.

Самое смешное, что clang 9 генерит нормальный код, а потом вы свой clang апгрейдите, и всё.
Почему «всё»? Векторизация началась. Там где этот код вы потом в цикл засунете — всё хорошо будет. А вот в отдельной стоящей функции — да, беда. Можно -fno-slp-vectorize поиспользовать… но тогда он совсем всё в скалярах оставит…

Ну тут, хотя бы, можно говорить что новый подход у clang обычно (когда всё инлайнится) будет лучше…

Ещё если добавить alignas(16), то gcc тоже генерит нормальный код, но я не понимаю, почему для x86_64 это важно.
Ну 16-то сразу зачем? Достаточно alignas(8). Тоже, я думаю, та же фигня. Хотя вот после этого как-то уже всё это даже не смешно. Пять лет они в gcc эту проблему починяют… Самое смешное — что что -O1 отлично работает. Вот как так-то?
Почему «всё»? Векторизация началась.

Зачем она там началась? Что вообще векторизовать в сравнении 8-байтного куска памяти с другими 8 байтами? Оно ж влезает в один 8-байтовый кусок, и код, который сгенерил clang 9, для этого конкретного случая оптимален.


Когда вот я этот код в цикл засуну, тогда пусть компилятор наполняет, например, один 256-битный регистр такими структурами и сравнивает их как 8-байтные сущности. Но до той поры зачем городить этот цирк?


Как вы и пишете, впрочем.


Ну 16-то сразу зачем? Достаточно alignas(8).

Да, спасибо, я просто не умею в числа, и 4 + 4 у меня почему-то получилось 16. Всё, что больше 0, слишком сложно.


Хотя вот после этого как-то уже всё это даже не смешно. Пять лет они в gcc эту проблему починяют… Самое смешное — что что -O1 отлично работает. Вот как так-то?

Чёрт, тоже прекрасный пример!

Что вообще векторизовать в сравнении 8-байтного куска памяти с другими 8 байтами?
Ну нет. Нету у вас там «сравнении 8-байтного куска памяти с другими 8 байтами». Там у вас сравнение двух кусков по 4 байта, однако. Без векторизации (и в Rust, кстати) — вы ровно это и получите.

Оно ж влезает в один 8-байтовый кусок, и код, который сгенерил clang 9, для этого конкретного случая оптимален.
Потому что там, скорее всего, была отдельная обработка подобного случая. А в clang 10 понадеялись на векторизацию. Бывает.
Нету у вас там «сравнении 8-байтного куска памяти с другими 8 байтами». Там у вас сравнение двух кусков по 4 байта, однако.

Это на уровне того, что я могу выразить средствами языка, потому что там действительно может быть padding (а, кстати, может ли у интов у одного и того же значения быть разные представления? лень лезть в стандарт, чтобы проверить). Но я ожидаю, что компилятор поймёт, что у меня здесь нет паддинга, и можно относится к экземпляру структуры как к одному большому 8-байтному куску.


Без векторизации (и в Rust, кстати) — вы ровно это и получите.

Так clang 9 спокойно это и генерит без всякой векторизации, сравнивая по 8 байт.

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

Гляньте-ка вот сюда: это крошечная модификация вашего примера.

Причём гарантированно дающая тот же результат, что и раньше. Однако обратите внимание: clang 10 всё отработал так же успешно, как и раньше — а в clang 9 всё «поехало». Заметьте, кстати, что во всех компиляторах, кроме, собственно, clng 9 — результат (как и должно) стал лучше (в clang 10 — «не хуже») чем раньше.

Так clang 9 спокойно это и генерит без всякой векторизации, сравнивая по 8 байт.
Зуб не дам, но выглядит так, что в clang 9 был какой-то peephole, а в clang 10, поскольку векторизатор стал достаточно умным, его убрали…

Интересно каким был реальный код, который к этому расследованию вас привёл…

Это на уровне того, что я могу выразить средствами языка
Ну здравствуйте, я ваша тётя. Работа «с двумя кусками по 8 байт», разумеется, в C++ тоже выражается — и, внезапно, отлично работает и во всех версиях gcc и в clang. Правда не в MSVC… ну тут уже «горбатого могила исправит», я извиняюсь. От MSVC мне никогда не удаётся получить хоть сколько-нибудь близкий к оптимальному код…
А за счёт чего он это сделает, извините? У вас две, совершенно независимые операции, потом вы как-то вот это всё комбинируете — да ещё и весьма нетривиально.

За счёт эвристик, конечно же! Мало кто пишет оператор сравнения именно таким образом, с битовыми операциями.


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


Интересно каким был реальный код, который к этому расследованию вас привёл…

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


Ну здравствуйте, я ваша тётя. Работа «с двумя кусками по 8 байт», разумеется, в C++ тоже выражается — и, внезапно, отлично работает и во всех версиях gcc и в clang.

Только когнитивная нагрузка этого кода уже куда выше, и сделать в нём ошибку проще. А если у вас в структуре не два int, а три short и ещё пара char, то всё становится совсем весело.


Ну и как вы выразите что-то, что влезает в 128 бит, но не влезает в 64? int128 в C++ вроде как пока не завезли.

int128 в C++ вроде как пока не завезли.
В стандарт — нет, но в имеющиеся в природе компиляторы уже давно завезли. Даже не знаю когда — на clang 3 и gcc 4.1 у godbolt история кончается…

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

Peephole — они такие. Шаг вправо, шаг влево — и оптимизация рассыпалась.

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

Какая будет быстрее? А вот фиг знает: не имея информации о том как часто ваши структуры отличаются в первом intе и как часто — не отличаются вообще вы этого просто не скажите.

А вот если сравнивать, как вы завещали, 8-байтовые куски… тогда уже места для выпендрёжа не остаётся.

Но в любом случае я бы этим стал заниматься, только если бы уже было ясно — что именно там у нас затык. Слишком, на самом деле, много неизвестных даже в такой простой задаче.
В стандарт — нет, но в имеющиеся в природе компиляторы уже давно завезли. Даже не знаю когда — на clang 3 и gcc 4.1 у godbolt история кончается…

Только это уже нестандартное расширение по определению.


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

Тоже отличный пример! Который лишь подчёркивает, что писать код, которому требуется быть производительным, на плюсах (да и на сях, думаю, тоже) нельзя.


А вот фиг знает: не имея информации о том как часто ваши структуры отличаются в первом intе и как часто — не отличаются вообще вы этого просто не скажите.

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

Который лишь подчёркивает, что писать код, которому требуется быть производительным, на плюсах (да и на сях, думаю, тоже) нельзя.
Можно конечно. Нельзя писать код, которому требуется быть максимально производительным.

А просто производительный код — вполне себе получается. Вот то поделие, которое clang 10 устроил — оно, на самом деле не так и медленно (по сравнению с просто ценой вызова функции это всё не так страшно, а после встраивания результат может уже далеко не так сильно отличаться).

Да и не конструктивно это: C++ — медленный… а что тогда быстрое? Не знаю ни одного языка, где без бенчмарков и аккуратного просматривания получается код стабильно более быстрый, чем на C++, а если один язык (там Haskell или Rust) мы бенчмаркаем и правим, а на другом (C или C++) просто «пишем идеоматично» — то это ж не совсем честное сравнение получается.

Причём про многие из этих вещей люди знают и «работают над этим». Скажем в современном C++ идеоматично передавать объект через передачу std::unqiue_ptr. Но это генерит лишний код. Чтобы от этого избавиться у нас есть trivial_abi — но он всё равно не делает тип trivial for the purposes of call! Знают разработчики об этом? Знают. Может лет через 10 и починят…

И вот в этом — весь C++: от момента, когда некая «теоретически zero-cost» идиома рождается до момента, когда она реально становится zero-cost — проходит лет 10-20… но ведь в других языках всё примерно так же…
Да и не конструктивно это: C++ — медленный… а что тогда быстрое? Не знаю ни одного языка, где без бенчмарков и аккуратного просматривания получается код стабильно более быстрый, чем на C++, а если один язык (там Haskell или Rust) мы бенчмаркаем и правим, а на другом (C или C++) просто «пишем идеоматично» — то это ж не совсем честное сравнение получается.

Абсолютно верно. Поэтому никакой язык не быстрый. Ну, вернее, ручное написание кода на ассемблере быстрое.


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

Абсолютно верно. Поэтому никакой язык не быстрый.
А вот есть C--, который нужен для этих ваших GHC IR.

Ну так GHC тоже не производит максимально быстрый код, тащем.


Ну и вместо C-- и NCG сейчас вполне можно использовать LLVM IR и, соответственно, LLVM'ный бекенд (-fllvm и всё).

В хаскеле ушли уже давно от С--

А можно я немножечко встряну? Тут вот аналогичный код на Rust компилируется в хороший ассемблер вне зависимости от уровня компиляции (кроме нулевого, конечно), причём на всех версиях, начиная от 1.27.0, выпущенной 21 июня 2018.

Я даже не знаю — смеяться или плакать. А ничего, что конкретно та проблема, которая у вас не провилась в Rust проявляется в GCC и не проявляется в LLVM? Ни в каких версиях?

Возьмите что-нибудь, что прявляется в Clang — и в Rust оно у вас тоже отличненько проявится. Код, мягко так скажем, недотягивает и до уровня C++ в clang 10…

Посылаю голову пеплом, недосмотрел.

Вы внимательно читали? я уже потратил месяцы на этот язык, как раз на волне красивых обещаний, разочаровался, точка :)

А время потраченное на такие срачи — не считается? (:

:) Вы заметели что на хабре регулярно при упоминании Раста тред разрастается до немыслимых масштабов? Интересно почему…
Есть такая полезная штука — рефлексия, говорят помогает взглянуть на вещи под другим углом.
А в сраче, если посмотреть статистически, мои жалкие 10 коментариев (этот 11ый) капля в море.
Жаль, вы стольких людей таким стилем подачи материала отвратили… молодо, зелено.
Вы заметели что на хабре регулярно при упоминании Раста тред разрастается до немыслимых масштабов? Интересно почему…

Благодаря усилием обеих сторон, естественно. Даже "самые упоротые расто-фанатики" самостоятельно сотки комментариев не напишут. Новости о релизах тому примером — там и 20 комментариев редко бывает.


А в сраче, если посмотреть статистически, мои жалкие 10 коментариев (этот 11ый) капля в море.

И на чтение чужих комментариев время тоже не тратится? Да на эту тему можно больше чем на обсуждаемое видео потратить.


Жаль, вы стольких людей таким стилем подачи материала отвратили…

Кто мы? Лично я? Лично мне — пофиг. Мне за код на расте деньги платят, а не за евангелизм.

И на чтение чужих комментариев время тоже не тратится? Да на эту тему можно больше чем на обсуждаемое видео потратить.

Хм, думаю час где то суммарного времени.
Раз пошел отсчет времени и придирки к мелочам :)) (это ирония если что)
Кто мы? Лично я? Лично мне — пофиг. Мне за код на расте деньги платят, а не за евангелизм.

Походу платят Вам за евангелизм, т.е. не хотят, а платят. Рабочее же время :)
И если пофиг, чтож вы со мной переписываетесь пассивно-агрессивно.
Ладно, это риторический вопрос :) Удачи Вам и пусть действительно Раст вам помогает в работе.
Жаль, вы стольких людей таким стилем подачи материала отвратили… молодо, зелено.
Почему вы так уверены? И почему вы считаете, что те, кого таким образом удалось отвратить — более полезные для экосистемы, чем те, кого этим удалось привлечь?

Это «агрессивное продвижение» — это просто фаза. Обозначающая что на язык обратили внимание «серьёзные дяди» — и продвигают его по всем правилам маркетинга.

Значит ли это, что в результате язык завоюет популярность и вытеснит другие? Ну… само по себе — скорее нет: вокруг Ада хайпа тоже хватало, а ничего особо популярного так и не выросло.

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

Даже Python через эту фазу прошёл, несмотря на мягкость и аккуратность самого Гвидо.
Почему вы так уверены? И почему вы считаете, что те, кого таким образом удалось отвратить — более полезные для экосистемы, чем те, кого этим удалось привлечь?

Вам не нужны инженеры с стажем в 10-20 лет? Люди которые делают реальное железо, спокойные, которым ничего не нужно уже доказывать, но они будут реальными драйвером роста? :)
Около 10 моих коллег ранее были впечатлены марекетинговыми заявлениями по расту в плане безопасности, скорости разработки и все в итоге разочаровались, это те люди которых вы потеряли.
Это «агрессивное продвижение» — это просто фаза.

Да все что мы говорим просто буковки и слова со знаками препинания.
Фанатизм и евангелизм это как раз то состояние в котором способность слышать отключается и появляется уверенность.
Надеюсь мы с вами не в этой реальности находимся?
Даже Python через эту фазу прошёл, несмотря на мягкость и аккуратность самого Гвидо.

Питон поднимался на моих глазах и там даже близко не было тех обещаний который раздает сообщество Раста.
Питон ругали — он улучшался, но было отличие — способность слышать.
Люди отворачиваются т.к. эта способность с самого начала была задавлена агрессивным маркетингом, апологетом которого видимо являетесь и Вы.
Ладно, как заметил мой предыдущий собеседник комментов уже настрочили много, сказали все что хотели, тот кто хочет — услышит.
Удачи вам.
Напомню одну цитату небезизветсного в некоторых кругах человека: Обычно новые научные истины побеждают не так, что их противников убеждают и они признают свою неправоту, а большей частью так, что противники эти постепенно вымирают, а подрастающее поколение усваивает истину сразу.

Вам не нужны инженеры с стажем в 10-20 лет? Люди которые делают реальное железо, спокойные, которым ничего не нужно уже доказывать, но они будут реальными драйвером роста? :)
Нет. Они не будут «драйвером роста». Они скорее тормозом будут. «Драйвером роста» станут новички — со временем. Ровно как у Планка.

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

Около 10 моих коллег ранее были впечатлены марекетинговыми заявлениями по расту в плане безопасности, скорости разработки и все в итоге разочаровались, это те люди которых вы потеряли.
Что значит «потеряли»? Если бы не было «марекетинговыми заявлений» — они вообще пришли бы к расту? Если нет — то нельзя сказать, что их кто-то «потерял». Вот они — да, они что-то потеряли. Время. А раст — нет, он просто не приобрёл ещё десяток сторонников. Если, вместо этого, он получил 100 новичков — это приемлемый компромисс.

Питон поднимался на моих глазах и там даже близко не было тех обещаний который раздает сообщество Раста.
Там другие были. Тот же принцип должен существовать один и, желательно, только один очевидный способ сделать это как-то не очень согласуется с тремя парсерами командной строки: getopt, optparse, argparse. А явное лучше, чем неявное — как это вообще согласуется с динамической типизацией?

В Python тоже полно «невыполненных обещаний» — просто, возможно, вы не так близко к сердцу их принимали, потому их невыполнение вами не так остро переживается…

Питон ругали — он улучшался, но было отличие — способность слышать.
Серьёзно? Не видел. Это я скорее у разработчиков PHP наблюдаю. Когда в python 3 сломали, к чертям собачьим, строки — то на все жалобы ответ был «вы просто не понимаете, как нужно работать со строками». «Наступить на горло собственной песне и сделать то, что сделали разработчики PHP с PHP6 — так и не смогли.

Чем это отличается от поведения разработчиков в Rust, которые некоторые вещи действительно отвергают с подобными же оправданиями?

При этом Rust, хотя бы, не ломал язык чтобы поддержать негодную парадигму…
Пора закругляться :)
Обычно новые научные истины побеждают не так, что их противников убеждают и они признают свою неправоту, а большей частью так, что противники эти постепенно вымирают, а подрастающее поколение усваивает истину сразу.
Нет. Они не будут «драйвером роста». Они скорее тормозом будут. «Драйвером роста» станут новички — со временем. Ровно как у Планка.

Вам видимо виднее… скажу коллегам, что их время вышло.
Заодно закопаем С/С++ с его базой инженеров.
В Python тоже полно «невыполненных обещаний» — просто, возможно, вы не так близко к сердцу их принимали, потому их невыполнение вами не так остро переживается…

Возможно, не буду спорить. Это субеъективная зона в которую мы вступаем.
Чем это отличается от поведения разработчиков в Rust, которые некоторые вещи действительно отвергают с подобными же оправданиями?

Было разделение коммерческих обещаний и реакции и комментариев сообщества и инженеров.
У Раста полное взаимопонимание, коммерческие материалы распространяются как инженерные самими инженерами.
А при выявлении несогласных начинается подавление.
Далее вступает в силу обратная связь когда здравомыслие это порок и люди с опытом по вашим заявлениям должны отмереть… по таким критерями формируется сообщество, какой итог будет у такого отбора вопрос открытый.
Удачи вам.
Нет. Они не будут «драйвером роста». Они скорее тормозом будут.
Надо просто не забывать, кто кого принимает на работу =)

Ну и еще — наверху собираются сливки,… и пена (с)

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


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

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

А аргументы предельно ясны. Они опираются на десятилетия опыта и статистику по уязвимостям. Людям, которые воспринимают С++ просто как инструмент, а не какой-то объект поклонения, давно понятно, что проблема именно в нем и решить ее невозможно в рамках этого языка. Раст как бы не случайно был придуман, а как следствие этого всего.
«Давно понятно.» честно говоря, так себе аргумент. Потому что, или не «давно» или это просто попытка оправдать rust, ибо C++ и rust разделяет 27 лет.
C++ и rust разделяет 27 лет
Это между какими событиями? Просто интересно…
Сколько лет различает вас и вашего отца? Вот между этими событиями.
Сколько лет различает вас и вашего отца? Вот между этими событиями.
Проблема в том, что у нас с отцом есть сертификаты рождения. А у языков их нет. Потому непонятно — то ли вы говорите о самом начале (но тогда C++ начинается как «C с классами» в 1982м, а Rust — соотвественно в 2006м… это 24 года разницы), то ли разница между первым релизом C++ и первым релизом Rust… (но это всего 17 лет, не 27), то ли ещё что…

Вот и возникает вопрос: что вы вы взяли за реперную точку, что разница в 27 лет получилась?
но ни в 1 сценарии он не станет стандартом только потому что пользователей активно убеждают
Наоборот — ни в одном сценарии он не станет стандартом, если не будет агрессивного убеждения пользователей.
Новость позитивная. Тем кто с болью вспоминает яву и IE, стоит присмотреться к Safari, который также ставит палки в колёса. И перевод, конечно, жуткий транслейт.

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

Послушайте оригинальное выступление на англ в видео — отпадут все вопросы. :)
Ждать поддержки Rust в Visual Studio? Или собственной реализации Microsoft Rust? Хотя они уже вроде делают Verona… Ну так присоединились бы к разработке, организовали бы комитет по стандартизации Rust:)
Visual Studio Code довольно давно и довольно неплохо поддерживает Rust в тандеме с rust-analyzer.

rust-analyzer пока плохо справляется с await. Выдает unknown, если используется конструкция вида Future<Output = T>.

комитет по стандартизации Rust

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

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

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

С одной стороны это конечно хорошо когда стандарт и всё такое. С другой стороны у трёх основных компиляторов до сих пор несовместимые расширения, не говоря о том, что MSVC до версии 19 (2017я студия) вообще весьма вольно относился к стандарту.


Но что меня больше всего удручает — как фичи вносятся в стандарт. Возьмём к примеру модули в С++ и async-await в Rust. Просто для примера. Модули до внесения в стандарт были в экспериментальном (и, насколько я знаю, отличающемся от стандарта) виде только в MSVC. CLang поддерживал гораздо более старую версию, если не вообще другой драфт. Ситуация с async-await же была совершенно иная. Последняя редакция фичи, которую внесли в стабильную ветку простым удалением гейта, была доступна на нестабильной ветке что-то около полугода, и все желающие могли её общупать по полной. Более того, все фичи перед стабилизацией сидят в анстэйбле, и их можно общупать не только по одной, но и в комбинациях.

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

А если бы оно было не лучше — то и зачем тогда этот стандарт с зоопарком компиляторов? Просто потому, что у сишников и плюсовиков так принято?

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

Сейчас же наступает эпоха корпоративных языков, ожидать каких либо стандартов или альтернативных компиляторов нет смысла.
Вообще-то это то, с чего начинались языки программирования в 50е. Оттуда выросли не только COBOL и FORTRAN (из сохранившихся в наше время), но REXX, MATLAB и куча других (большинство умерло… хотя одно время были популярны — вские FOCAL и прочие… ну так и вообще, в принципе, большинство языков программирования умерло).

Насколько это в целом жизнеспособно в доглосрочной перспективе по сравнению с классической моделью разработки языков — время покажет.
Это не классическая модель, а изобретение «академиков» в 60е. Когда было принято описывать языки вообще не думая (или очень мало думая) о том, можно ли их реализовать и как. Lisp, ALGOL так появились.

А Rust разрабатывается по не менее классической модели кооперации вокруг одной реализации: так были созданы Java, C#, PHP, Swift, Go, Ruby, Perl… это только из Top20. И ни один из этих языков не собирается помирать, что характерно…
Это не классическая модель, а изобретение «академиков» в 60е.

60-ые годы уже не классика)? Да и к тому же си появился и вырос не в академической среде, хотя в итоге был стандартизован.

60-ые годы уже не классика)?
Если искодить чисто из возраста, то все эти модели сегодня классика, так как одом из XX века.

Да и к тому же си появился и вырос не в академической среде, хотя в итоге был стандартизован.
Ну C как раз появился так же, как и Rust: Ритчи где-то описывал, что там был цикл: новые фичи языка требовали увеличивать размер компилятора (что логично), что приближало его к границам «железа», но зато позволяли в следующей версии уменьшить размер компилятора и освободить место для следующих фич…

А стандартизация — это уже конец 80х (первый стандарт — C89 он же C90… 17-18 лет после появления языка).

Но там это потребовалось, чтобы «подружить» множество несовместимых диалектов… а у Rust (как и вообще у всех языков «нового поколения») этой проблемы нет: распространяется бесплатно, новую версию может скачать кто угодно и почти мгновенно… откуда, внезапно, взяться кучам несовместимых реализаций?
Микрософт в своём репертуаре. Вместо подключения статического анализатора и ликвидации задолженности — решили всё переписать найдя для этого серебрянную пулю.
Очевидно же, что не сработает
Это вы серьезно??? Или просто «проходили мимо» и решили чиркануть??

While Microsoft is bulish on Rust, Levick admits that Microsoft core developers won’t stop using C/C++ anytime soon.
“We have a lot of C++ at Microsoft and that code is not going anywhere,” he said. “In fact, Microsoft c++ continues to be written and will continue to be written for a while.”

абсолютно серьёзно
исходя из написанной на русском статеечки сверху — следует именно то, что я написал
приведённый вами кусок английского текста — взять непонятно откуда — скорее всего с зарубежных серверов которыми владеет цру, поэтому строить на нём свои умозаключения — я не буду
Так вот из «статеечки сверху»
Хотя Microsoft оптимистично настроена на Rust, Левик признает, что разработчики ядра Microsoft не прекратят использовать C/C++ в ближайшее время.

«У нас в Microsoft много C++ и этот код никуда не денется» — сказал он. «Фактически, Microsoft продолжает писать c++ и будет писать некоторое время».

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

Давайте попробуем разобрать статью и вообще феномен Раста по существу. На протяжении последних нескольких лет я наблюдаю крайне агресивный пиар Раста, и эта статья не исключение. Не могу сказать, с чем это связано, но можно привести ряд аналогичных ситуаций с другими языками, когда языки-«убийцы» не получали должного внимания (взять тот же Julia, например) со стороны сообщества, хотя определенно этого заслуживали.
Вот возьмем, например, главный козырь и киллер фичу Раста — безопасность по памяти, которую обычно противопоставляют отсутствию оной в C/C++. Но в связи с этим вопрос: а чем хуже C++ в связке с хорошим статическим анализатором, чем Раст? Ответ: ничем. Очередная статья очередного апологета Раста, который не имеет опыта разработки на C/C++, выдвигает по этому поводу следующий тезис:
Статический анализ упоминается, как еще одно возможное решение. Но статический анализ требует слишком много времени: его необходимо подключить к системе сборки. «Так что есть большой стимул не использовать статический анализ» — сказал Левик. «Если он не включен по умолчанию, он не поможет».
То есть человек всерьез утверждает, что внедрение статического анализа в CI и в повсведневную разработку слишком дорого по сравнению с обучением сотрудников новому языку.
Кстати об обучению новому языку: синтаксис Раста — это просто треш имхо. За 10 лет программирования на 5+ языках я такого не встречал ни разу. Пусть это субъективное мнение, но я готов поспорить, что ни одному программисту с мало мальски серьезным опытом промышленной разработки такой синтаксис не будет привычен. В этом, очевидно, стоит винить создателей языка. Но оставим в стороне синтаксис — в языке нет ООП. Даже с учетом критики ООП (вполне обоснованной, кстати) эта парадигма на сегодняшний день является де-факто стандартом в индустрии. Создавать в 21xx году язык, в котором наследование заменено костылем в виде трейтов — у меня этому нет объяснения.
Стоит отдать должное Расту — это хороший нишевый язык, который лучше, чем C, подходит для разработки систем, в которых на первом месте стоит формальная корректность. Но зачем писать на Расте микросервисы и тому подобное, да еще и агрессивно продвигать его в качестве 10/10 языка для таких задач? Ответа нет.
Это лишь малый список недостатков Раста, который позволяет поставить под сомнения главный тезис статьи. В общем резюме: с моей точки зрения, Раст конкретно пиарят, не совсем ясно только, кто за это платят. По факту это просто yet another programming language с претензиями. Кто сомневается в искусственно созданном ажиотаже вокруг языка, рекомендую к ознакомлению любопытную статью «Why the developers who use Rust love it so much». При внимательном прочтении можно увидеть все то же, чем грешит данная статья, да и вообще все статьи типа «раст — крута»: о преимуществах Раста перед C/C++, скорой смерти C/C++ и безопасности по памяти обычно громче всех кричат те, кто раньше писал фронтенд на Джаваскрипте (я утрирую, конечно, но суть ясна). Чего стоит только этот пассаж:
When I think of a “statically typed language”, I think of Java, or C#, or something like TypeScript.
Но в связи с этим вопрос: а чем хуже C++ в связке с хорошим статическим анализатором, чем Раст? Ответ: ничем.

Каким конкретно анализатором и какими конкретно настройками этого анализатора мне добиться той же безопасности, которую даёт раст?


Кстати об обучению новому языку: синтаксис Раста — это просто треш имхо. За 10 лет программирования на 5+ языках я такого не встречал ни разу. Пусть это субъективное мнение, но я готов поспорить, что ни одному программисту с мало мальски серьезным опытом промышленной разработки такой синтаксис не будет привычен.

У меня опыт поменьше (всего два языка, один из которых плюсы, и 17 и 9 лет опыт разработки соответственно), но мне синтаксис раста по большей части вполне норм (хотя у меня с ним нулевой опыт, я только читаю код). Единственное, что корёжит — одинарный тик для переменных лайфтаймов, мой визуальный парсер начинает думать, что это строка, и печалится, что нет закрывающего тика. Но это мелочь.


Но оставим в стороне синтаксис — в языке нет ООП. Даже с учетом критики ООП (вполне обоснованной, кстати) эта парадигма на сегодняшний день является де-факто стандартом в индустрии. Создавать в 21xx году язык, в котором наследование заменено костылем в виде трейтов — у меня этому нет объяснения.

На самом деле наследование — это костыль для отсутствующих иерархий трейтов.


Может, я занимаюсь каким-то не тем программированием, но ООП мне в практике был нужен ровно в одном проекте (где было много UI) из дофига. В остальном плюсовом коде нет ООП, в коде на другом языке тоже нет ООП, и как-то от этого хуже не становится.


А вот опыт с кодовыми базами, где много ООП ради ООП, у меня есть, и это так себе опыт.


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

Даже тут не соглашусь. Для систем, где важна формальная корректность, раст слишком слаб.


о преимуществах Раста перед C/C++, скорой смерти C/C++ и безопасности по памяти обычно громче всех кричат те, кто раньше писал фронтенд на Джаваскрипте (я утрирую, конечно, но суть ясна)

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


А, ну и кстати,


C/C++

Это два разных языка с двумя разными философиями и идиомами. Писать их через слешс странно. Вы же не пишете «C/C#»?

и где очень важно не падать и торговать корректно

М-м-м. Перспектива словить в произвольном месте unwrap() (и соответствующий краш) вместо исключения не смущает? :)

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

Это как бы все-таки ортогональные вещи. Попортить память запросто может unsafe код, а unwrap() можно словить в какой-нибудь библиотеке, которую писал гражданин, поленившийся в данном месте передать ошибку «наверх», ведь в случае Раста это неиллюзорно требует написания некоторого количества бойлерплейта на КАЖДОМ уровне. Лично я считаю подход Rust к обработке ошибок недостаточным по сравнению с языками с поддержкой исключений (они даже в помирающем Objective C более-менее нормально работают в сочетании с ARC, тысяча чертей!).

Если уж совсем боль, то unwrap можно перехватить.

Только в плюсах у вас вся программа unsafe, а в расте эти блоки явно помечены.

Не стебитесь так откровенно, вы же прекрасно поняли, что я имею в виду :)
Уже обсуждалось: так могло бы быть, но так не сделано. Считается что безопасность нужно обеспечивать на уровне класса, но не экспортировать её дальше.

Что неприятно: просмотреть только код, помеченный unsafe — недостаточно.

Более того: писанных правил о том куда можно экспортировать небезопасность — я вообще не нашём. Что ешё более неприятно.

Понятно, что формальных гарантий это не даёт. Но быть внимательным language lawyer'ом при чтении одних лишь unsafe-блоков проще, чем при чтении вообще всего кода.

Кто-то подкрадётся и вставит unwrap в произвольное место? Кроме того есть крейт no_panic, который может проверить отсутствие паник во время компиляции.

У этого крейта есть неприятная особенность: без оптимизации (и на низких уровнях оптимизации, ЕМНИП, тоже) он кучу false positives выдаёт.

Смущает не больше, чем возможность "словить" exit или abort.


Кстати, unwrap — это не краш.

Дело в том что и падения на C++ и креши на Rust — это всё «убытки из-за вылетания из биржевого дня».

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

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

А что такого? Они достаточно детерменированы, в отличии от сегфолтов, можно еще и логическую ошибу пропустить с такими же последствиями.

Вы же не пишете «C/C#»?
Можно ещё C#/F#/J# писать.

Хотя с C и C++ странно: они довольно-таки сильно перемешаны — хотя формально являются разными языками. Может быть потому что на Windows C++ так и соблагоизволил получить стабильный ABI и потому много C библиотек на самом деле «внутри» на C++ написаны.
стабильный это начиная с v140 и то некторые приколы(https://github.com/conan-io/conan/issues/3573) то и дело всплывают
Каким конкретно анализатором и какими конкретно настройками этого анализатора мне добиться той же безопасности, которую даёт раст?
Выпишите, пожалуйста, список гарантий, подберем вам анализатор.
У меня
Может, я
у меня есть
Я писал
Пропускаем, не интересно. Не считаю нужным тратить время на спор насчет личных предпочтений.
Даже тут не соглашусь. Для систем, где важна формальная корректность, раст слишком слаб.
Согласен, я не совсем корректно употребил термин. Я видел ваши публикации про развлечения с Идрисом, и, честно говоря, я не считаю, что формальная корректность в таком виде нужна хоть кому-нибудь в индустрии. Я имел в виду больше что-то вроде бортовых систем, где главный показатель корректности — отсутствие гонок. Хотя вроде Раст в этом случае тоже ничего не гарантирует, но это все-таки лучше, чем словить UB из-за алиасинга.
Это два разных языка с двумя разными философиями и идиомами. Писать их через слешс странно. Вы же не пишете «C/C#»?
Не очень уместная придирка. Очевидно, что в этом контексте C и C++ идут в тандеме, так как Раст противопоставляется им обоим с одинаковой аргументацией.
Выпишите, пожалуйста, список гарантий, подберем вам анализатор.

Как в расте.


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

Окей. Тогда продолжим после того, как вы предъявите объективные исследования с достаточной статистической силой о важности ООП, об уродстве синтаксиса раста, о важности наследования, ну и о том, кто громче всего кричит о смерти плюсов. Как, сможете?


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

Кардиостимуляторы, рентгеновские аппараты (Therac-25 передаёт привет), те же бортовые системы в условных самолётах или космических аппаратах.

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

Увы, но если даже в язык с формальной верификацией засунешь корявую спеку, то он лишь докажет, что она корректна в своей корявости.

НЛО прилетело и опубликовало эту надпись здесь

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

> параметрический полиморфизм с тайпклассами (типажами)
C++20 concept
> алгебраический тип данных с паттерн-матчингом
std::visit
C++20 concept

Покрывают согласно стандарту только "периметр", в теле функции валидность не применяется никак. И да, опциональны.


std::visit

Возьмите любой нетривиальный пример паттерн матчинга и попробуйте реализовать аналог через std::visit.

Но в связи с этим вопрос: а чем хуже C++ в связке с хорошим статическим анализатором, чем Раст? Ответ: ничем.

Сразу мимо… Даже в том же обсуждении -wlifetime для clang предлагали помечать код специальными аннотациями чтобы анализатор мог правильно исследовать время жизни.
Без подсказок со стороны программиста провести исчерпывающий анализ времен жизни невозможно — там существуют неоднозначности, которые должен как раз программист разрешать, расставляя атрибуты. В случае Rust это как раз привело к созданию lifetime синтаксиса.


Создавать в 21xx году язык, в котором наследование заменено костылем в виде трейтов — у меня этому нет объяснения.

Вообще-то этот "костыль" намного более выразителен, чем наследование. Может объясните мне его костыльность? Как по мне это еще более сильное разделение между данными и алгоритмами работы с ними, чем это есть в наследовании.


Это лишь малый список недостатков Раста, который позволяет поставить под сомнения главный тезис статьи

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


Но зачем писать на Расте микросервисы и тому подобное, да еще и агрессивно продвигать его в качестве 10/10 языка для таких задач? Ответа нет.

Может потому, что их получается писать легко и они при этом еще и работают хорошо?

Сразу мимо… Даже в том же обсуждении -wlifetime для clang предлагали помечать код специальными аннотациями чтобы анализатор мог правильно исследовать время жизни.
Дело не в анализаторе, а в ограничениях языка — потому статический анализатор Раста (встроенный в язык) имеет априори преимущество перед [внешними ]Линтерами С++.

Вообще-то этот «костыль» намного более выразителен, чем наследование. Может объясните мне его костыльность
Трейты с 9ю параметрами конечно более выразительные, но нихрена не читаемые.
Трейты с 9ю параметрами конечно более выразительные, но нихрена не читаемые.

Это как? Ты их не путаешь с char_traits?

Да путаю, но не с этим. Наследование трейтов решает вопрос.

Но вот проблема большого кол-ва параметров на практике наблюдается.

А можно пример, я не очень понимаю что за параметры

Да ругались уже про недостаточный автовывод типов.

Но кажется, это я не в тему (ООП с помощью трейтов) заехал…

Такое не так уж и часто бывает, причем как я понимаю, в похожем случае бы в ООП языке было бы наследование от 9 интерфейсов.

Ну нет же, в этом случае.

Хотя для несвязанных трейтов — да.
Дело не в анализаторе, а в ограничениях языка — потому статический анализатор Раста (встроенный в язык) имеет априори преимущество перед [внешними ]Линтерами С++.

Ну, как минимум потому, что в Rust подобным образом проверяется весь код, включая std и зависимости. В C++ такую роскошь себе позволить не получается.

Да, это неоспоримый плюс. Хотя std и зависимости достаточно проверить единожды.

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

Откуда вы это взяли?

Об этом писал Уолтер Брайт, реализовавший OB для D, и о сравнимых затратах — Дэвид Малколм, про реализацию DFA в GCC10.

Я переводил обе статьи.
Сразу мимо… Даже в том же обсуждении -wlifetime для clang предлагали помечать код специальными аннотациями чтобы анализатор мог правильно исследовать время жизни.
Без подсказок со стороны программиста провести исчерпывающий анализ времен жизни невозможно — там существуют неоднозначности, которые должен как раз программист разрешать, расставляя атрибуты. В случае Rust это как раз привело к созданию lifetime синтаксиса.
Мне кажется или этот пассаж как раз таки равняет Раст и C++ с аннотациями?
Вообще-то этот «костыль» намного более выразителен, чем наследование. Может объясните мне его костыльность? Как по мне это еще более сильное разделение между данными и алгоритмами работы с ними, чем это есть в наследовании.
Не знаю насчет выразительности, но код читать тяжелее имхо. Вполне возможно, что у меня ООП головного мозга, но все-таки сознательно делать язык, который не следует общепринятым концепциям, просто так — это как минимум странно. Или быть может есть конкретная причина, почему Раст не реализует ООП?
Список из субьективного восприятия синтаксиса и крайне спорный момент насчет ООП это прямо таки список недостатков. Сильная аргументация, ничего не скажешь.
Я склонен считать, что эти моменты имеют место не только для меня. Кроме того, в вашем ответе объективности не больше. Самое объективное, конечно, это:
Может потому, что их получается писать легко и они при этом еще и работают хорошо?
Диссертация на тему «легко» и «хорошо» как метрики оценки трудоемкости разработки и качества ПО.
но все-таки сознательно делать язык, который не следует общепринятым концепциям, просто так — это как минимум странно
Так зачем делать «как было», если можно сделать лучше?
Или быть может есть конкретная причина, почему Раст не реализует ООП?
Он реализует ООП. Прекрасно. Он не реализует то, что продают под видом ООП разработчикам C++ и Java.

И да, тому есть вполне понятная и совершенно очевидная причина: наследование реализации — штука небезопасная и потому всовывать её в язык, который пытается что-то предоставить в области безопасности… несколько странно.

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

Есть trait object для динамического и генерики для статического.

"Что-нибудь в духе Go" в Rust как раз сделано, добавление ключевого слова dyn к имени трейта даёт интерфейс.

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

В Rust, насколько я знаю, так делать нельзя.

Если делать ООП по SOLID, то все случайные реализации интерфейсов структурами так и останутся случайностями, а все отличия Go от Rust в этом плане сведутся к наличию impl и dyn в последнем.

Вау! Круто-то как. То есть в вашей вселенной разработчики Haskell не ломали совместимость, чтобы сделать монаду аппликативом, а моноид — полугруппой? А не расскажите — чего нужно выкурить в такую интересную вселенную попасть?

Увы и ах — «все отличия Go от Rust в этом плане сводятся к наличию impl и dyn в последнем» только в тех случах когда подобные вещи разработчики предвидят в 100% случаев.

На практике же ситуация, когда из какого-то интерфейса выделяется какой-то полезный подинтерфейс — редкостью не является.

И решить эту проблему в Rust можно только одним способом: не объявлять trait с более, чем одним методом, а если нужны более сложные — то обявлять каждый метод отдельным trait и потом, поверх этого уже — собирать более сложные trait.

Слава богу так никто не делает.

И нет, я не говорю, что нужно «ООП в стиле Go» привнести в Rust — он там явно не к месту. Я просто говорю о том, что они таки разные — и да, эта разница практически заметна тоже.
Вау! Круто-то как. То есть в вашей вселенной разработчики Haskell не ломали совместимость, чтобы сделать монаду аппликативом, а моноид — полугруппой?

А как от этого помогут интерфейсы в стиле Go?


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


Всего-то вместо требования базовой реализации trait Monad : Applicative надо предоставить реализацию по умолчанию: impl<T> Applicative for T where T: Monad.


И то же самый принцип работает для любых "полезных подинтерфейсов".


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

Всего-то вместо требования базовой реализации trait Monad: Applicative надо предоставить реализацию по умолчанию

А как будет выглядеть код, который работает и с аппликативными, и с монадическими методами?


Если у вас нет констрейнта class Applicative m => Monad m where ... и вы напишете


foo :: Monad m => ...

то у вас будет использоваться этот дефолтовый инстанс, что не всегда желательно. Получается, надо писать foo :: (Applicative m, Monad m) => ... даже в новом коде?

дефолтовый инстанс, что не всегда желательно

В Rust — в отличие от Haskell — нет приоритета инстансов. Иначе говоря, если у вас есть "дефолтный" инстанс — значит никакого другого "недефолтного" быть уже не может, компилятор не даст.

Ждём специализацию на stable, в таком случае?

Это ещё долго ждать и может даже вечно. Её и в nightly пока скорее нет, чем есть.

Но в связи с этим вопрос: а чем хуже C++ в связке с хорошим статическим анализатором, чем Раст? Ответ: ничем.

Серьёзно? То есть у microsoft столько проблем с безопасностью, связанных с ошибками работы с памятью, потому что они не прогнали свои исходники через статический анализатор? Или посыл в том, что раст на самом деле не помогает от ошибок работы с памятью?

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

12 лет продакшена на С++ вас устроят?
Плюс эпизодически Java, C#, Python. Всякую мелочёвку не берём.
Угадайте у каких языков я считаю синтаксис наиболее вырвиглазным? С++ с его кучей контекстно-чувствительных вещей. И Perl.


EDIT: Убрал огрызки редактирования

Когда я изучал документацию Rust, у меня как раз сильные ассоциации с Perl возникали.

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


Первая — ключевые слова короче, их тоже меньше. В результате визуальная плотность спецсимволов растёт.


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

Да, сигнатуры обобщенных функций — одно из главных трудночитаемых мест в синаксисе Rust. И дело не только в синтаксисе, с ним могут помочь where-блоки. Дело в том, что плотность информации на строчку кода высока.

Мне кажется, раст является ещё одним "лучшим шансом". Когда-то была Ада, когда-то еще кто-то. Но немалая часть безопасных систем уже выстроена, выстроены процессы их разработки существующими методами. Чтобы строить что-то новое и глобальное — нужно много раст программистов, а их просто нет. А в маленьких стартапах расту не выжить — мало программистов, а те, что есть, довольно дорогие. И опять же, GUI-фреймворка для раста толкового нет, писать для мобилок сложно, в вебе — тоже сложно, в бэкенд они долгое время пытались пролезть — не вышло, с embedded системами прямо сейчас как-то не очень получается. Я не вижу пока у раста возможности стать широко распространенным языком.

Не стоит списывать Аду со счетов. Да и Раст тоже =)

Но да, скорее всего останутся нишевыми.

Вообще так или иначе все языки нишевые.

может кто в теме и пояснит.

Почему в Rust не выбрали модель управления памяти с помощью ARC как например в Objective C/Swift? Borrowing не решает всех проблем, всё равно нужны смарт-пойнтеры, так не проще ли было сделать единообразное решение на все случаи, к тому же ARC того типа что в Swift — это не Garbage collector и работает пооптимальнее.

Потому что это сужает область применения. И потом, с ARC у нас уже есть Swift.

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

хм, с ходу так и не скажешь что это оптимальнее

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

Атомарные операции происходят быстро, но тем не менее имеют определенный оверхед (например на синхронизацию кешей разных процессоров). Поэтому в том же Rust есть Rc (не потокобезопасный смарт пойнтер) и Arc (потокобезопасный). В том и прелесть что вы можете использовать ровно тот тип управления памятью который нужен для вашей задачи. И для 80-90% задач достаточно использовать обычные ссылки

А еще Rc и Arc и прочее ARC это история про память в хипе, что тоже плохо иногда.

Атомарные операции происходят быстро, но тем не менее имеют определенный оверхед (например на синхронизацию кешей разных процессоров).
Там даже без какой-либо синхронизации и вообще участия двух ядер скорость такая, что прикручивать это к структурке из двух-трёх int-ов — идея плохая. Откройте табличку и посмотрите. Даже если забыть про Bulldozer с его «вроде как 55ю тактами» (ну не смог Агнер придумать как такие тормоза точно промерить), то даже и 18 тиков у Skylake и 17 у Ryzen — это не бог весть как быстро…
а нельзя как-то оптимизировать работу со ссылкой пока счетчик равен 1? Ну скажем условно выставлять флаг когда появляется 1-я ссылка. А счетчик создавать только когда видим что флаг уже поднят — значит это уже вторая ссылка. А таких случаев как сказали — большинство.
А давая выбор Arc или Rc — тут появляется возможность ошибки, так? Если программист ошибся и выбрал Rc где нужен был Arc, не съест ли такая ошибка оптимизации, да и просто неприятная ошибка логики. Это ведь нижний слой обслуживания технологии, и неприятно что даже на этом уровне можно сделать ошибку.

UPD: интересная ссылка на табличку, спасибо
а нельзя как-то оптимизировать работу со ссылкой пока счетчик равен 1?

А если этот флаг выставляют два потока одновременно?


А давая выбор Arc или Rc — тут появляется возможность ошибки, так? Если программист ошибся и выбрал Rc где нужен был Arc, не съест ли такая ошибка оптимизации, да и просто неприятная ошибка логики.

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

А если этот флаг выставляют два потока одновременно?


мм, не соображу — как такое может быть? У каждого потока свой стэк выполнения, и если они доступаются к общему объекту, то как они могут одновременно выполнять его конструирование? Флаг ведь менялся бы на этапе создания объекта.
т.е. если оба потока вызвают
User ref = new User(); // не знаю как в расте
то ref будет у каждого свой. Если же они доступаются к уже созданному — то флаг будет уже поднят
а нельзя как-то оптимизировать работу со ссылкой пока счетчик равен 1?
Можно, но не нужно. Дело в том, что если вы говорите программисту: «одна ссылка — это очень-очень дёшево, а за две — будем хлестать розгами»… то он чешет репу, долго думает — и изобретает таки структуру данных, в которой почти все обращения идут через единственную ссылку (которую можно, впрочем, кому-то на время отдавать).

Внезапно: так устроенных языков у нас не один, а два — Rust и современный C++. С его std::unique_ptr и std::move.

И потому, оп-ля, современный идеоматичный код на C++ часто можно переписать на достаточно идеоматичный Rust.

А вот если этого не сделать… то думать об этом никто не будет и «живых ссылок» — будет масса.

Отсюда, на самом деле, «растут ноги» у странного феномена: на всех бенчмарках — C++ и C#/Java показывают близкие результаты. А вот в реальных программах — почему-то разница на порядок, а то и на два.

Это не потому, что GC такой медленный. Это потому что если людям разрешить не думать о памяти — то они этого делать и не будут… а потом — уже никакой оптимизатор вас не спасёт.
я имел в виду не два типа ссылок а один, в котором просто оптимизирована работа для частного случая пока ссылка только одна. А когда появляется 2-я — тогда и создавать атомарный счетчик.
Если остальных случаев когда нужны Rc, Arc и тд. всего 10% то потеря производительности должна быть небольшой, а семантика одна и та же, и не надо фиксить какие-то проблемы лайфтаймами. Если я верно понимаю, в некоторых случаях когда переменные имеют разную область определения, нужно использовать лайфтаймы скажем при передаче аргументов в функцию.

Это потому что если людям разрешить не думать о памяти — то они этого делать и не будут… а потом — уже никакой оптимизатор вас не спасёт.


а как, кстати, решается проблема фрагментации кучи в Rust? Или такой проблемы нет?
А когда появляется 2-я — тогда и создавать атомарный счетчик.

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


Какие-то частные случаи можно отлавливать во время компиляции (escape analysis), но программист теряет контроль над поведением ссылок, что неприемлемо для системного языка.


а как, кстати, решается проблема фрагментации кучи в Rust? Или такой проблемы нет?

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