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

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

reverse :: [a] -> [a]
reverse = reverse_helper []

reverse_helper :: [a] -> [a] -> [a]
reverse_helper result [] = result
reverse_helper result (x:xs) = reverse_helper (x:result) xs

"reverse_helper" не совсем хорошее, описательное имя. Однако "reverse_recursive_part" просто неловко.

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

7 ответов

Решение

Я склонен добавлять "_recurse" в конце. Так что "reverse_recurse". Не уверен, откуда я это взял. Мне нравится оставлять базовую функцию простой, как в вашем примере. Это, как правило, "публичная" функция, и тот факт, что она использует вспомогательную функцию для выполнения итерации, не имеет значения для вызывающей стороны. В javascript я иногда захожу настолько далеко, что скрываю итеративную функцию через замыкание, чтобы действительно понять, что ее нельзя вызывать напрямую.

Вы можете вызывать вспомогательную функцию как угодно, и это не будет иметь значения, если вы не поместите вспомогательную функцию в "глобальное" пространство имен. Простое добавление "простого" кажется обычной практикой.:) Например, в Хаскеле,

reverse :: [a] -> [a]
reverse = reverse' []
    where reverse' :: [a] -> [a] -> [a]
          reverse' result [] = result
          reverse' result (x:xs) = reverse' (x:result) xs

Я согласен со ShreevatsaR, если вы не сделаете вспомогательную функцию на высшем уровне (или, что еще хуже, поместите ее в список экспорта), тогда не имеет значения, как ее зовут. Я склонен вызывать вспомогательные функции f а также g,

reverse :: [a] -> [a]
reverse = f []
  where
    f ys []     = xs
    f ys (x:xs) = f (x:ys) xs

Я просто использую эту схему именования для небольших функций (иначе я не знаю, что f относится к). Опять же, зачем вам писать большие функции?

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

reverseAccumulator

Как у Хаскелла zip а также zipWith, Но я бы не назвал эти "вспомогательные" функции, zipWith это просто общая функция и zip это реализация по умолчанию (вероятно, та, которая использовалась чаще всего).

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

Я использую aux или же foo_aux (для основной функции foo), и вложите определение так, чтобы оно не было видно снаружи.

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

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

Настроить и выполнить

пример:

function whateverSetup() { ... }
function whateverExecute() { ... }
Другие вопросы по тегам