В общем, 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 и его динамических возможностей новые связи в этот граф могут быть добавлены произвольным внешним кодом и даже в зависимости от рантайм-данных.
Зато если запустить санитайзер gcc, вот он вдоволь срабатывает.
Если вы именно санитайзер имели в виду, то тут как раз нет ничего удивительного: статические анализаторы и динамические детектируют разные баги, с довольно небольшим пересечением.
Для Rust было бы неплохо. Есть Clippy, но там, ЕМНИП, нет никаких кросс-функциональных вариантов анализа, только в пределах одной функции. Ну и некоторые ошибки, которые PVS-studio детектирует, от языка слабо зависят (вроде V6004)
хотя большие языковые модели уже на пятки наступают
Они никогда не заменят статические анализаторы, потому что: а) никакая модель, какой бы навороченной она бы не была, не может диагностировать паттерны ошибок, которых не было в обучающих данных, и добавить новое правило в анализатор проще, чем дообучать модель на многих примерах. б) LLM склонны к галлюцинациям, причём довольно убедительно выглядящим, а от качественного статанализатора ждут низкого false positive rate.
Динамическую диспетчеризацию в 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 уступает почти по всем аспектам, сюжет более невнятный, а одинаковая оранжевая гамма всех уровней надоедает
Понимаю, что статья давняя, но можете вставить ссылку на искомое видео, чтобы читателям не пришлось искать самостоятельно?
Как-то выходит без этого. И да, в парсерах для эффективности стоит переходить с написания отдельного лексера и собственно парсера на паерсер, который меняет состояние по отдельным байтам, но руками писать такое сродни безумию.
А вот использование goto для освобождения ресурсов - это так костыль в сишечке. В практически всех языках для этого есть более вменяемые инструменты: RAII в C++/D/Rust, try-with-resources в Java, using в C#, context managers в Python, bracket pattern в StandardML/Ocaml/Haskell. Причём конкретно RAII напишет ровно такой же код, что и сишник руками, только без ошибок.
Проблема в том, что это не дерево. Более того, с учётом нулевых возможностей для сокрытия определений в Python и его динамических возможностей новые связи в этот граф могут быть добавлены произвольным внешним кодом и даже в зависимости от рантайм-данных.
Разбиение по парам зачем-то написано в виде tt-muncher, и это при том, что его можно написать напрямую:
Если вы именно санитайзер имели в виду, то тут как раз нет ничего удивительного: статические анализаторы и динамические детектируют разные баги, с довольно небольшим пересечением.
Для Rust было бы неплохо. Есть Clippy, но там, ЕМНИП, нет никаких кросс-функциональных вариантов анализа, только в пределах одной функции. Ну и некоторые ошибки, которые PVS-studio детектирует, от языка слабо зависят (вроде V6004)
Они никогда не заменят статические анализаторы, потому что:
а) никакая модель, какой бы навороченной она бы не была, не может диагностировать паттерны ошибок, которых не было в обучающих данных, и добавить новое правило в анализатор проще, чем дообучать модель на многих примерах.
б) LLM склонны к галлюцинациям, причём довольно убедительно выглядящим, а от качественного статанализатора ждут низкого false positive rate.
Ну да, опыт показывает, что они ещё и просто криво работают.
То, что MinGW пытается имитировать unix-like окружение на винде
Тем временем возможности C
Нет, дело именно в плюсах. Это настолько кривой язык, что на нём практически невозможно писать безопасно, даже если очень хочется
Динамическую диспетчеризацию в Rust делают через трейт-объекты. Так как сам трейт-объект не является
Sizedтипом, напрямую передавать его нельзя, можно только по указателю. Другое дело, что этот указатель совершенно не обязательно должен быть владеющим. В частности, пример в статье про динамический диспетчер можно написать иначе, без ненужных аллокаций в куче:Причём за счёт deref coercion приводить ссылки явно к
&dyn Processableна вызывающей стороне не требуется.А аргументы будут или это опять голословное утверждение?
А можете привести конкретные примеры?
Rust-код в статье выглядит сильно неоптимальным. Именно, он на каждой внутренней итерации преобразовывает rust-овый
Vecв массив JS, что подразумевает копирование и боксинг данных (каждого отдельного числа), а потом итоговыйVecкопируется ещё раз при переводе в значение Javascript. Это очень много лишних операций. Лучше было бы на стороне Rust предаллоцировать массивы и потом их заполнять - или, ещё лучше, использовать типизированныйFloat64Arrayи избежать конвертации вовсе. Правда, такой типизированный массив придётся делать плоским, что может повлиять на удобство со стороны JavascriptА вот про это можно поподробнее? В чём уступает? Мне на ум только меньший охват целевых платформ приходит.
Всегда можно понизить уровень сложности
А я вот прошёл Doom Eternal первым и потом прошёл Doom 2016 через силу. Потому что в плане геймплея Doom 2016 уступает почти по всем аспектам, сюжет более невнятный, а одинаковая оранжевая гамма всех уровней надоедает
Вот только ничего из этого в Hare нет.
Автора почему-то тотально удалили с Хабра. Вот ссылка на копию в web archive