Обновить
46

Типострадалец

13
Подписчики
Отправить сообщение

В общем, property-based testing — это эксперимент, который надо уметь ставить, и его результаты тоже надо уметь обрабатывать. Об этом прекрасно рассказал автор QuickCheck в видео John Hughes — Building on developers' intuitions (...) | Lambda Days 19.

Понимаю, что статья давняя, но можете вставить ссылку на искомое видео, чтобы читателям не пришлось искать самостоятельно?

Значит, вы ни разу в жизни не пробовали писать эффективные

  • стейтмашины

  • парсеры

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

  • зависимое выделение/освобождение ресурсов

А вот использование goto для освобождения ресурсов - это так костыль в сишечке. В практически всех языках для этого есть более вменяемые инструменты: RAII в C++/D/Rust, try-with-resources в Java, using в C#, context managers в Python, bracket pattern в StandardML/Ocaml/Haskell. Причём конкретно RAII напишет ровно такой же код, что и сишник руками, только без ошибок.

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

Разбиение по парам зачем-то написано в виде tt-muncher, и это при том, что его можно написать напрямую:

macro_rules! pairs {
    ($($a:tt $b:tt)*) => { with_firsts($($a),*); with_seconds($($b),*); }
}

Зато если запустить санитайзер gcc, вот он вдоволь срабатывает.

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

Для Rust было бы неплохо. Есть Clippy, но там, ЕМНИП, нет никаких кросс-функциональных вариантов анализа, только в пределах одной функции. Ну и некоторые ошибки, которые PVS-studio детектирует, от языка слабо зависят (вроде V6004)

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

Они никогда не заменят статические анализаторы, потому что:
а) никакая модель, какой бы навороченной она бы не была, не может диагностировать паттерны ошибок, которых не было в обучающих данных, и добавить новое правило в анализатор проще, чем дообучать модель на многих примерах.
б) LLM склонны к галлюцинациям, причём довольно убедительно выглядящим, а от качественного статанализатора ждут низкого false positive rate.

Ну да, опыт показывает, что они ещё и просто криво работают.

То, что MinGW пытается имитировать unix-like окружение на винде

язык молод и ограничен в возможностях

Тем временем возможности C

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

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

Динамическую диспетчеризацию в Rust делают через трейт-объекты. Так как сам трейт-объект не является Sized типом, напрямую передавать его нельзя, можно только по указателю. Другое дело, что этот указатель совершенно не обязательно должен быть владеющим. В частности, пример в статье про динамический диспетчер можно написать иначе, без ненужных аллокаций в куче:

// такие же определения Processable, а также DataA, DataB и реализаций Processable для них

fn dynamic_processing(item: &dyn Processable) {
    item.process();
}

let a = DataA;
let b = DataB;

dynamic_processing(&a); // Выведет "DataA обрабатывается"
dynamic_processing(&b); // Выведет "DataB обрабатывается"

Причём за счёт deref coercion приводить ссылки явно к &dyn Processable на вызывающей стороне не требуется.

А аргументы будут или это опять голословное утверждение?

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

А можете привести конкретные примеры?

Rust-код в статье выглядит сильно неоптимальным. Именно, он на каждой внутренней итерации преобразовывает rust-овый Vec в массив JS, что подразумевает копирование и боксинг данных (каждого отдельного числа), а потом итоговый Vec копируется ещё раз при переводе в значение Javascript. Это очень много лишних операций. Лучше было бы на стороне Rust предаллоцировать массивы и потом их заполнять - или, ещё лучше, использовать типизированный Float64Array и избежать конвертации вовсе. Правда, такой типизированный массив придётся делать плоским, что может повлиять на удобство со стороны Javascript

...после ленивой годичной практики языка, я все же был вынужден заключить, что в разрезе embedded программирования (где можно и нужно активно использовать программирование времени компиляции) Rust не только не делает качественно скачка вперед, но и даже в чем-то уступает C++ в 2024 году.

А вот про это можно поподробнее? В чём уступает? Мне на ум только меньший охват целевых платформ приходит.

Всегда можно понизить уровень сложности

А я вот прошёл Doom Eternal первым и потом прошёл Doom 2016 через силу. Потому что в плане геймплея Doom 2016 уступает почти по всем аспектам, сюжет более невнятный, а одинаковая оранжевая гамма всех уровней надоедает

Новые интересные концепции, языковые конструкции, приемы, устранение недостатков старых языков...

Вот только ничего из этого в Hare нет.

Автора почему-то тотально удалили с Хабра. Вот ссылка на копию в web archive

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность