6
votes

Slow to learning newer julia syntax and scoping.

In Julia v1.1.1

what is the explanation for why the MWE below throws error "ff not defined" ?

N = 5;
typp = "b";
mu = 2;

function bigfun()

  function f(u,mu)
    ee = mu*u;
    return ee
  end

  function g(uv,mu)
    ee = (mu^2)*uv
    return ee;
  end

  while 1 == 1

    u = ones(N);
    if typp == "a"
      ff(u) = f(u,mu);
    elseif typp == "b"
      ff(u) = g(u,mu);
    end
    fu = ff(u);
    break;

  end

end

bigfun();
2
You are using global variables (N, typp, mu), which is bad for performance, and a bad idea in general. You should avoid that. (A style tip: use while true instead of while 1 == 1.)DNF
Ok thanks. Honest (and naive) question, but what if the variables are conceptually global?dj_a
It's the very first tip detailed in docs.julialang.org/en/v1/manual/performance-tips. Use const if you really want a global variable.giordano
thanks for the reminder !!dj_a

2 Answers

10
votes

This is a known bug in Julia: https://github.com/JuliaLang/julia/issues/15602. You can't define an inner function conditionally. There a few ways around this issue:

  1. Define ff as an anonymous function:
        if typp == "a"
          ff = u -> f(u,mu)
        elseif typp == "b"
          ff = u -> g(u,mu)
        end
        fu = ff(u)
    
  2. Define ff once, and add the conditional inside of it:
        function ff(u, typp)
          if typp == "a"
            f(u,mu)
          elseif typp == "b"
            g(u,mu)
          end
        end
        fu = ff(u, typp)
    
  3. Don't define the function ff at all. You don't need to, in the example you provided, just assign fu conditionally
        if typp == "a"
          fu = f(u,mu)
        elseif typp == "b"
          fu = g(u,mu)
        end
    
1
votes

As mention in the Julia Docs,

Julia uses lexical scoping, meaning that a function's scope does not inherit from its caller's scope, but from the scope in which the function was defined.

It is worth reading some examples in the above link but the gist is that the function is defined in the local scope/context of the if/else statement and does not exist outside of that scope (at the end of that function).