All streams
Search
Write a publication
Pull to refresh
0
0
Mattew Skin @a-motion

Fuck Ego Guru

Send message
А потом люди вырастают из детсада, идут в школу и начинают писать статьи на английском языке в свой личный блог, как это делают профессионалы во всем мире.

Так что вся ваша пирамида на самом деле на днище настоящей пирамиды Маслоу, в которой хабр фигурирует только на самом нижнем уровне, в роли «песочницы».

Самая наркоманская строка там «Node.js прекрасная вещь для написания скриптов».

Не секрет, конечно. Это DSL поддержки pattern-matching’а в языке, который его из коробки не поддерживает.
Да никто не спорит, что type hint в частности и понимание типов вообще хорошо. И статический анализ — безусловное добро (в отличие от строгой типизации, кстати). Не спорит никто.

Именно поэтому во всех динамических языках, рожденных с пониманием того, зачем они нужны, статический анализ и контракты есть или из коробки, или были добавлены на очень ранних стадиях. Вместо тестов типа «метод должен бросить исключение TypeError если ему передано не целое число» люди давно придумали mutation-based тесты (https://github.com/mbj/mutant — это для руби, уверен, что что-то подобное есть и для языков, которые исторически заимствуют инфраструктуру у руби, наподобие PHP и JS).

Но все это вообще не о том. TDD заставляет сначала думать об архитектуре, а потом — о коде. Код с тестами (хоть тысячу раз статически типизированный) приводит к неоптимальным решениям, потому что построить грамотную архитектуру в голове очень сложно (читай: невозможно).

Это тот же эффект, что и в случае резиновой уточки на столе: проговаривая постановку задачи, формализуя ее, мы фактически на 90% воплощаем ее решение. Остается только набросать код. Например, я всегда готовлю красивые презентации по новым архитектурным решениям, и в процессе подготовки последние зачастую претерпевают серьезные изменения. Когда объясняешь тезисы для неподготовленной аудитории — многие казавшиеся очевидными вещи становятся не такими очевидными, а зачастую — и неверными. Тесты — то же самое. Лишний способ заставить самого себя пройти тест (пардон) на продуманность архитектуры.

Язык и его типизация на данном этапе (становления и формализации проблемы) — дело вообще стопиццотое, о чем я с самого начала и твержу.

А, ну это-то безусловно, это настолько очевидно, что даже и упоминания не сто́ит. Только при чем тут это?

Лечить перхоть усекновением головы, конечно, вариант. Но вот фразу «использование статической типизации уже шаг к TDD» — к которой я и прицепился — профессионал с опытом работы написать не может, только диванный теоретик. Потому что «а давайте заиспользуем с сегодняшнего дня статическую типизацию» — это глупость вот прямо со всех сторон. Во-первых, решения о выборе языка принимаются не по принципу приятственной типизации. Во-вторых, покупка яхты — это, конечно, шаг к «научиться плавать», но для большинства людей есть более приемлемые способы. В-третьих, TDD вообще никак не связано с типами; в ЛИСПе, например, тип вообще один, строго говоря. И идите скажите этим бедолагам, что шаг на пути к TDD для них — перейти на Rust.

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

Нет, такого я сказать не хотел, хотя в мире навалом полных непротиворечивых алгебр, в которых бесконечность — совершенно равноправный член социума. Также легко определить полную непротиворечивую алгебру, в которой 1/0 будет чем угодно. Но это все тут вообще ни при чем.

Я же хотел сказать, что ∞ = ∞ автоматически делает аксиоматику поля рациональных чисел противоречивой. Что, как бы, не совсем комильфо. Потому что вместе с ∞ + x = ∞ оно жить не может. Поэтому правильным является подход в котором 1 / 0 ≠ 1 / 0 ≠ 2 / 0 ≠ ∞. Только тогда _пользователь_ этого кода сможет не писать разлапистых ифов на каждую бесконечность.

Вы в следующий раз не на Вику, а сразу на пикабу ссылку давайте.

Я же сказал: я прекрасно понимаю, почему так. Потому что разработчики некоторых языков не очень образованы и/или умны. Стандартная арифметика с плавающей запятой и мантиссой умерла в Фортране, лет 30 тому назад. Если бы все пользовались теми представлениями, которые удобны машине, у нас бы такие фокусы с флоатами до сих пор были, что ах, и знаки одного популярного в узких кругах числа мы бы до сих пор считали на бумажке.

Но нет, люди с тех пор научились BigDecimal, Rational, и так далее. Я бы посмотрел на ваше лицо, если бы ваш банк считал все флоатами и вот такими бесконечностями, которые даже не консистентны.

Есть масса нормальных языков, пригодных для вычислений. И есть вот это недоразумение для «кнопки подвигать в браузере». И не нужно сюда, пожалуйста, притягивать за уши безумные реплики из середины прошлого века про IEEE 754-2008, ладно?

А я и не говорил, что тут NaN. Я говорил, что JS ведет себя дегенеративно.

И да, я прекрасно понимаю, почему. Что не делает такое решение сколько-нибудь адекватным. Очевидно, что и для вещественных, и для целых (а других тут и нет) всегда выполняется

∞ ≠ ∞

Хороший смайл получился, кстати.
Большое спасибо за ценный совет. Когда вы будете согласны спонсировать остановку разработки на неопределенное время, потому что «тимлид решил все переписать с нуля», я с удовольствием вернусь у рассмотрению этой блистательной идеи.

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

В реальном же мире микросервисы — да, перевожу на другие языки потихоньку. Но заставить хорошего в целом программиста взять и выучить эрланг, например, я не могу. Или Elm для новой витрины — очень меня всем устраивает. Но наш вполне неплохой в своем деле джсист, увы, не готов грызть гранит. Вы предлагаете разогнать к чертям команду? Или что?

При том, что, повторяю еще раз (я все еще помню, с какого тезиса стартовала эта ветка, да) статическая типизация — совсем не панацея и на бэкенде, например, мне пока представляется скорее злом. Ну как злом, так, не сто́ит выделки. А вот законодательно «сначала тест, потом код» — запросто. Безо всякой статической типизации, насчет которой я могу и ошибаться, но в контексте данной дискуссии это вообще абсолютно нерелевантно.
Помогают. Никто не спорит. «статическая типизация и контракты кода помогают снизить кол-во необходимых проверок в тестах» относится к переходу на TDD примерно так же, как «мерседес более комфортный автомобиль в сравнении с жигулями» к «я решил продать велосипед и купить машину».

Шаг к TDD, например, в 99% случаев может быть осуществлен только в рамках одного языка, потому что смена языка обычно не менее судьбоносное решение в продакшене, и принимать их вместе просто страшно. Я могу в приказном порядке допускать задачу к выполнению только после ревью тестов. А вот заставить людей фигачить на хаскеле или расте — не могу.

Ну это если говорить про реальные use cases, а не про диванных теоретиков со статической типизацией.

> использование статической типизации уже шаг к TDD

А перхоть ваша статическая типизация еще не лечит?

Слушайте, ну есть у нее свои плюсы (мало и спорные, но есть). Но вот не нужно, пожалуйста, лепить ее в любую щель. Вот я прямо сейчас смотрю на тест, который проверяет, что моя функция корректно обработает _любой_ тип принимаемого параметра. И это, да, TDD. Такой контракт, знаете ли.
Даже если отвлечься от того, что понятие «поле строк» существует только в вашей голове (и, вероятно, в книжках Бредбери), неопределенная операция умножения в точности означает, что результат не определен. Даже не знаю, как еще прозрачнее это сформулировать. Неопределен — значит ничему не равен. В том числе и самому себе. С делением на ноль та же фигня.

В некоторых языках, наоборот, операция умножения строки на число определена. Вот в руби, например:
'foo' * 5
#⇒ "foofoofoofoofoo"

Вот тут сравнивайте в свое удовольствие.

Впрочем, js и с делением на ноль выступает дегенеративненько:
5.0 / 0 === 10.0 / 0
true
Потому что над полем вещественных чисел определена операция умножения, это настолько очевидно, что даже странно уточнять.

Одно другому не мешает, это во-первых.

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

Например, хочется, чтобы выбор библиотеки тоже относился к деталям реализации. А это уже смежный с ифом вопрос.

> Для программистов почти никогда не стоит вопрос «что надо сделать?» (архитектура),
> максимум остаётся вопрос «как это сделать?» (детали реализации)

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

Команда для того и нужна, чтобы можно было не заниматься архитектурой на самых низких уровнях. И вот тут-то я ожидаю от девелопера, что он не наводнит код бесконечными ифами. А то, что расписано до уровня «осталось только придумать „как это сделать“» можно, повторяю, совершенно спокойно чатботам на аутсорс отдать за три копейки. В наше время это уже нельязя назвать работой програмиста. Это работа копипастера, машинистки со знанием пары дополнительных языков, типа COBOL и javascript, ну или на чем вы пишете.

> тестовые задачки должны быть приближены к реальным задачам,
> которые должен решать соискатель после трудоустройства

У меня вот вопрос родился: если мы разговариваем про собеседование чувака, который будет по грамотному ТЗ фигачить имплементацию, то зачем вообще собеседование? Я лично в таком случае просто найду аутсорсера, у которого есть гитхаб, на который я и стану смотреть. Как такой человек выглядит, что ест на завтрак, и умеет ли решать логические задачи — до фонаря совершенно же.

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

Так вот, вопрос: вы когда говорите про «тестовые задачки должны быть приближены к реальным задачам» отдаете себе отчет в том, что реальные задачи типа «форма с тремя полями» уже давно перестали быть задачами. Их решит миллиард человек на Земле, дешевле и быстрее члена команды. Реальные задачи как раз не имеют четких формулировок, зачастую даже входных условий, и больше всего похожи на «пойди туда не знаю куда, принеси то, не знаю что». И ценность члена команды — именно умение выкристаллизовать из этого формулировку, а не умение потом все запрограммировать. С последним, повторюсь, прекрасно справляются люди, которых я даже по имени не знаю.

А я нигде не говорил, что оно будет _быстрее_. Оно будет изящнее. А это в 99% случаев важнее.

Этот пример невозможно забыть, если любишь изящный код. Локальные переменные, помимо прочего, досталяют проблемы некоторым GC в некоторых языках (у меня есть примеры, но тут «поля недостаточно широки, чтобы привести их», как по другому поводу писал один математик).

Понимаете, в современном мире «наизусть» девальвировано полностью. 30 лет назад имело смысл спрашивать про код как таковой — сегодня все гуглится быстрее, чем пишется. Поэтому я спрашиваю про паттерны.

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

В реальном мире все задачи такие. Я ожидаю как раз вдумчивых дополнительных вопросов, уточнения формулировок, совместного доведения задачи до хорошо поставленной. Нафигачить по идеальному ТЗ тыщу строк кода может и обезьяна, и генератор кода, и чатбот.
Ага, и вот именно это и есть ответ на вопрос «зачем, например, я люблю спрашивать про `a, b = b, a`». Это же первый (ну хорошо, второй) пример, на который наталкивается человек, разбирающийся с вопросом «а зачем нужен `xor`».

И если кандидат `xor` любит и умеет, он этот пример знает в лицо. А если он привык рожать локальную переменную на каждый вздох — то пусть еще пойдет подучится.

А дальше — ну вот есть два взаимоисключающих флага, которые надо проверить — и ведь каждый раз глаза вытекают от монструозного `if` с 55-ю ветками.
Не-не-не, вы меня неверно поняли. Я согласен с вами целиком и полностью, я лишь отреагировал на фразу [вне контекста, что зря] «А должно быть иначе?».

Иногда — должно, вот все, что я хотел сказать. Так-то я сам всегда использую `===` и даже вот этот ужас внутри `if` (обернутый в `check(UNDEFINED, NULL)`).

Information

Rating
Does not participate
Location
Barcelona, Barcelona, Испания
Registered
Activity