Замечу, кстати, что в расте можно сделать себе заморочку с получением элемента по индексу — буквально через clippy запретить обычную [] индексацию и использовать .get метод, который возвращает Option, просто это уже opt-in поведение, если надоело паники ловить на пустом массиве, например.
Но ведь вопрос что делать с исключением/паникой в коллбэке - это исключительно вопрос логики библиотеки? Как здесь язык может помочь, любой?
Где-то приемлемо пропустить панику и завалить библиотеку, где-то можно заставить коллбэки быть fallible - то есть они могут вернуть Result::Err с разными причинами и либа как-то их обрабатывает - в таком случае паника просто преобразуется в тот же Err и дальше вы делаете всю стандартную логику.
Тут может возникнуть вопрос с тем что коллбэк может успеть до паники поменять ваш стейт и в итоге состояние будет в каком-то виде на который внешний код не рассчитывает - но, опять же, тут нет хорошего пути решения.
То, что в эрланге это решается тем что рантайм/стд в таком случае перезапускают воркеры - это только один из возможных способов обработки, на уровне языка конкретного такое может решаться только через общие соглашения или через явное требование указать способ обработки таких ситуаций при инициализации библиотеки, чтобы внешнему пользователю пришлось посмотреть какие вообще доступны варианты и их плюсы/минусы. И вот тут кстати раст как раз позволит сделать так, чтобы не указав этот параметр ты вообще не смог библиотеку использовать.
Понимаю что такой подход добавляет когнитивную нагрузку на вызывающего, но других решений просто нет - только разумные дефолты с возможностью их изменения.
Про десериализацию/анбоксинг я вообще не понимаю примера - в расте принято по умолчанию что такие операции возвращают Result, который панику может инициировать только при unwrap - и тут компилятор как раз и поможет, вынуждая явно обрабатывать ошибку. И это как раз и есть общее соглашение на уровне языка. Конкретный код/либа может его игнорить, разумеется, но тут уж точно ничего на уровне языка/компилятора не поделаешь.
Так а примеры то приведете? Может даже без кода, мне действительно интересно чтобы иметь в виду для себя в дальнейшем. Все три ваши статьи я читал, нигде там подобных поинтов не видел, хотя это как раз, на мой взгляд, и есть важная часть "что не так с языком". Можете даже отдельную статью написать если в коммент не влезает.
Ну и еще раз укажу - исходный мой коммент был про то, что раст с клиппи на максималках как раз помогает защищаться от тупых ошибок ллмок на уровне кода, что вместе с высокоуровневыми тестами (для уровня логики) помогает быть уверенным в том что код работает.
Ага, ну тут мы сходимся. И как раст тут мешает? Ваш пример с let it crash как раз же и показывает что на нем это вполне можно сделать - просто тот рантайм эрланга который отлавливает ошибки "пользовательского" кода и перезапускает его - надо написать вручную. Но это явно не проблема самого языка, он просто работает на уровень ниже чем erlang (что вы и доказали успешно переписав часть рантайма эрланга на раст).
Я просто не понимаю какие дикости может вызывающий код натворить, чтобы нельзя было в либе на расте это отловить-то?
1.9.0 - это который 9 лет назад вышел? Ну думаю уже немного неактуальный пример (да и до этого его скорее можно было в nightly использовать).
Мне на самом деле был бы интересен реальный пример где раст не дает возможности для либы сделать корректный и безопасный api, даже если мы говорим про пользовательские типы.
Философия «на моей стороне всё работает» редко порождает действительно хорошие библиотеки.
Ну это вопрос философский - где прокладывать границу между кейсами которые библиотека (в лице автора) может/хочет поддерживать, а где уже говорить "хотите странного, делать не собираюсь".
Да и в целом непонятно что вы имеете в виду - а как автор библиотеки может гарантировать работу кода на вызывающей стороне вообще?
Ну я говорю про application-уровень, про который и писал автора. Но даже если говорим про уровень библиотеки и раст - он же как раз и предоставляет возможности защититься от большинства проблем со стороны вызывающего кода прямо на уровне типов + defensive программирования на уровне конкретных публичных методов.
Программист всегда сможет завалить программу - просто если он делает это через unsafe блоки, то это по большей части его проблема, разработчика библиотеки должно парить только возможность сломать его код через публичный api.
Для алгоритмических ошибок и есть e2e тесты. Их, конечно, не для всех проектов возможно нормально сделать, но что-то придумать можно всегда. Тогда вайб-кодеру останется продумывать варианты использования и записывать их в тесты - которые, кстати, тоже можно генерить ллмкой.
И вообще я говорю скорее про ошибки уровня "запись в уже закрытый канал" который на том же го уронят программу с паникой, тогда как в расте можно в принципе запретить expect/unwrap и быть уверенным что все ошибки обрабатываются... Ну хоть как-то.
Если добавить к этому еще и запрет на array[i] - чтобы всегда использовался array.get, то паники в коде будут очень большой редкостью, в результате чего ты можешь быть уверенным что программа ведет себя по спецификации в виде тестов.
Это конечно не отменяет описанную автором проблему с плохой архитектурой - но в целом описанные "тесты на архитектуру" есть продолжение той же идеи с validate-first подходом, но на более высоком уровне.
Вообще, генерить код через LLM для более-менее больших вещей надо через validation-first подход. Я пока выбрал подход с e2e тестами вход и выход которых зафиксирован в yaml файлах - так ты хотя бы уверен что внутренняя логика работает как задумывалось.
Правда я еще и проект делаю на Rust с максимальным уровнем clippy - тогда компилятор за меня валидирует отсутствие всяких тупых ошибок от нейросеток. Интересно было бы попробовать ваш подход с валидацией архитектуры попробовать прикрутить как плагин к cargo
В 9 классе на экзамене по геометрии как раз выпала теорема Пифагора. Доказал как раз по схеме "смотри" - к гипотенузе C достраиваем квадрат, к его сторонам 3 - еще 3 таких же треугольника чтобы они образовывали бОльший квадрат. Площадь бОльшего квадрата будет (a + b) ^ 2, по формуле раскладывается на a^2 + b^2 + 2ab - где 2ab это как раз площади 4 треугольников и соотвественно площадь исходного квадрата с^2 равна a^2 + b^2 - то есть площадь внешнего квадрата минус площадь треугольников.
А можно хоть какие-то подробности добавить? Хотя бы ссылку на бенчмарки или еще что-то
@Boomburum жесть конечно ваши коллеги ущербно себя ведут.
Так, подождите, про письмо от ПОДДЕРЖКИ ХАБРА - это вы серьезно? ЧИВО БЛИН?!
https://share.google/aimode/H3WGmYMQ8sRJjKfq2
Считайте это вместо LMGTFY, вопрос просто действительно странный.
Во-первых это не стд а внешняя либа.
Во-вторых у него есть Send+Sync - то есть он (как минимум - предполагается что) потокобезопасный.
Замечу, кстати, что в расте можно сделать себе заморочку с получением элемента по индексу — буквально через clippy запретить обычную [] индексацию и использовать .get метод, который возвращает Option, просто это уже opt-in поведение, если надоело паники ловить на пустом массиве, например.
Там же в конце статьи про них два раза написано, или автор потом уже добавил?
Я говорю про то, чтобы автоматически валидировать переделки ИИ вместо того чтобы смотреть изменения структуры кода глазами каждый раз
Ну я скорее про то что после изменений генерить этот ямл заново и валидировать какие-то общие правила, как описывал автор статьи?
О, как раз то о чем я говорилил выше. А тесты через этот инструмент потом не пытались делать?
Но ведь вопрос что делать с исключением/паникой в коллбэке - это исключительно вопрос логики библиотеки? Как здесь язык может помочь, любой?
Где-то приемлемо пропустить панику и завалить библиотеку, где-то можно заставить коллбэки быть fallible - то есть они могут вернуть Result::Err с разными причинами и либа как-то их обрабатывает - в таком случае паника просто преобразуется в тот же Err и дальше вы делаете всю стандартную логику.
Тут может возникнуть вопрос с тем что коллбэк может успеть до паники поменять ваш стейт и в итоге состояние будет в каком-то виде на который внешний код не рассчитывает - но, опять же, тут нет хорошего пути решения.
То, что в эрланге это решается тем что рантайм/стд в таком случае перезапускают воркеры - это только один из возможных способов обработки, на уровне языка конкретного такое может решаться только через общие соглашения или через явное требование указать способ обработки таких ситуаций при инициализации библиотеки, чтобы внешнему пользователю пришлось посмотреть какие вообще доступны варианты и их плюсы/минусы. И вот тут кстати раст как раз позволит сделать так, чтобы не указав этот параметр ты вообще не смог библиотеку использовать.
Понимаю что такой подход добавляет когнитивную нагрузку на вызывающего, но других решений просто нет - только разумные дефолты с возможностью их изменения.
Про десериализацию/анбоксинг я вообще не понимаю примера - в расте принято по умолчанию что такие операции возвращают Result, который панику может инициировать только при unwrap - и тут компилятор как раз и поможет, вынуждая явно обрабатывать ошибку. И это как раз и есть общее соглашение на уровне языка. Конкретный код/либа может его игнорить, разумеется, но тут уж точно ничего на уровне языка/компилятора не поделаешь.
Так а примеры то приведете? Может даже без кода, мне действительно интересно чтобы иметь в виду для себя в дальнейшем. Все три ваши статьи я читал, нигде там подобных поинтов не видел, хотя это как раз, на мой взгляд, и есть важная часть "что не так с языком". Можете даже отдельную статью написать если в коммент не влезает.
Ну и еще раз укажу - исходный мой коммент был про то, что раст с клиппи на максималках как раз помогает защищаться от тупых ошибок ллмок на уровне кода, что вместе с высокоуровневыми тестами (для уровня логики) помогает быть уверенным в том что код работает.
Тут мы кажется тоже сошлись во мнении.
Ага, ну тут мы сходимся. И как раст тут мешает? Ваш пример с let it crash как раз же и показывает что на нем это вполне можно сделать - просто тот рантайм эрланга который отлавливает ошибки "пользовательского" кода и перезапускает его - надо написать вручную. Но это явно не проблема самого языка, он просто работает на уровень ниже чем erlang (что вы и доказали успешно переписав часть рантайма эрланга на раст).
Я просто не понимаю какие дикости может вызывающий код натворить, чтобы нельзя было в либе на расте это отловить-то?
1.9.0 - это который 9 лет назад вышел? Ну думаю уже немного неактуальный пример (да и до этого его скорее можно было в nightly использовать).
Мне на самом деле был бы интересен реальный пример где раст не дает возможности для либы сделать корректный и безопасный api, даже если мы говорим про пользовательские типы.
Ну это вопрос философский - где прокладывать границу между кейсами которые библиотека (в лице автора) может/хочет поддерживать, а где уже говорить "хотите странного, делать не собираюсь".
Да и в целом непонятно что вы имеете в виду - а как автор библиотеки может гарантировать работу кода на вызывающей стороне вообще?
Ну я говорю про application-уровень, про который и писал автора. Но даже если говорим про уровень библиотеки и раст - он же как раз и предоставляет возможности защититься от большинства проблем со стороны вызывающего кода прямо на уровне типов + defensive программирования на уровне конкретных публичных методов.
Программист всегда сможет завалить программу - просто если он делает это через unsafe блоки, то это по большей части его проблема, разработчика библиотеки должно парить только возможность сломать его код через публичный api.
Для алгоритмических ошибок и есть e2e тесты. Их, конечно, не для всех проектов возможно нормально сделать, но что-то придумать можно всегда. Тогда вайб-кодеру останется продумывать варианты использования и записывать их в тесты - которые, кстати, тоже можно генерить ллмкой.
И вообще я говорю скорее про ошибки уровня "запись в уже закрытый канал" который на том же го уронят программу с паникой, тогда как в расте можно в принципе запретить expect/unwrap и быть уверенным что все ошибки обрабатываются... Ну хоть как-то.
Если добавить к этому еще и запрет на
array[i]- чтобы всегда использовалсяarray.get, то паники в коде будут очень большой редкостью, в результате чего ты можешь быть уверенным что программа ведет себя по спецификации в виде тестов.Это конечно не отменяет описанную автором проблему с плохой архитектурой - но в целом описанные "тесты на архитектуру" есть продолжение той же идеи с validate-first подходом, но на более высоком уровне.
Вообще, генерить код через LLM для более-менее больших вещей надо через validation-first подход. Я пока выбрал подход с e2e тестами вход и выход которых зафиксирован в yaml файлах - так ты хотя бы уверен что внутренняя логика работает как задумывалось.
Правда я еще и проект делаю на Rust с максимальным уровнем clippy - тогда компилятор за меня валидирует отсутствие всяких тупых ошибок от нейросеток. Интересно было бы попробовать ваш подход с валидацией архитектуры попробовать прикрутить как плагин к cargo
Кажется вы пытаетесь переизобрести memory bank
В 9 классе на экзамене по геометрии как раз выпала теорема Пифагора. Доказал как раз по схеме "смотри" - к гипотенузе C достраиваем квадрат, к его сторонам 3 - еще 3 таких же треугольника чтобы они образовывали бОльший квадрат. Площадь бОльшего квадрата будет (a + b) ^ 2, по формуле раскладывается на a^2 + b^2 + 2ab - где 2ab это как раз площади 4 треугольников и соотвественно площадь исходного квадрата с^2 равна a^2 + b^2 - то есть площадь внешнего квадрата минус площадь треугольников.
Только скорее мемори банк (а не MCP сервера) решает проблемы с summary.