Error in returning value from function loop

Hello,
I have a function like this:

function ricky(x, k, r, I)
  for i in 1:I
    println("T", i, "\t= ", x)
    q = 1-x/k
    y = x * exp(r*q)
    x = y
  end
  return y
end

when I launch it, I get:

julia> ricky(50000, 2.2*10^7, 0.47, 24)
T1  = 50000
T2  = 79914.30104963228
T3  = 127644.309471282
T4  = 203673.98788725163
T5  = 324462.31598247594
T6  = 515551.7595856664
T7  = 815844.3952348703
T8  = 1.28279201312967e6
T9  = 1.9969756490546213e6
T10 = 3.0617026996446643e6
T11 = 4.588540941518327e6
T12 = 6.6561029840302905e6
T13 = 9.238094228093313e6
T14 = 1.213357406412708e7
T15 = 1.4980645412844565e7
T16 = 1.7404312164067835e7
T17 = 1.9199775856128015e7
T18 = 2.0383414901214056e7
T19 = 2.109967655786273e7
T20 = 2.1509439686879102e7
T21 = 2.173604725412978e7
T22 = 2.1858962851902638e7
T23 = 2.1924924681004412e7
T24 = 2.1960117884318497e7
ERROR: UndefVarError: y not defined
Stacktrace:
 [1] ricky(::Int64, ::Float64, ::Float64, ::Int64) at /home/gigiux/ricky.jl:8
 [2] top-level scope at none:1

How can I export x from inside the loop into the return statement but without making it global?
Thank you

Put local y in front of the loop.

2 Likes

Or just y = 0.0

1 Like

As they said, use:

In the original version the y variable is local to each iteration of the loop. You can see that here, for example:

julia> function f(x)
         for i in 1:2
           if i == 2
             println(" i = ", i)
             println(y)
           end
           y = x
           println(" i = ", i, " y = ", y)
         end
       end
f (generic function with 1 method)

julia> f(1)
 i = 1 y = 1
 i = 2
ERROR: UndefVarError: y not defined
Stacktrace:
 [1] f(::Int64) at ./REPL[12]:5
 [2] top-level scope at REPL[13]:1

julia>

When you add the local y or set y = something outside the loop, y becomes a variable in the scope of the function, and then it works:

julia> function f(x)
         local y
         for i in 1:2
           if i == 2
             println(" i = ", i)
             println(y)
           end
           y = x
           println(" i = ", i, " y = ", y)
         end
       end
f (generic function with 1 method)

julia> f(1)
 i = 1 y = 1
 i = 2
1
 i = 2 y = 1

julia>
2 Likes

Note that, even with the local y declaration, your function throws an error if I == 0, so not initializing y to a starting value before the loop is arguably an indication of a bug.

It looks like what you really want might to eliminate the y variable completely, since it seems redundant:

function ricky(x, k, r, I)
    for i = 1:I
        x *= exp(r * (1-x/k))
    end
    return x
end
5 Likes