All streams
Search
Write a publication
Pull to refresh

Comments 20

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

Нашли bottleneck — вынесите в отдельный микросервис на Rust.
gRPC, HTTP, хоть сокеты — не важно. Так безопаснее всего.

Но как же наносекунды с сетевыми то вызовами, карл?? :)

  1. В Rust нет compile-time гарантий целостности для структур, размещённых в хипе. Вместо этого он использует флаги, счетчики и проверки во время выполнения, которые вызывают panic и аварийно завершают программу.

  2. Управление объектами в хипе основано на умных указателях с подсчётом ссылок, как в C++, что приводит к утечкам памяти.

  3. Rust не предотвращает дедлоки.

  4. Все приложения на Rust прямо или косвенно импользуют unsafe, теряя безопасность памяти и защиту от data races.

  5. Паники часто возникают при работе с optional, заимствованиями и приведениями типов, если их специально не обрабатывать. В этом выражении приведения типов три возможных краша (кстати, как вам такой синтаксис простого приведения типов?):
    result.unwrap().borrow().as_any().downcast_ref::<RefCell<T>>().expect("!").clone()

  6. Синтаксис адски переусложнен даже для простых операций. Вот пример безопасного присваивания полю структуры по maybe-null-указателю:
    ptr.and_then(|x| x.try_borrow_mut().ok()).map(|mut x| x.field = 1);

    Вот пример того же кода на языке Аргентум: ptr?_.field := 1 - просто, предсказуемо и безопасно. И хотя Аргентум решает все перечисленные выше проблемы, работая без паник, утечек, unsafe, гонок, дедлоков и GC, я его пока не рекомендую из-за его экспериментального статуса.

гарантий целостности для структур, размещённых в хипе

О чём конкретно речь?

Управление объектами в хипе основано на умных указателях с подсчётом ссылок

Ложь, контейнеры вроде Box<T> и Vec<T> не имеют подсчёта ссылок

Все приложения на Rust прямо или косвенно импользуют unsafe, теряя безопасность памяти и защиту от data races.

Вы не поняли суть Rust

Паники часто возникают

Ложь, в приведённом вами выражении вы сами целенаправленно вызываете панику, они не возникают сами по себе

(кстати, как вам такой синтаксис простого приведения типов?)

Никак, потому что вы не дали никакой информации о том, что такое result и зачем вы всю эту чушь вообще написали

maybe-null-указателю

У указателей не существует метода and_then, так что где-то тут вы опять лжёте

Вот пример того же кода на языке Аргентум

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

Ну и раз уж речь зашла про Аргентум:

работая без ... unsafe

Загоревшись интересом, как такие чудеса в принципе возможны, я заглянул в исходники на гитхабе, а там стандартная библиотека написана на C — то есть она вся автоматически unsafe

За конкретным примером даже далеко ходить не пришлось, можно взять сразу хелловорлд — стандартная функция log не стесняясь напрямую вызывает fputs, вызов которой конечно же является unsafe: вызывающий её программист обязан самостоятельно проконтролировать, что строка s->chars является null-terminated и что её чтение не приведёт к чтению за пределами выделенной памяти

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

работая без ... unsafe

В языке Argentum нет unsafe mode, в отличие от Rust.

вызывающий её программист обязан самостоятельно проконтролировать, что строка s->chars является null-terminated и что её чтение не приведёт к чтению за пределами выделенной памяти

Вы совершенно правы. Строка, s->chars является null-terminated, это гарантируется самим языком. Никакие операции над строками не могут создать последовательность utf-8 символов без 0-терминатора. Если идти дальше, s никогда не может быть null, это гарантируется системой типов Аргентума и никогда не может показывать на мусор. Поэтому выражение fputs(s->chars, stdout); безопасно.

Но конечно, FFI это всегда дыра в безопасности (escape hatch, как любят писать в научных статьях). С этим ничего сделать к сожалению нельзя, можно только сократить периметр общения с внешним миром до рантайм-библиотеки. Это, кстати, справедливо и для всех managed-языков, таких как JS/Java/Python и т.д.

Строка, s->chars является null-terminated, это гарантируется самим языком.

И снова ложь. Открываем объявление структуры AgString:

char     chars[1];    // variable size zero terminated utf8

Здесь не только нет никаких гарантий безопасности (нет, комментарий «zero terminated» не является такой гарантией), но и вообще большие подозрения на неопределённое поведение. Вы проводите странные манипуляции со структурой, выделяя больше памяти чем размер структуры и обращаясь за пределы структуры, чтобы записать целую строку в массив размером один элемент — жутко страшный код.

Кроме того, вы вручную подсчитываете количество выделяемой памяти и столь же вручную пишете нулевой байт в s->chars[size] — ничего из этого язык C не проверяет, все эти операции являются unsafe и работают только благодаря вашей собственной аккуратности, а не каким-то там гарантиям.

Почти каждая строчка в runtime.c — это потенциальный выстрел в ногу, о каких вообще гарантиях может идти речь?

Последнее поле char[1] и malloc(sizeof(MyStruct)+extra_data)- это классический подход для представления структур переменного размера, который работает во всех версиях C (в С99) его расширили до char[]. Вы не обязаны этого знать, это низкоуровненое программирвование.

Конечно, рантайм любого целевого языка как правило пишется на языке более низкого уровня, менее безопасном, и это само по себе не делает целевой язык менее safe. Например Python VM реализована на С со страшной адресной арифметикой и "небезопасными" операциями. И при этом Python - managed и memory safe язык.

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

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

Всё верно: unsafe Rust — язык более низкого уровня, менее безопасный чем safe Rust

Все гарантии безопасности языка распространяются на программы написанные на этом языке

Всё верно: гарантии безопасности safe Rust распространяются только на safe Rust, при этом внутренняя реализация рантайма на unsafe Rust не играет никакой роли

любая успешно скомпилированная программа на этом языке может упасть только при

...любой случайной вашей опечатке в unsafe-коде runtime.c

и это само по себе не делает целевой язык менее safe

То есть вы признаёте свою неправоту и отказываетесь от пункта 4 своего изначального комментария

...любой случайной вашей опечатке в unsafe-коде runtime.c

Код настолько небольшой, что его реально полностью проконтролировать и покрыть тестами (как это сделано в JVM, VM Python, .NET и прочих managed языках, где рантайм тоже написан на С).

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

Всё верно: гарантии безопасности safe Rust распространяются только на safe Rust, при этом внутренняя реализация рантайма на unsafe Rust не играет никакой роли

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

То есть вы признаёте свою неправоту и отказываетесь от пункта 4 своего изначального комментария

Вы не понимаете суть уровней безопасности кода. Еще раз: существует доверенный код - супервизор, виртуальная машина, рантайм - этого кода мало, он нечасто меняется и хорошо покрыт тестами. И существуют тонны менее качественного кода, безопасность которого гарантируется исполнением в VM или JIT/AOT копмпиляцией из высокоуровневого языка, не допускающего опасные операции. Проблема Раста в том, что он позволяет неконтролируемо встраивать небезопасные фрагменты кода прямо внутрь безопасных, полностью ломая уровни безопасности.

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

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

unsafe-блоки в Rust ещё меньше и их ещё легче проконтролировать и покрыть тестами

любой крейт который ты используешь может в любой момент стать unsafe

Это не проблема Rust, лично вам никто не запрещает контролировать отсутствие unsafe-блоков в используемых вами крейтах (или вообще не использовать сторонние крейты)

существует доверенный код

Ваш runtime.c не является доверенным, потому что вы тоже человек и можете совершать ошибки

Более того, ваш runtime.c является менее доверенным чем unsafe-блоки в Rust: сообщество Rust выработало очень строгий этикет написания unsafe-блоков, помогающий обеспечить их безопасность, такие как обязательные комментарии // SAFETY: с обоснованием, почему проводимая unsafe-операция является безопасной (или по крайней мере считается безопасной написавшим её программистом), в то время как ваш runtime.c — стандартная сишная мешанина, которую страшно читать

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

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

> гарантий целостности для структур, размещённых в хипе

О чём конкретно речь?

Раст рекламируется как язык, следящий за владением, и не позволяющий одновременных мутабельных алиасов. Но эти гарантии провеяются на этапе компиляции только для стековых объектов и заимствований. В то время как в хипе вызовы borrow/borrow_mut не проверяются на стадии компиляции, а вместо этого используя счетчики внутри RefCell убивают ваше приложение в рантайме.

> Управление объектами в хипе основано на умных указателях с подсчётом ссылок

Ложь, контейнеры вроде Box<T> и Vec<T> не имеют подсчёта ссылок

Контейнеры вроде Box<T> не позволяют создавать иерархии (графы) объектов, поскольку на объект в таком контейнере нельзя иметь ссылку из другого объекта. Поэтому Box<T> это про полиморфизм и рекуривные (безразмерные) типы а не про иерархические структуры данных в хипе.

> Все приложения на Rust прямо или косвенно импользуют unsafe, теряя безопасность памяти и защиту от data races.

Вы не поняли суть Rust

Похоже да, я не понял суть Раста. Он рекламируется как safe, но его ограничения приводят к тому, что 20-30% всех приложений на Расте непосредственно используют unsafe блоки кода, а 50-80% приложений имеют зависимости первого уровня от unsafe crates. Получается, что язык не совсем safe?

> Паники часто возникают

Ложь, в приведённом вами выражении вы сами целенаправленно вызываете панику, они не возникают сами по себе

Если простое выражение на языке успешно компилируется, а при исполнении с некоторой пероятностью падает - это не нормально. Вы не находите?

> (кстати, как вам такой синтаксис простого приведения типов?)

Никак, потому что вы не дали никакой информации о том, что такое result и зачем вы всю эту чушь вообще написали

Вам надо что-то делать со своим гневом.

Давайте по-другому, допустим у нас есть nullable-ссылка на полиморфный объект, например result: Option<Rc<RefCell<dyn Any>>> // простой синтаксис, правда.
Как получить из нее Option<Rc<RefCell<MyType>>>?

> maybe-null-указателю

У указателей не существует метода and_then, так что где-то тут вы опять лжёте

Классическая Maybe-monad в Расте == Option. Поэтому maybe-null-указатель - как раз имеет Option::and_then

Вам определенно нужно или исключить из лексикона слово "лжете" или окончательно перейти на стиль "врешь собака".

> Вот пример того же кода на языке Аргентум

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

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

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

убивают ваше приложение в рантайме

И снова ложь. Во-первых, паники не убивают приложение, их можно перехватить и обработать (хотя скорее всего не нужно). Во-вторых, здесь добавляется ваша ложь из пункта 5: вас никто не заставляет вызывать заведомо паникующие методы, вы вполне можете использовать try_borrow/try_borrow_mut

не позволяют создавать иерархии (графы) объектов

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

Получается, что язык не совсем safe?

Никакой язык не может быть полностью safe даже в теории. Аргентум тоже оказался unsafe, и, что гораздо хуже — Аргентум, будучи написанным на C/C++, не контролирует своё собственное использование unsafe. Rust лучше уже хотя бы в том плане, что он пытается изолировать unsafe-код в unsafe-блоках

Если простое выражение на языке успешно компилируется, а при исполнении с некоторой пероятностью падает - это не нормально. Вы не находите?

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

Option<Rc<RefCell<dyn Any>>>

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

Классическая Maybe-monad в Расте == Option

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

Домашнее задание для читателей — посчитать, сколько правил демагога использовал kotan-11 в своих комментариях

Придумайте более адекватный пример

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

Готово. Максимально приближенный к реальности но все еще реализуемый в пару сотен строк бенчмарк языков. https://habr.com/en/articles/955158/
Можете реализовать его на Расте (или любом языке по вашему выбору), чтобы доказать его применимость.

Вы точно понимаете, что такое бенчмарк (benchmark)?

Вот что про этот термин говорит[1] Wiki:

Benchmark (computing), the result of running a computer program to assess performance

ключевые слова в этом определении — "running" и "performance", тогда как Вы просите доказать, что то, что Вы захотелиможно написать на Rust-е.

Это попахивает либо лабораторной работой, либо «тестовым заданием» при приёме на работу, которые злоумышленники-работодатели рассылают кандидатам и просто используют их работу в production-е (P.S.: кстати, в статье так и написано: «тестовое задание»).

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

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

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

[1] https://en.wikipedia.org/wiki/Benchmark

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

Уже второй или третий ИИ-слоп от этого автора с этим интро.

Стоит ли говорить что ни в одной статье не было практики ни от автора, ни от ИИ.

Стоит забанить аккаунт за спам.

Почему сразу хардкорный Rust? Есть же производительные языкы с меньшим порогом входа - C#, Java, Go.

В них всех тоже есть GC, так что шило на мыло. Бывали истории о переходе с Go на Rust из-за тормозов

Что за 2 крайности? Там посередине есть еще еще гошечка, и миллион других языков

Но в целом ИИ все правильно написал - список для выбора стоит /не стоит нормальный

н

Sign up to leave a comment.

Articles