views:

613

answers:

7

In functional programming, it's often important to optimize any "looping" code to be tail recursive. Tail recursive algorithms are usually split between two functions, however - one which sets up the base case, and another that implements the actual loop. A good (albeit academic) example would be the reverse function.

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" isn't really a good, descriptive name. However, "reverse_recursive_part" is just awkward.

What naming convention would you use for helper functions like this?

A: 

setup and execute

example:

function whateverSetup() { ... }
function whateverExecute() { ... }
Steven A. Lowe
whateverSetup is a horrible name if the function is public.
Cybis
@[Cybis]: It should be implied that you replace "whatever" with an appropriate descriptive term, e.g. WidgetSetup, WidgetExecute, etc.
Steven A. Lowe
+2  A: 

I tend to add "_recurse" to the end. So "reverse_recurse". Not sure where I got that from. I like leaving the base case function simple as you have in your example. It tends to be the "public" function and the fact that it uses a helper function to perform the iteration is irrelevant to the caller. In javascript I sometimes go so far as to hide the iterative function via a closure, to make it really clear it is not to be called directly.

Crescent Fresh
"_recurse" - that's a good one.
Cybis
+3  A: 

I always use do_, like "do_compute" with "compute". I find it quite descriptive as it is effectively the part of the function that performs the action, whereas the "compute" that gets called needs to have a simple descriptive name for the outside world.

small_duck
+11  A: 

You can call the helper function anything you want, and it won't matter as long as you don't put the helper function in the "global" namespace. Simply adding a "prime" seems a common practice. :) E.g., in Haskell,

reverse :: [a] -> [a]
reverse = reverse' []
    where reverse' :: [a] -> [a] -> [a]
          reverse' result [] = result
          reverse' result (x:xs) = reverse' (x:result) xs
ShreevatsaR
+2  A: 

I agree with ShreevatsaR, if you don't make the helper function top-level (or worse, put it in the export list), than it doesn't matter what its name is. I tend to call helper functions f and g.

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

I just use this naming scheme for small functions (otherwise I don't know what the f refers to). Then again, why would you ever write big functions?

However, if you do want to export your 'helper' function because it might be useful to others, I would call it:

reverseAccumulator

Like Haskell's zip and zipWith. But I wouldn't call those 'helper' functions, zipWith is just a generic function and zip is the default implementation (probably the one thats used the most).

Tom Lokhorst
+2  A: 

I use aux or foo_aux (for main function foo), and nest the definition so it's not externally visible.

Chris Conway
+2  A: 

I also agree with ShreevatsaR, in this example I would make the helper a private function.

For other cases where I need helper functions to be visible in the whole module, but not exported, I tend to prefix functions with '_'. Sure, there is the explicit exports statement but during development I tend to export all functions to ease interactive exploration, e.g. in ghci. Later on I add the list of exported functions and the underbar makes it easy to remember whether I intended a function to be local or not.

Magnus