Каково ваше соглашение об именах для вспомогательных функций?
В функциональном программировании часто важно оптимизировать любой "зацикливающийся" код, чтобы он был хвостовым рекурсивным. Однако рекурсивные алгоритмы хвоста обычно делятся между двумя функциями: одна задает базовый вариант, а другая реализует реальный цикл. Хорошим (хотя и академическим) примером будет обратная функция.
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() { ... }