Entry tags:
О допустимой сложности
Очередной раз уткнулся на работе в безумие.
Безумие заключается в том, что теоретически правильные методики работы приводят к разрастанию непонятного кода.
Теоретическая правильность заключается в DRY. Т.е. куски кода и данных, являющиеся отражением одних и тех же сущностей или потоков данных предметной области выносятся в отдельные модули, обобщаются, делаются универсальными и прочее.
Причем тут именно что не натягивание совы на глобус, когда "похожие" функции и данные насильственно обобщаются, а только те, где написание двух раздельных заведомо приведет к необходимости синхронной правки двух и более разных мест кода.
А возникающая непонятность - это то, что в результате один конечный результат работы зависит от десятков модулей, в каждом из которых функции высшего порядка посылают другие функции третим функциям, возвращающим функции, которые обрабатывают списки функций.
Это условно говоря, на практике там ничего сложнее "передать функцию-конвертор и параметры в обобщенную функцию и получить результат" нету. В паре мест есть reduce внутри reduce для сложной группировки, все это занимает 10-20 строк кода и спокойно целиком вмещается на экран.
Подобные вещи для меня являются достаточно простыми и самоочевидными. Даже в чужом коде (нормально написанном) понятно, как с таким работать: открываешь самую верхнюю функцию и начинаешь от нее идти по дереву вызовов, постепенно отсекая неинтересные ветки, пока не доберешься до нужной. Это даже в крестиках-жабах-дотнетах-питонах просто, а в функциональных языках с их лаконичностью и того проще.
А проблема в том, что потом это нужно объяснить коллегам. И тут начинается какая-то знатная хрень, потому что я объяснить не могу.
Для меня очевидно, что map/filter/reduce - это как 2+2, обработка последовательностей, на которой вообще вся эта функциональщина стоит, и что структура данных определяет вызываемые для нее функции и что общие функции и данные нужно выносить в отдельные модули, а не писать каждый раз заново одно и тоже. Но процесс раскладывания в уме ТЗ на эти базовые блоки и обратной сборки конечного результата из блоков - объяснению не поддается.
Писать же код в "понятном стиле", в том смысле, чтобы минимизировать сложность за счет написания в лоб, без зависимостей, не выделять отдельные функции для удобства чтения - это, по моему, какой-то совсем уже бред.
Безумие заключается в том, что теоретически правильные методики работы приводят к разрастанию непонятного кода.
Теоретическая правильность заключается в DRY. Т.е. куски кода и данных, являющиеся отражением одних и тех же сущностей или потоков данных предметной области выносятся в отдельные модули, обобщаются, делаются универсальными и прочее.
Причем тут именно что не натягивание совы на глобус, когда "похожие" функции и данные насильственно обобщаются, а только те, где написание двух раздельных заведомо приведет к необходимости синхронной правки двух и более разных мест кода.
А возникающая непонятность - это то, что в результате один конечный результат работы зависит от десятков модулей, в каждом из которых функции высшего порядка посылают другие функции третим функциям, возвращающим функции, которые обрабатывают списки функций.
Это условно говоря, на практике там ничего сложнее "передать функцию-конвертор и параметры в обобщенную функцию и получить результат" нету. В паре мест есть reduce внутри reduce для сложной группировки, все это занимает 10-20 строк кода и спокойно целиком вмещается на экран.
Подобные вещи для меня являются достаточно простыми и самоочевидными. Даже в чужом коде (нормально написанном) понятно, как с таким работать: открываешь самую верхнюю функцию и начинаешь от нее идти по дереву вызовов, постепенно отсекая неинтересные ветки, пока не доберешься до нужной. Это даже в крестиках-жабах-дотнетах-питонах просто, а в функциональных языках с их лаконичностью и того проще.
А проблема в том, что потом это нужно объяснить коллегам. И тут начинается какая-то знатная хрень, потому что я объяснить не могу.
Для меня очевидно, что map/filter/reduce - это как 2+2, обработка последовательностей, на которой вообще вся эта функциональщина стоит, и что структура данных определяет вызываемые для нее функции и что общие функции и данные нужно выносить в отдельные модули, а не писать каждый раз заново одно и тоже. Но процесс раскладывания в уме ТЗ на эти базовые блоки и обратной сборки конечного результата из блоков - объяснению не поддается.
Писать же код в "понятном стиле", в том смысле, чтобы минимизировать сложность за счет написания в лоб, без зависимостей, не выделять отдельные функции для удобства чтения - это, по моему, какой-то совсем уже бред.
no subject
no subject
Еще 2.5 года назад это можно было сделать нормально - т.е. взять обычного программиста на C#/Delphi/SQL, то сейчас уже все, поезд ушел - с непрерывно нарастающей рабочей нагрузкой я смог справиться, только используя сначала кодогенерацию на F#, затем DSL на Clojure.
no subject
no subject
Проблемы начинаются, когда надо придумать структуру нового документа, или разобраться, пригодна ли старая структура к повторному использованию, и вообще при изучении внутренностей.
no subject
Как только тебя перекупит Айсед, дети ребе Б начнут кушать картофельные очистки. :)no subject
no subject
no subject
no subject
no subject
no subject
Кто на него полезет-то!
;-)
no subject
no subject
no subject
no subject
no subject
no subject
no subject
Ну может быть.
no subject
Вообще, имхо, даже безотносительно к фп, у народа явные заструднения с пониманием того, что структура рождается из функционального предназначения. Что при любой парадигме пограммирования сначала идет FA, a уже потом всяческие SA. Говоришь вроде самоочивидные вещи, а на тебя непонимающими глазенками хлопают и опяь за старое, а что если сделать так, а можно сделать так. Да, так а что вы делать-то собрались? Для чего это предназначено, какие функции выполнять будет? А в ответ- хлоп-хлоп.
no subject
no subject
no subject
Если у вас разделение на функции нелогично - тушите свет.
no subject
Отсюда и попытка писать общие модули/обработки везде, где они хотя бы немного общие.
no subject
no subject
no subject
Твоя программа набрала уже такую сложность что для ее дальнейшего функционирования нужно уже создавать сообщество.
no subject
no subject
no subject
no subject
Таки да, плюсую.
no subject
А такое вообще бывает? Можно примеры?
no subject
В моей практике интересные случаи c "потому что группа" сводились в основном к факторизации. Вся линейная алгебра, кстати, построена на "потому что группа", правда, там связка из нескольких групп, часть из которых абелевы.
no subject
И коллег подбирать способных к абстракции.
И это относится не только к сведению всего к тензорному произведению моноидов, а просто к осознанию сути вещей, прежде чем кодировать байтики.
no subject
"Теорию категорий вспоминать не нужно" —
metaclass.livejournal.com/710583.html
no subject
Если же объяснять map/filter/reduce людям безграмотным, то я бы, пожалуй, только через linq смог бы :)
Такое чувство, что им нужен ликбез, но фирма ликбез не спонсирует, если я правильно понял.
no subject
no subject
А вот это кстати хитрый момент, 100% согласен, что на этом функциональщина стоит, но сам так думать не умею. Более высокий уровень абстракции, так думать ещё научить надо.
В идеале - ещё в универе на модельных задачах, но тут Вы понимаете...
UPD: Это я всё к тому, что дело не в допустимой сложности (который для меня, скажем, связан с количеством объектов, которыми надо одновременно оперировать), а в допустимом для индивида уровне абстракции.
no subject