Should a helper function be defined inside or outside the main function?

I have a function f that uses a helper function h (which has no use beyond f). I face the choice of whether to define h inside or outside f. As in:

inside

function f()
  h() = ...
  return h()
end

outside

h() = ...
function f()
  return h()
end

If I want users to not have access to h at all, I should define it inside f. But is there a penalty to doing so? Does h get created every time f is called?

No.

2 Likes

Depends. The difference is that a nested h can share local variables with f, which you likely do not intend if you want it work the same as if h was defined outside f. If you take care to not let any variables overlap, then it should work the same because the lowerer lifts the nested function to the global scope and gives its type a var name, and what the written definition line ends up doing is assigning the function to a local h. With a little more work than written global names, the var name can still be found and used to make the function, something like var"#h#1".instance.

Aside: In a different case where you want shared variables, h or f reassigning those variables would cause type inference problems that cost performance…

4 Likes

Note that there exists another approach

julia> let
           global f
           h() = 3
           function f(x)
              x + h()
           end
       end
f (generic function with 1 method)

julia> f(3)
6

julia> h
ERROR: UndefVarError: `h` not defined
4 Likes

That will also make a var name for the nested function’s type, so the function can be accessed the same way as in the original example.