Global variables / anonymous function

We should avoid global variables, such as, for example:

a = 2
function f(x)
    return (x + a)^2 
end
f(3)

As I understand, one way to pass data into a function is the use of anonymous functions. In this case,
we could do:

a = 2
function f(x,g)
  return g(x)^2
end
f(3, x -> x+a)

Also I am not sure if this is equivalent in the function call:

g(x) = x + a 
f(3,g)

First, as I understand, this second syntax results in faster code. If this is correct, I wander if this is equivalent:

a = 2
g(x) = x + a
function f(x)
  return g(x)^2
end
f(3)

The variable a, in this last example, is a global variable being used in g(x), so it seems that the problem of the first code is back.

Am I thinking this correctly? Is the anonymous function option effectively different in implementation and, thus, results faster code?

Or else we should always pass a as an argument explicitly to f, as in

a = 2
function f(x,a)
  return (x + a)^2
end
f(3)

Thank you for your considerations.

a is still global here and you will still have bad performance.

Yes, or use const a = ...

3 Likes

Ok, so in a typical scenario in which, for example, a minimizer calls a function in a specific format,
for instance

function minimize(f)
   # do whatever here, but calls f with the syntax f(x) and I don't want to change that
end

If I want to implement an f which uses several parameters I probably should do:

g(x,a) = x + a
a = 2
f(x) = g(x,a)
minimize(f)

or

const a = 2
f(x) = x + a
minimize(f)

Wright?

Or something like

g(x,a) = x + a
function run_stuff()
    a = 2
    minimize(x -> g(x, a)
end
2 Likes

Usually I would do something like

objective(model, a, x) = ...

degrees_of_freedom(model) = ...

function parametric_minimum(model, a; x0 = zeros(degrees_of_freedom(model))
    opt = minimizer(x -> objective(model, a, x), x0)
    if !is_converged(opt)
        error("could not find minimum")
    end
    get_minimum(opt)
end