 # ForwardDiff saving unwanted variable

Hi everyone,

I am migrating from Matlab to Julia and I have noticed some weird (perhaps unwanted?) behavior of the ForwardDiff package.

``````using ForwardDiff
function eq()

function qfun(x)
q = x + x
return q
end

q = qfun([1.0, 2.0])

dq = derq([1.0, 2.0])

return q
end

a = eq()
``````

This does not return 3.0 but instead:

``````Dual{ForwardDiff.Tag{var"#qfun#17",Float64}}(3.0,1.0,1.0)
``````

However, if I change the name of q inside qfun I get what I expected (3.0 as output):

``````using ForwardDiff
function eq()

function qfun(x)
q2 = x + x
return q2
end

q = qfun([1.0, 2.0])

dq = derq([1.0, 2.0])

return q
end

a = eq()
``````
``````3.0
``````

Also, if I run this code outside a function, I get an output of 3.0 to q:

``````using ForwardDiff
function qfun(x)
q = x + x
return q
end

q = qfun([1.0, 2.0])

dq = derq([1.0, 2.0])

q
``````
``````3.0
``````

What is going on? Is this a bug or am I missing something from some expected behavior of ForwardDiff? It sounds super weird to me that the label used inside a function can affect the final output.

Best,

Caio

This isn’t a bug, and it doesn’t actually have anything to do with ForwardDiff. Here’s a simpler example of the same behavior:

``````julia> function outer()
function inner()
x = 1
end

x = 2
inner()
return x
end
outer (generic function with 1 method)

julia> outer()
1
``````

The call to `inner()` sets `x = 1`, and the `x` inside `inner()` is the same one in `outer()`.

You’re seeing this happen because `ForwardDiff.gradient(qfun, ...)` results in `qfun` being called, which has the side-effect of modifying the local variable `q`.

You are correct that this doesn’t happen at global scope:

``````julia> function inner()
x = 1
end
inner (generic function with 1 method)

julia> x = 2
2

julia> inner()
1

julia> x
2
``````

Global scope is a bit different in Julia–if you want to re-assign a global variable from within a function or a loop, you need to be explicit and use the `global` keyword:

``````julia> function inner()
global x
x = 1
end
inner (generic function with 1 method)

julia> x = 2
2

julia> inner()
1

julia> x
1
``````
3 Likes

After checking the FAQ about the scope of variables and your answer I think I got it, thanks.

In fact, I would not like the variables to be reassigned when I call ForwarDiff to compute the derivatives (this is the only reason why qfun needs to be defined in my code). One option is to rename “q”, but this is costly, since in my actual code there are many variables being reassigned, and they appear many times in a formula. The best solution I could find was declare “q” local inside the function, which gives 3.0 as output.

``````using ForwardDiff
function eq()

function qfun(x)
local q
q = x + x
return q
end

q = qfun([1.0, 2.0])

dq = derq([1.0, 2.0])

return q
end

a = eq()
``````

Does `qfun` actually have to live inside `eq()`? If not, then this problem is easy to avoid: you could simply do:

``````using ForwardDiff

function qfun(x)
q = x + x
return q
end

function eq()
q = qfun([1.0, 2.0])