Pull to refresh
3
0

Разработчик

Send message

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

1) Есть альтернативы, например, в виде флага, который ставится в 1 по ошибке, и который можно проверять (точно так же, как по стандарту IEEE754 это затребовано task-local для плавучки). Можно придумать переопределение режима и флага для своего куска кода, не обязательно в TLS, годится любая указанная переменная.

Можно, кто же спорит. Но жёстко контроллируемую математику не ввели. Видимо, посчитали чрезмерной в контексте языка.


2) Вообще, позиция отрицания «anything can throw» это перегиб даже больший, чем предыдущее активное введение структурных исключений во все новые языки. И паника, которая по умолчанию что-то печатает, по такому событию — тоже.
Можно было бы подумать в эту сторону, но не отвергать исключения совсем.

Панику стоит рассматривать не как исключение "что-то пошло не так", а аналог сигнала "что-то КОНКРЕТНО пошло не так".


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

Неточно выразился. Под "срач" здесь и дальше понимаются возмущённые крики определённой аудитории "Оверхед!!!". С учётом что Rust позиционируется как более безопасная и в чём-то простая замена C/C++, это было бы смертельно.


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

Справедливости ради, большинство нынешних уязвимостей вызвано скорее ошибками доступа к памяти/ресурсам, а не арифметики как таковой. Мне бы тоже было интересно посмотреть на проверяемую компилятором арифметику.

По поводу устойчивости к ошибкам человека надо читать 1ю часть. Простой и понятный и при этом однозначный синтаксис тут в помощь.

Грамматика насколько мне известно как минимум однозначная. По крайней мере, дичи вроде C/С++ most vexing rule или counter-clockwise rule нет в природе. Примеры контекстно-зависимых элементов.
Простота и понятность — в целом вещи субъективные. Для знакомых с Си-подобными языками читать и понимать труда не составляет.


Перерасход памяти для строк зависит от реализации. Пусть строка s1 содержит 1024 символа. Сколько будет задействовано памяти (и какой — стек, хип?) после операций s1[14] = 'x'? s1 += 'x'?

Строки реализованы в виде владеющего типа String и невладеющего типа-диапазона &str. Первый выделяет память в куче, второй — ссылается на уже выделенную строку или её часть. Строковые литералы выделяются в data section и рассматриваются как &'static str.


Пакеты с кастомными строками


ФП — повсюду
— прошу ссылку для оценки

В целом довольно сильная ориентация на ФП:



Если у Вас есть более конкретные требования к поддержке ФП в языке, напишите пожалуйста.


Контроль времени выполнения — это не про рантайм этап, а про время исполнения, например что функция выполнялась не дольше 100мс.

Я себе не совсем представляю, как язык может это гарантировать в отрыве от ОС.


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


Мне кажется, проблема в том, что мы не совсем об одном и том же разговариваем. Вы, похоже, говорите в основном про SPARK, который хоть и статически верифицируем, но в силу специфики имеет ограниченный круг применения. Я в основном говорю про Ada в общем. Так о чём будем продолжать разговор? Если про SPARK — предлагаю закончить, т.к. там благодаря стат. верификации большинства рантайм проверок и так не будет. И проблем с "не закрыли файл" тоже. Просто не во всех приложениях можно на этапе проектирования просчитать, сколько оно сожрёт ресурсов. Я бы сказал, в очень небольшом числе приложений.

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

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

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

Зато Unchecked_Deallocation это супер современно.

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

Окей. Ткните меня пожалуйста носом в аналог std::unique_ptr, std::shared_ptr, std::weak_ptr. Я серьёзно. Потратил часа два или три и так и не нашёл. Т.е. что делать если мне нужно в контейнер положить не само значение, а ссылку на него?

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

К сожалению, любое решение имеет свою цену. К примеру, исключения позоляют рапортовать любую ошибку откуда угодно. Но приводят к тому, что необходимо реально ждать такой ошибки из каждой щели. Почитайте про weak/strong exception guarantee в С++. В некоторых случаях обеспечение даже слабой гарантии превращает код в лапшу.

https://doc.rust-lang.org/std/panic/fn.set_hook.html


The default hook prints a message to standard error and generates a backtrace if requested, but this behavior can be customized with the set_hook and take_hook functions.

https://doc.rust-lang.org/std/primitive.i32.html#method.checked_add и далее вниз по доке. Для остальных примитивов аналогичный набор.

Я честно говоря так и не понял, о какой безопасности говорят сторонники Ada. В языке с исключениями, при отключенной сборке мусора, предполагается ручное на уровне С управление ресурсами. А RAII сделан через отдельный базовый класс, что сильно срезает его полезность. Т.е. возможностей отстрелить себе аллоцированный ресурс по самый thread header больше, чем в C++.

Давайте немножко разделим.


По поводу обработки числовых переполнений. Здесь КМК столкнулись требования zero overhead и безопасности. Во-первых, в Rust сознательно отказались от исключений в пользу Result. Следовательно, бросить исключение из оператора сложения мы не можем. Иначе был бы C++ "anything can throw". К тому же, проверка каждой операции приводила бы к оверхеду. Результатом был бы жуткий срач. Далее, делать всю арифметику return Result — убить эргономику. Ещё один потенциальный срач. Для тех, кому нужна предсказуемая арифметика, у каждого целочисленного типа Rust есть набор методов checked/saturating/wrapping/overflowing. У чисел с плавающей точкой есть свой набор контроллируемых операций.


Теперь, по поводу паник. Паники предназначены для выражения ошибок "Шеф! Всё пропало!". По умолчанию паники реализованы через С++-подобный механизм исключений, но можно реализовать свой паник хендлер либо выставить panic=abort. По умолчанию поймать панику можно — std::panic::catch_unwind.

Попробую, хотя у Вас в некоторых пунктах намешано много всего


  1. Надёжность
    • "Устойчивость к ошибкам человека..." Честно говоря так и не понял, какие конкретные критерии.
    • Юникодные строки — да. Плюс ОС-зависимые строки отдельно для желающих. Защита от перерасхода памяти — не совсем понятно. Строковые слайсы? Cow? Что именно? Дата-время — есть std::time, для более точной оценки уточните требования.
    • Приведение типов только явное. Контроль переполнения и потери точности — через отдельные методы на примитивных типах (overflow_add etc.).
    • Контроль границ — есть.
    • Контроль памяти — compile-time borrow checker, non-null по умолчанию. Контроль стека — приводит к панике. Защита от фрагментации — нет, т.к. нет GC (или я не понял о чём Вы).
    • Обработка ошибок — ADT Result с сахаром плюс panics для ошибок вроде division by zero, bad alloc etc. ADT, RAII — используется в полный рост.
    • Модульность — иерархическая, crate как единица сборки. Пакетный менеджер и менеджер зависимостей из коробки.
  2. Функциональность
    • ООП — нет в классическом понимании. Дженерики есть. Трейты выполняют функцию и концептов, и интерфейсов.
    • ФП — повсюду.
    • Контракты — нет. Юниттесты — встроены в язык и тулчейн.
    • Доступ к железу — не совсем понятно что именно надо. По идее зависит от платформы. Проекты микро-ОС для микроконтроллеров есть. Для ассемблерных вставок ЕМНИП есть макрос asm! в unstable. В целом — идеология языка никак не мешает такому доступу быть.
    • Многопоточность — классическая с аппаратными потоками и примитивами. Трейты Send/Sync для контроля перемещения объектов между потоками и контроля доступа из множества потоков к объектам. Акторы, асинхронка — в отдельных крейтах (см. tokio, std::futures, actix etc.). Микросервисы — не совсем понятно каким боком они к языку, но есть несколько крейтов для простой сборки оных.
    • Сетевые функции — базовая сеть в stdlib, остальное на crates.io
    • ГУИ — в основном биндинги к Gtk etc.
    • Файловый ввод-вывод — есть.
  3. Безопасность
    • Контроль времени выполнения — там где проставлены panics или возврат ошибок. В целом опирается на безопасность времени компиляции.
    • Очистка выделяемой/освобождаемой памяти — по умолчанию нет, т.к. принцип zero overhead. Можно кастомизировать глобальный аллокатор либо сделать свои арены.

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

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

Пожалуйста вычитывайте свои статьи. Читать Множество Слов С Большой Буквы С Очепятками, при начисто сбитом форматировании, тяжело.
И, кстати, какие предсказания способна сделать ваша модель? Про опыт Резерфорда и вообще объяснение целой кучи квантовых явлений в рамках вашей модели уже спросили.

Вброшу свою ложечку. Судя по https://old.reddit.com/r/cpp/comments/akihlv/c_modules_might_be_deadonarrival/, эти самые констрейнты заключаются в "шоб мы могли свой код времён Кеннеди перенести в новый стандарт в 2 строчки".
Т.е. module lookup хотят сделать зависимым от содержимого файлов (а там имя модуля может задаваться в зависимости от макроссов, упс...) просто потому, что, грубо говоря, есть ОС, которая не умеет больше одного слоя директорий в своей ФС. Или ОС, которая не знает, что такое расширение. Или в байте 9 3/4 бит...

Information

Rating
Does not participate
Location
Украина
Registered
Activity