Поддерживает ли функциональное программирование новые соглашения об именах?

Недавно я начал изучать функциональное программирование с помощью Haskell и пришел к этой статье в официальной вики Haskell: Как читать Haskell.

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

Что вы думаете об этом?

Ответ 1

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

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

Просто мое мнение.

В ответ на ваш комментарий

Я возьму два фрагмента кода из Real World Haskell, как из глава 3.

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

tidySecond :: [a] -> Maybe a
tidySecond (_:x:_) = Just x
tidySecond _       = Nothing

Функция достаточно обобщена из-за параметра типа a и того факта, что мы действуем по встроенному типу, так что нам все равно, что на самом деле второй элемент. Я считаю, что x достаточно в этом случае. Так же, как в небольшом математическом уравнении.

С другой стороны, в разделе "Представление локальных переменных" они пишут примерную функцию, которая пытается смоделировать небольшой часть банковского домена:

lend amount balance = let reserve    = 100
                          newBalance = balance - amount
                      in if balance < reserve
                         then Nothing
                         else Just newBalance

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

Ответ 2

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

map                     :: (a->b) -> [a] -> [b]
map f  []               =  []
map f (x:xs)            =  f x : map f xs

Для кого-то, кто не подвергался воздействию Haskell, это может показаться уродливым, неподъемным кодом. Но большинство программистов Haskell сразу поймут это. Таким образом, он выполняет свою работу.

var list = new int[] { 1, 2, 3, 4, 5 };
int countEven = list.Count(n => n % 2 == 0)

В этом случае короткое имя переменной кажется подходящим.

list.Aggregate(0, (total, value) => total += value);

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

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

Ответ 3

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

Неизменяемость также в некоторой степени способствует этому - на традиционных языках, таких как C/С++/Java, переменная может представлять разные данные в разные моменты времени. Поэтому ему нужно дать имя, чтобы дать программисту представление о его функциональности.

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

Ответ 4

Сейчас я изучаю Haskell, но я не чувствую, что его соглашения об именах настолько разные. Конечно, в Java вы вряд ли найдете такие имена, как xs. Но легко найти такие имена, как x в некоторых математических функциях, i, j для счетчиков и т.д. Я считаю, что такие имена идеально подходят в правильном контексте. xs в Haskell подходит только общие функции по спискам. Их много в Haskell, поэтому это имя широко распространено. Java не обеспечивает простой способ обработки таких общих абстракций, поэтому имена списков (и самих списков) обычно более специфичны, например. lists или users.

Ответ 5

Я только что посетил ряд переговоров по Haskell с большим количеством образцов кода. В то время как код имел дело с x, я и f, имя не беспокоило меня. Однако, как только мы вошли в манипуляции с тяжелыми списками и т.д., Я обнаружил, что три буквы или их имена намного менее читаемы, чем я предпочитаю.

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

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

Ответ 6

Все, что помогает читаемости, является хорошей вещью. Значимые имена - это хорошая вещь на любом языке.

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

Я был бы осторожен, как далеко я принял совет о именах Haskell

Ответ 7

Когда в Риме делай, как делают римляне

(Или, как говорят в моем городе: "Donde fueres, haz lo que vieres" )

Ответ 8

Моя практика Хаскелла имеет только посредственный уровень, поэтому я смею пытаться ответить только на вторую, более общую часть вашего вопроса:

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

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

Я был любопытным, как легко писать практические программы на таком "чрезвычайно" минималистическом языке функционального программирования, как комбинационная логика.

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

Несмотря на такой экстремальный минимализм, все еще существуют практические методы "программирования" комбинаторной логики аккуратным и приятным способом. Я написал quine в модульном и многоразовом виде, и это не было бы противным даже bootstrap a self-interpreter на нем.

Для резюме я почувствовал следующие особенности использования этого чрезвычайно минималистического языка функционального программирования:

  • Необходимо придумать много вспомогательных функций. В Haskell существует много синтаксического сахара (сопоставление образцов, формальные параметры). Вы можете написать довольно сложные функции в нескольких строках. Но в комбинаторной логике задача, которая может быть выражена в Haskell с помощью одной функции, должна быть заменена хорошо подобранными вспомогательными функциями. Бремя замены синтаксического сахара Хаскелла принимается умственно подобранными вспомогательными функциями в комбинаторной логике. Что касается ответа на ваш исходный вопрос: стоит придумать значащие и запоминающиеся имена для этих легионов вспомогательных функций, потому что они могут быть довольно мощными и многократно использоваться во многих другие контексты, иногда неожиданным образом.

  • Более того, программист комбинаторной логики не только вынужден обнаруживать броские имена кучки умственно выбранных вспомогательных функций, но даже больше, он вынужден (повторно) изобретать целые новые теории. Например, для имитации списков, программист вынужден имитировать их с помощью fold function s, в основном, он должен (пере) изобретать катаморфизм, глубокие алгебраические и теории теории категорий.

Я предполагаю, что несколько различий можно отнести к тому факту, что функциональные языки имеют мощный "клей" .

Ответ 9

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

Ответ 10

Я согласен с множеством пунктов, сделанных здесь в отношении именования аргументов, но быстрое "найти на странице" показывает, что никто не упомянул Tacit программирование (так называемый беспутельный/бессмысленный). Легко ли это читать, может быть спорным, так что это зависит от вас и вашей команды, но, безусловно, стоит тщательного рассмотрения.

Нет именованных аргументов = Соглашения об именах без аргументов.