Вы когда-нибудь слышали про принцип "Функциональное ядро - Императивная оболочка". Очевидно для того, чтобы взаимодействовать с окружением нужно работать с ним как с глобальной изменяемой "переменной". Однако бизнес-логика может быть и должна быть изолирована от окружения насколько это возможно. Чистые функции проще тестировать и понять, а любым изменяемым состоянием нужно управлять.
Мир меняется, но некоторые вещи не меняются, например законы геометрии - там нет состояния - есть входные данные (стороны треугольника равны), по которым можно получить другие данные (все углы равны), используя ограниченный набор аксиом - базовых функций в каком-то смысле.
все эти алгебраические эффекты - это попытка справиться с кандалами, которые сами на себя надели: смешивать ошибки с возвращаемыми значениями банально неудобно, противоестественно.
Алгебраические эффекты - это не (только) про ошибки - это попытка объединить на первый взгляд разные вещи: исключения, генераторы, корутины (прерываемые функции) и т.п. Потому что с монадами и и прочими есть некоторые проблемы, но пока это на уровне исследований.
Не знаю зачем вы начали говорить про мутабельность. В мутабельности на уровне функции я не вижу ничего плохого, если функция остается чистой. В условиях многопоточности - функции без общего мутабельного состояния проще для использования и понимания, исключает ряд ошибок и позволяет не использовать мьютексы и т.п. Erlang вполне себе хорошо живет в многопоточном мире без изменяемых данных.
>Исключения могут быть выражены через обработку ошибок, а обработка ошибок через исключения. То есть тезисы о скорости, перфомансе и прочем неактуальны
Каким они могут быть неактуальны, если исключения всегда работают хуже (хотя бы потому что сохраняют стек вызовов (забудем про C++)). А вообще - исключения частный случай алгебраических эффектов (см. язык Koka).
>При этом, исключения дают куда более лаконичный код.
До тех пор пока не нужно их обрабатывать (try catch finally не вершина лаконичности). И все это ценой отсутствия типа ошибок в сигнатуре функций (забудем про Java и checked exceptions, которые почему-то все ругают) - пишите в каждой функции try или все может упасть в неподходящий момент.
>Дополнительно, исключения дают некоторые инструменты, которые при возврате ошибок недоступны: например при переходе к ошибкам утрачивается возможность распечатки стека вызовов
Исключения и стек вызовов - вещи ортогональные (тут пора вспомнить про C++, где стека нет).
В расте можно включить стек вызовов через RUST_BACKTRACE=1.
Вообще стеки вызовов удобны для программиста, но не удобны для пользователя - можно создавать собственные стеки ошибок (добавлять контекст), например через anyhow https://crates.io/crates/anyhow. В golang практикуются похожие вещи, и все счастливы.
(Юнит) тесты нужно писать в любом случае (уже жду споры о том что это не так и код должен работать на честном слове, хотя казалось бы 2025 год на дворе). В конце концов, если код написанный ИИ и код написанный человеком проходит один и тот же набор тестов, то какая разница, кто его писал? Да нужно сделать рефакторинг и т.п. И да, написание (хороших) тестов не проще чем реализация. Если не хватает уверенности - можно использовать фаззинг и PBT.
Вообще, писать код и писать тесты по-хорошему должны разные люди, но это невозможно в TDD (если это не парное программирование).
При написании кода условного самолета используют более строгие методы проверки качества, чем тестирование, вроде формальной верификации - только так можно проверить, что код соответствует спецификации (что не защищает от ошибок в самой спецификации).
Я не эксперт, но: я как-то узнал, что Lichess, имея до 100 тыс. пользователей онлайн, крутится на одном сервере (точнее, игровой сервер Lila). Так что масштабируемость довольно спорный момент, если это не сайт с аудиторией всяких социальных сетей.
Если хочется арч, но не хочется возиться с установкой, то рекомендую EndevourOS (KDE), хороший установщик и минимум вещей. Поставил на работе и дома, полгода назад (после трех лет на Manjaro XFCE, в принципе тоже норм).
Если стоит nvidia, то драйвера легко ставятся через nvidia-inst, а гибридная графика настраивается через envy-control в CLI.
LogSeq (привет Clojure!), причем он есть на всех платформах. Еще делает все не совсем как Obsidian, вместо взаимодействия с md файлами напрямую, работаешь с "блоками" на которые тоже можно ссылаться и даже встраивать в другие. Обычно все пишется в дневных заметках. Было немного сложно перейти с Obsidian, но кажется такой подход более логичный. Вообще там много фич, с которыми я пока не разобрался. Еще интересный факт: для документации они используют его же, можно оценить возможности: https://docs.logseq.com
Вы говорите про интеграционное тестирование, но в TDD фокус на юнит тестах. Если вам нужно 9000 моков, чтобы написать простейший тест, то наверное, что-то не так с проектированием системы. Возможно, если тесты писать до кода, то моки могут и не понадобиться.
Если из-за малейшего изменения кода падают 9000 тестов, то это значит, что код и тесты слишком сильно связаны, TDD сам по себе здесь не поможет, просто нужно уметь писать хорошие тесты, которые не завязываются на конкретную реализацию.
По поводу генерации данных для тестов - есть такой подход как Property Based Testing.
Information
Rating
Does not participate
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Вы когда-нибудь слышали про принцип "Функциональное ядро - Императивная оболочка". Очевидно для того, чтобы взаимодействовать с окружением нужно работать с ним как с глобальной изменяемой "переменной". Однако бизнес-логика может быть и должна быть изолирована от окружения насколько это возможно. Чистые функции проще тестировать и понять, а любым изменяемым состоянием нужно управлять.
Мир меняется, но некоторые вещи не меняются, например законы геометрии - там нет состояния - есть входные данные (стороны треугольника равны), по которым можно получить другие данные (все углы равны), используя ограниченный набор аксиом - базовых функций в каком-то смысле.
К сожалению нет, только смотрел документацию. Сами авторы говорят что язык исследовательский (пока), но вроде вполне можно использовать.
Алгебраические эффекты - это не (только) про ошибки - это попытка объединить на первый взгляд разные вещи: исключения, генераторы, корутины (прерываемые функции) и т.п. Потому что с монадами и и прочими есть некоторые проблемы, но пока это на уровне исследований.
Не знаю зачем вы начали говорить про мутабельность. В мутабельности на уровне функции я не вижу ничего плохого, если функция остается чистой. В условиях многопоточности - функции без общего мутабельного состояния проще для использования и понимания, исключает ряд ошибок и позволяет не использовать мьютексы и т.п. Erlang вполне себе хорошо живет в многопоточном мире без изменяемых данных.
>Исключения могут быть выражены через обработку ошибок, а обработка ошибок через исключения. То есть тезисы о скорости, перфомансе и прочем неактуальны
Каким они могут быть неактуальны, если исключения всегда работают хуже (хотя бы потому что сохраняют стек вызовов (забудем про C++)). А вообще - исключения частный случай алгебраических эффектов (см. язык Koka).
>При этом, исключения дают куда более лаконичный код.
До тех пор пока не нужно их обрабатывать (try catch finally не вершина лаконичности). И все это ценой отсутствия типа ошибок в сигнатуре функций (забудем про Java и checked exceptions, которые почему-то все ругают) - пишите в каждой функции try или все может упасть в неподходящий момент.
>Дополнительно, исключения дают некоторые инструменты, которые при возврате ошибок недоступны: например при переходе к ошибкам утрачивается возможность распечатки стека вызовов
Исключения и стек вызовов - вещи ортогональные (тут пора вспомнить про C++, где стека нет).
В расте можно включить стек вызовов через RUST_BACKTRACE=1.
Вообще стеки вызовов удобны для программиста, но не удобны для пользователя - можно создавать собственные стеки ошибок (добавлять контекст), например через anyhow https://crates.io/crates/anyhow. В golang практикуются похожие вещи, и все счастливы.
(Юнит) тесты нужно писать в любом случае (уже жду споры о том что это не так и код должен работать на честном слове, хотя казалось бы 2025 год на дворе). В конце концов, если код написанный ИИ и код написанный человеком проходит один и тот же набор тестов, то какая разница, кто его писал? Да нужно сделать рефакторинг и т.п. И да, написание (хороших) тестов не проще чем реализация. Если не хватает уверенности - можно использовать фаззинг и PBT.
Вообще, писать код и писать тесты по-хорошему должны разные люди, но это невозможно в TDD (если это не парное программирование).
При написании кода условного самолета используют более строгие методы проверки качества, чем тестирование, вроде формальной верификации - только так можно проверить, что код соответствует спецификации (что не защищает от ошибок в самой спецификации).
Deathpact выступает с подобной маской
https://youtu.be/6uwqtdQaymI?si=TAyRzIz_891P3fOw
https://youtu.be/55F5xAQhsFk?si=2vUPgaesgDvAODiQ
Я не эксперт, но: я как-то узнал, что Lichess, имея до 100 тыс. пользователей онлайн, крутится на одном сервере (точнее, игровой сервер Lila). Так что масштабируемость довольно спорный момент, если это не сайт с аудиторией всяких социальных сетей.
Если хочется арч, но не хочется возиться с установкой, то рекомендую EndevourOS (KDE), хороший установщик и минимум вещей. Поставил на работе и дома, полгода назад (после трех лет на Manjaro XFCE, в принципе тоже норм).
Если стоит nvidia, то драйвера легко ставятся через nvidia-inst, а гибридная графика настраивается через envy-control в CLI.
Можно конкретнее? Сижу на лине уже 5 год, и меня вполне все устраивает: разработка, офис, игры и т.п. Какие у вас проблемы?
Keepass
LogSeq (привет Clojure!), причем он есть на всех платформах. Еще делает все не совсем как Obsidian, вместо взаимодействия с md файлами напрямую, работаешь с "блоками" на которые тоже можно ссылаться и даже встраивать в другие. Обычно все пишется в дневных заметках. Было немного сложно перейти с Obsidian, но кажется такой подход более логичный. Вообще там много фич, с которыми я пока не разобрался. Еще интересный факт: для документации они используют его же, можно оценить возможности: https://docs.logseq.com
Вы говорите про интеграционное тестирование, но в TDD фокус на юнит тестах. Если вам нужно 9000 моков, чтобы написать простейший тест, то наверное, что-то не так с проектированием системы. Возможно, если тесты писать до кода, то моки могут и не понадобиться.
Если из-за малейшего изменения кода падают 9000 тестов, то это значит, что код и тесты слишком сильно связаны, TDD сам по себе здесь не поможет, просто нужно уметь писать хорошие тесты, которые не завязываются на конкретную реализацию.
По поводу генерации данных для тестов - есть такой подход как Property Based Testing.