Какое ваше соглашение об именах для вспомогательных функций?
В функциональном программировании часто важно оптимизировать любой "циклический" код, чтобы он был рекурсивным. Рекурсивные алгоритмы хвоста обычно разделяются между двумя функциями, однако - одна из которых устанавливает базовый регистр, а другой - реализует фактический цикл. Хорошим (хотя и академическим) примером будет обратная функция.
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" просто неудобно.
Какое соглашение об именах вы использовали бы для вспомогательных функций, подобных этому?
Ответы
Ответ 1
Я обычно добавляю "_recurse" до конца. Итак, "reverse_recurse". Не знаю, откуда у меня это получилось. Мне нравится оставить функцию базового блока простой, как у вас в вашем примере. Он имеет тенденцию быть "общедоступной" функцией, и тот факт, что он использует вспомогательную функцию для выполнения итерации, не имеет отношения к вызывающему. В javascript я иногда зашел так далеко, чтобы скрыть итеративную функцию через закрытие, чтобы сделать ее действительно прозрачной, ее нельзя вызывать напрямую.
Ответ 2
Вы можете вызвать вспомогательную функцию, что угодно, и это не имеет значения, если вы не помещаете вспомогательную функцию в "глобальное" пространство имен. Простое добавление "простого" кажется обычной практикой.:) Например, в Haskell,
reverse :: [a] -> [a]
reverse = reverse' []
where reverse' :: [a] -> [a] -> [a]
reverse' result [] = result
reverse' result (x:xs) = reverse' (x:result) xs
Ответ 3
Я всегда использую do_, например "do_compute" с "compute". Я нахожу это довольно описательным, так как он фактически является частью функции, выполняющей действие, тогда как "вычисляемый", который вызывается, должен иметь простое описательное имя для внешнего мира.
Ответ 4
Я согласен с ShreevatsaR, если вы не делаете вспомогательную функцию верхнего уровня (или, что еще хуже, помещаете ее в список экспорта), чем это не имеет значения, каково ее имя.
Я обычно вызываю вспомогательные функции f
и g
.
reverse :: [a] -> [a]
reverse = f []
where
f ys [] = xs
f ys (x:xs) = f (x:ys) xs
Я просто использую эту схему именования для небольших функций (иначе я не знаю, что означает f
). Опять же, зачем вам писать большие функции?
Однако, если вы хотите экспортировать свою функцию "помощник", потому что она может быть полезной для других, я бы назвал ее:
reverseAccumulator
Как Haskell zip
и zipWith
.
Но я бы не назвал эти "вспомогательные" функции, zipWith
является всего лишь общей функцией, а zip
является реализацией по умолчанию (вероятно, тот, который больше всего использовался).
Ответ 5
Я также согласен с ShreevatsaR, в этом примере я бы сделал помощником частную функцию.
В других случаях, когда мне нужно, чтобы вспомогательные функции были видимыми во всем модуле, но не экспортировались, я предпочитаю префиксные функции с помощью "_". Конечно, есть явный экспортный отчет, но во время разработки я стараюсь экспортировать все функции для облегчения интерактивного исследования, например. в ghci. Позже я добавляю список экспортируемых функций, а нижний байт упрощает запоминание того, была ли я назначена функция локальной или нет.
Ответ 6
Я использую aux
или foo_aux
(для основной функции foo
) и вставляю определение, чтобы оно не выглядело внешне.
Ответ 7
настроить и выполнить
Пример:
function whateverSetup() { ... }
function whateverExecute() { ... }