Применение принципов чистого кода к функциональным языкам

16

В настоящее время я читаю Чистый код Роберта Мартина . Я думаю, что это здорово, и когда я пишу ОО-код, я принимаю его уроки близко к сердцу. В частности, я думаю, что его совет использовать маленькие функции со значимыми именами делает мой код более плавным. Лучше всего подытожить этой цитатой:

[Мы] хотим иметь возможность читать программу, как если бы это был набор абзацев TO, каждый из которых описывает текущий уровень абстракции и ссылается на последующие абзацы TO на следующем уровне ниже.

( Чистый код , стр. 37: «TO абзац» - это абзац, который начинается с предложения, озвученного в инфинитиве. «Для выполнения X мы выполняем шаги Y и Z». «Для выполнения Y мы ...» и т. Д. ) Например:

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

Я также пишу функциональный код для моей работы. Примеры Мартина в книге определенно читаются так, как если бы они были набором параграфов, и они очень ясны - но я не уверен, что «чтение как набор абзацев» является желательным качеством для функционального кода, чтобы иметь ,

Взяв пример из стандартной библиотеки Haskell :

maximumBy               :: (a -> a -> Ordering) -> [a] -> a
maximumBy _ []          =  error "List.maximumBy: empty list"
maximumBy cmp xs        =  foldl1 maxBy xs
                        where
                           maxBy x y = case cmp x y of
                                       GT -> x
                                       _  -> y

Это как можно дальше от совета Мартина, но это лаконично, идиоматичный Хаскелл. В отличие от примеров Java в его книге, я не могу себе представить способ рефакторинга этого в нечто такое, о чем он просит. Я подозреваю, что Haskell, написанный в стандарте Чистого кода, окажется скучным и неестественным.

Я ошибаюсь, что (хотя бы некоторые из них) Чистый код расходится с лучшими практиками функционального программирования? Есть ли разумный способ переосмыслить то, что он говорит, в другой парадигме?

Патрик Коллинз
источник
1
Функциональные программисты, как правило, пишут слишком сжатый код, это правда. Я бы даже не считал это лучшей практикой даже в такой среде.
Теластин
Простите за невежество, но что за абзац TO?
Шашанк Гупта
4
Как недавно упоминалось в другом вопросе, Дейкстра писал о глупости «программирования на естественном языке», и я склонен с ним согласиться, что код, который читается как проза, - несбыточная мечта. Я думаю, что это особенно верно в Haskell, который, будучи чистым, символически выражает равенство между значениями, а не последовательность шагов для получения эффектов. Я думаю, что важно то, что приведенный код является идиоматическим. Например xs, это плохое имя, но оно так же распространено в функциональных языках, как и iдля переменных цикла.
Довал
@ShashankGupta Я отредактировал вопрос со ссылкой на определенную страницу в книге, а также со своим собственным пониманием того, что написал дядя Боб.
@ShashankGupta Он приводит несколько примеров, но идея в том, что он должен читаться как проза. «Чтобы найти максимум в списке, вы проверяете каждый элемент ...»
Патрик Коллинз

Ответы:

11

Clean Code - это прежде всего руководство по стилю. Strunk and White не применяется, когда вы пишете на клингоне. Идея в том, что вы хотите быть понятными программистам, которые, вероятно, будут читать ваш код. Вы хотите иметь код, который является модульным и легко реструктурируемым. Есть способы сделать это в Haskell так же, как есть способы сделать это на любом другом языке, но точные детали могут отличаться.

При этом для Хаскелла существует ряд рекомендаций по стилю . Переполнение стека также имеет довольно полное руководство . Сохранение логики кодирования простым и кратким кажется довольно постоянным. Обобщение функций также подчеркивается, поскольку это приводит к модульности. СУХОЙ код также подчеркивается, как и с Чистым кодом.

В конце концов, «Чистый код» и руководящие принципы кодирования на Haskell стремятся к одному и тому же, но в конечном итоге идут своим путем.

Мировой инженер
источник
1
Мне кажется, что в этом ответе учтены принципы дисконтирования, которые учит Чистый код, которые очень применимы ко всем языкам, и это является ключевым в задаваемом вопросе. Я понимаю, почему люди думают о Чистом коде как о руководстве по стилю, и я думаю, что это отчасти верно, но недостаточно, чтобы отклонить всю книгу как одну.
Аллан
Я не считаю книгу «Чистый кодекс» Мартина руководством по стилю. Я чувствую, что учения этой книги действительно соответствуют где-то между руководством по стилю и шаблонами дизайна.
Майкл Р
15

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

Выраженный в формате "TO абзаца" Боба Мартина, я прочитал ваш пример следующим образом:

  • Вычислить maximumBy , вам нужны функция упорядочения и список, и результат является элементом этого списка.
  • Вычислить maximumBy пустой список и любую функцию упорядочивания является ошибкой.
  • Чтобы вычислить maximumByсписок xs, вы сворачиваете этот список, используяmaxBy функцию.
  • Чтобы вычислить maxByдва элемента списка, вы сравниваете их, используя заданную функцию упорядочения. Если первый элемент больше, выберите его. В противном случае выберите второй.

Вы начинаете с самых общих понятий и переходите к более подробным, как в императивных примерах. Идея «абзацев TO» заключается в том, что вы можете прекратить чтение в определенный момент, когда вы получили достаточно деталей, без необходимости перепрыгивать страницу вверх и вниз. Это, безусловно, случай здесь.

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

Есть способы реализовать это, которые не следуют рекомендациям «TO абзац». Если оставить в стороне явную сигнатуру, предложение «обзора» более высокого уровня будет опущено. Вы можете использовать выражение if для обработки ошибок вместо сопоставления с шаблоном, что может привести к неправильному смешиванию с другим уровнем абстракции. Вы могли бы встроить maxByкак анонимную функцию вместо того, чтобы дать ей имя, которое может быть описано позже более подробно.

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

Карл Билефельдт
источник