Same code in if and else blocks, get UndefVarError only on else condition

Suppose I have a function with 2 arguments, and I want to make a new function with one of the arguments fixed to a value, depending on some condition. For example:

fun(x,a) = a*x
function foo(flag::Bool)
   if flag
       bar(x) = fun(x,2)
   else
       bar(x) = fun(x,2)
   end
   return bar
end

In this example the value of a is fixed to 2 on both branches, just for illustration.
If I run this code in a script, foo(true) returns the desired function, but foo(false) gives

ERROR: UndefVarError: bar not defined
Stacktrace:
 [1] foo(::Bool) at .\none:7
 [2] eval(::Module, ::Any) at .\boot.jl:235

I realize now at least a couple of different ways to re-write foo so that it works, but my question is why does the above version not work when control flows down the else branch? I think I can learn something by understanding this, but I can’t make sense of it in terms of my understanding of scoping rules.

Thank you (I’m using Julia 0.6.2, BTW)

You cannot define a function conditionally in this way because the function method table needs to be constructed at the top level. disallow methods of local functions in different blocks · Issue #15602 · JuliaLang/julia · GitHub has an explanation and some discussion of workarounds. For your purpose you should probably make bar an anonymous function like this:

bar = x -> fun(x, 2)

Thank you and sorry for duplicating the issue you linked. If this type of conditional function definition is not allowed in Julia, it should probably produce a (more informative) error in both the true and false cases. Since that issue is still open, I assume better handling of this problem (and some corresponding documentation) will appear in due course.

Yes, though the quickest way to make the documentation appear is probably to add it yourself :slight_smile: It may be worth adding a note in the Conditional Evaluation or Functions section of the manual until the root problem is fixed or a better error/warning is added.