Pull to refresh

Comments 48

В рамках предложения: 1.5. Написал, собрался рефакторить — сначала напиши тесты. Да, я все еще встречаю людей, которые рефакторят код без тестов.
Всегда так делал и буду делать.
Когда у вас есть статические типы, тесты при рефакторинге вам по большому счету нафиг не нужны.
Простите, не понял. Если вы рефакторите логику, разве нельзя ее сломать, при этом не поломав типов?
Если вы рефакторите логику, разве нельзя ее сломать, при этом не поломав типов?

Зависит от типов. Если типы достаточно выразительны — нет, нельзя. Но да, на практике такие вещи не слишком распространены; впрочем и «обычных» типов хватает для того, чтоб вынести за скобки необходимость держать в голове большую часть кода и следить за сохранностью логики в ней.

Ну и именно потому, что всё можно сломать — рефакторинг и делает программист, а не нейронка. Вне зависимости от того, есть ли у вас тесты или нет. Тесты — не гарантия того, что вы ничего не сломали. Как максимум это гарантия того, что вы не сломали тесты (да и то не всегда).
UFO just landed and posted this here
Согласен про Idea, в моем случае PhpStorm, и тоже использую эти фичи постоянно. Я имел в виду именно переписывание кусков кода, когда нужно, к примеру, переписать логику, запросы к ORM/БД, и подобные вещи.

А если вам на ревью пришёл PR с рефакторингом, как вы со спокойной совестью поставите Approve? В этом случае сильно помогает автоматизация, в том числе тестирования.

Это не рефакторинг, а переименования и перемещения. Рефакторинг — это когда значительно меняется подход к реализации какого-либо слоя логики без изменения ее функциональности.

UFO just landed and posted this here
UFO just landed and posted this here

Обожаю диванных экспертов. Расскажите, как в библиотеке, которая парсит маркдаун, хоть в чем-то помогут типы.

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

В корректные контрпримеры надо уметь. Существуют наборы тестов для маркдауна, которые покрывают ожидаемый ввод, гарантируя, что когда вы добавлете экстеншн, существующие конструкции не поломались.


Типы там вообще не помогут буквально ничем.

Существуют наборы тестов для маркдауна

Конечно существуют.

которые покрывают ожидаемый ввод

Что будем делать с не ожидаемым?

Но на самом деле наверное даже не стоило влезать в общение с человеком, который ради пачки комментариев намеренно проигнорировал то, что заглавный комментарий ветки не содержит в себе повального обобщения.
Что будем делать с не ожидаемым?

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

Более того, давно уже известно, что написание тестов полезно не только и не столько постоянной проверкой результата исполнения кода, сколько качеством получающейся структуры кода за счёт более глубокого продумывания при написании тестов.
TDD требует отказа от тестирования тех сценариев, которые использоваться не будут, и покрытия тестами только тех, которые будут.

А, ну теперь-то всё понятно. Нужно просто использовать ПО только так, как это было задумано; а как не было задумано — не использовать. Мы-то, тупые, тут чё-то сокрушаемся, что код порой не работает, потому что разработчики не всё предусмотрели. А умные парни всё уже давно решили.

Более того, давно уже известно, что написание тестов полезно не только и не столько постоянной проверкой результата исполнения кода, сколько качеством получающейся структуры кода за счёт более глубокого продумывания при написании тестов.

А знаете, что еще повышает качество структуры кода, помимо продумывания при написании тестов?
Продумывание собственно самой структуры кода перед её написанием.
UFO just landed and posted this here

Это не вариант.


Что там от кого требует TDD — такое же точно идолопоклонничество, как «типы нас спасут от ядерного взрыва».


Неожиданный ввод может перекладываться в аккумулятор, как есть. Может выбрасывать исключение. Может сразу возвращать пустую строку. Может возвращать разметку до позиции, в которой мы нашли что-то неожиданное.


Зависит от варианта использования.

UFO just landed and posted this here

Что именно выразить-то? Чувствую, в воздухе явственно запахло монадами.


Мне лично тут не нужны помощники, чтобы что-то выразить. Все выражено до меня.

UFO just landed and posted this here

А почему это нельзя прямо кодом выразить? Буквально, кинуть эксепшн?

UFO just landed and posted this here

Ах вон оно что!


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


Посмотрите, как мы в Elixir к документации подходим. Я, к примеру, функции без спецификации или документации, заворачиваю на код-ревью не глядя. Такая культура сложилась, и люди втянулись.


Ну вот, например, библиотека параллельного вычисления — даже не корка языка. У меня весь мой код такой же, и в OSS, и под NDA.


Автоматически генерируется вот в такое.

UFO just landed and posted this here

Конечно. И да, доктесты придумали как раз для проверок документации компилятором.

UFO just landed and posted this here

Нет, дело не в этом. Документация лучше по очень многим причинам, главная: в силу формата, она априори позволяет рассказать читателю больше, чем тесты. Документация для эрланга включает в себя типы, если автор кода не совсем тупой. А если тупой — типы тоже не спасут.


И она не может устареть; эта страшилка из девяностых — сама устарела, с введением современных правил разработки. CR проверяет и документацию тоже. С тем же упехом можно заявить, что код может устареть: ведь у нас теперь расширился список обрабатываемых вариантов для параметра x, а в коде это не поправили (и типы тут не помогут тоже).


Типы не напишут за меня документацию, не сделают ненужными тесты, и не являются серебряной пулей с осиновым наконечником, которая спасет нас от диавола. Вот и все.

UFO just landed and posted this here

Во-первых, мне это неочевидно. Во-вторых John Hughes для такого типа задач придумал property testing. В-третьих, один последний clause для парсящей ввод из стрима функции, который откусывает один символ если ничего не заматчилось, и перекладывает в аккумулятор, делает утверждение очевидным. В-пятых, потенциальная возможность обработки бесконечного стрима делает доказательство невозможным.

UFO just landed and posted this here
Total parser combinators

Пункт «во-первых» там присутствовал ради последних двух пунктов.


сформулируйте свойство «всегда завершается»

Не могу придумать, зачем бы это мне (кроме академического интереса похвастаться коллегам).


те свойства, которые вы пишете в property-based testing, вполне могут быть выражены в типах

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


Про левую рекурсию не слышали?

Зачем в этой задаче левая рекурсия? Больше баззвордов, пока все в комнате не начнут выглядеть некомпетентными болванами?


В языках, где бесконечные стримы выразимы

Бесконечные стримы выразимы во всех без исключения полных по Тюрингу языках, даже если они не знают, что называются красивым словом «выразимы». Любой язык умеет читать из сокета.


понятие завершимости заменяется более общим понятием продуктивности

А вот это уже вредно для конечного продукта. Например, работа с XMPP протоколом в общем случае не удовлетворяет этому условию: ejabberd в прямом смысле запустит поток и будет висеть бесконечно, ожидая следующей станзы, пока клиент не отключится.


Ему не надо никого оповещать о таймаутах и каноничекую продуктивность такого процесса не доказать (потому что ее нет). И ничего, мир не рухнул.

UFO just landed and posted this here

Вообще, мне кажется, что у вас легкая форма профессиональной деформации, вызванная прыжком из языка, где можно в WORD по указателю положить достаточно короткую строку, в язык со строгими типами (еще я удивлен, почему вы все-таки предпочитаете Хаскель — Идрису, тот вроде, идеологически еще концептуальнее).


Без обид, исключительно, как повод задуматься, если вдруг увидите в моих словах рациональное зерно.


Мир просто не черно-белый. В том же эрланге есть чудесный способ получить все плюшки, не связываясь с типами (продуманный pattern matching и guards). Кому не хватает — есть статический анализатор кода, который умеет выводить типы. И хотя сам Вирдинг утверждает, что типы — это круто, и их нет в эрланге только потому, что язык изначально проектировался для hot code reload, я не думаю, что они бы что-то всерьез улучшили.

UFO just landed and posted this here
чем больше я про все это говорю и пропагандирую, тем больше людей про это знает

Это-то мне понятно, и такая позиция мне крайне близка. Просто чем больше вы начинаете говорить о типах, как о панацее — тем дешевле становятся их преимущества (которых тоже, конечно, вагон).


IMSO, конечно.

UFO just landed and posted this here

«Дешевле» — в смысле «доказательная наука» превращается в «религию».


Я повторяю: я согласен, что есть ситуации, в которых типы помогают. Но когда мне начинают говорить, что типы лучше документации, типы делают ненужным тестирование и типы спасут мир — это уже начинает выглядеть как «на все — Воля Божья».

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

ИМХО одно другому не мешает. Представьте себе донельзя упрощенный вариант:

int sum(int a, int b) {
return a+b;
}

А потом кто-то впопыхах берет и меняет плюс на минус, и это проходит code review (лично видел не раз). Строгая типизация удовлетворена, компилятор счастлив, но самолет продакшн таки падает. YMMV, но у меня таких примеров в работе море.
UFO just landed and posted this here
Прошу прощения, мне не знаком данный синтаксис в контексте языков программирования (математически понятно). Подскажите, какой это язык? В любом случае, мой комментарий касался более классических ЯП, где подобное отсутствует. Ну и такой момент — если эти теоремки будут рядом, всегда есть искушение «поправить» и их заодно с рефакторингом. Понятно, что от полных идиотов не спасет ничто, но если тесты вообще в другом файле, то очумелые ручки доберутся до них с чуть меньшей вероятностью. Все ИМХО.
но если тесты вообще в другом файле

А уж если их в блокчейн положить…

Я в принципе нисколько не против, чтоб люди упарывались, вы просто когда упарываетесь — то имейте в виду, что выраженные типами теоремы о том, как должен работать тот или иной код — это по сути почти то же самое, что и полное покрытие любого ввода через property-based тесты, только без тестов.

(Почти — потому что типы базируются на математике, а property-based тесты таки вынуждены выполнять ваш код и смотреть на результат)
UFO just landed and posted this here

Пф. Вы переписали код вычиления суммы с языка Foo на язык Bar. Теперь, по сути, сама функция sum не очень-то нужна, потому что вы выразили ее полностью в типах.


Смена аксиоматики не может сделать что-то понятнее, точнее, или правильнее.

UFO just landed and posted this here

В целом согласен, но с оговоркой что тесты должны быть интеграционными. От юнит тестов при более-менее большом рефакторинге толку ноль

Наверное, camel case стоило оставить, как есть :)
Sign up to leave a comment.