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

StackOverflow https://stackoverflow.com/questions/418120

Вопрос

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

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" - это просто неудобно.

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

Это было полезно?

Решение

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

Другие советы

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

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

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

Я согласен с 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 это реализация по умолчанию (вероятно, та, которая используется чаще всего).

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

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

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

настройка и выполнение

пример:

function whateverSetup() { ... }
function whateverExecute() { ... }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top