# Recursive function does not return last value

Hi,
I wrote a custom algorithm to find the root of my equation (I know, there is much better out there, but my function is not differentiable and it s defined decreasing)

Anyway, this is the algorithm. I would like to return the last value of the ‘x’ which is my root. But I cannot!
It returns nothing.
Harnessing with it, I understood that it returns the first value of the first if statement it walks through, but why!? How can I return the last value. I can define a global variable and get it through that, but it is just wrong!

Thanks for help

``````## Assuming the function is monotonous decrescent
K = 0.
function _find_minimum!(;y0=10., n = 2.,  x::Real=20., ν::Real, model::Function)
y = -4*x + 5
# _compute_voltage(;model=ss,ν=ν, Kie=x)
if abs(y0) > 0.001
if sign(y0) ==sign(y)
## the solution is far ahead!
x1 = x + sign(y0)*(2^n-1)
_find_minimum!(y0=y, n=n, ν=ν, x=x1, model=model)
end
if sign(y0) != sign(y)
## you stepped through the solution, go back!
x1 = x - sign(y)*(2^n-1)
_find_minimum!(y0=y, n=n/2., ν=ν, x=x1, model=model)
end
else
## this works
global K = x
return x
end
end
``````

Incidentaly, you can find univariate solvers in

1 Like

All expressions in Julia have a value. For an `if` statement, that value is the value of the expression in whatever branch was taken (or `nothing` if no branch was taken):

``````julia> a = if 1 == 2
"hello"
else
"world"
end
"world"

julia> a
"world"
``````

Likewise a function automatically returns the value of its last expression if you don’t have an explicit `return`:

``````julia> function foo()
if 1 == 2
"hello"
else
"world"
end
end
foo (generic function with 1 method)

julia> a = foo()
"world"

julia> a
"world"
``````

You just need to do `return _find_minimum(...)` to ensure that the returned value from the last recursive call is propagated all the way out.

For a much simpler example, here’s a simple recursive function to compute a square root:

``````julia> function find_sqrt(x, guess)
y = x / guess
if y ≈ guess
return guess
else
return find_sqrt(x, 0.5 * (guess + y))
end
end
find_sqrt (generic function with 1 method)

julia> find_sqrt(4, 1)
2.000000000000002

julia> find_sqrt(2, 1)
1.4142135623746899

``````
2 Likes

Also note that I could have removed both `return` statements without changing the behavior of the function, since the function will implicitly return the value of the `if` block, and the value of that block will be the value of whatever branch was chosen:

``````julia> function find_sqrt(x, guess)
y = x / guess
if y ≈ guess
guess
else
find_sqrt(x, 0.5 * (guess + y))
end
end
find_sqrt (generic function with 1 method)

julia> find_sqrt(9, 1)
3.000000001396984
``````
2 Likes

Thanks for the clear explanation, although it is important to signal that the if branches need the else. Indeed, the same algorithm -with the complementary if statement - return nothing

``````
function find_sqrt(x, guess)
y = x / guess
if y ≈ guess
guess
end
if !(y ≈ guess)
find_sqrt(x, 0.5 * (guess + y))
end
end

``````