Hello,
I want to change the value of a variable within a function in a for loop. Here’s a silly example.
for k in 1:10
myfun(a,b) = a*b+k
println myfun(1,2)
end
So k is not an input, but I want to change it. I have good reasons for this, don’t worry ;).
I’m thinking I need to have the function definition as a string and then eval that string, or something like that. I don’t want to use k as a global variable, as that leads to issues.
Can anyone help?
Thanks a lot!
Perhaps use a callable mutable struct instead of a closure, which is syntactic sugar for a callable immutable struct. Then no metaprogramming is required.
But your example is working, right? (apart from a syntax error, which I assume is related to copy-pasting here)
julia> for k in 1:10
myfun(a,b) = a*b+k
println(myfun(1,2))
end
3
4
5
6
7
8
9
10
11
12
I think this creates a new function that closes over the local variable k in each loop iteration. Is there anything wrong with this approach in your real context?
I was sure people would ask for the reasons behind this =P.
Basically this example is not at all how my real problem will be. The function will be called from other functions and I don’t want to risk having that unclear k in there.
My reason for doing this is just to validate some stuff in my code. So I don’t plan on keeping this in the actual code, just in a validation script.
I don’t want to modify the function or its inputs because that function is already pretty complicated in its definition (it actually belongs to a struct).
Anywho, any ideas on how to eval the function definition in the loop?
Thanks!
Yes, I think you got it.
I’m looping over k and it’s used in a function. I want to modify it inside that function (which I’ll redefine anyway for each value of k). So I want to redefine the function based on what’s effectively a global var (without using global vars, as they can’t be redefined).
Is this clearer?
julia> mutable struct MyFun
k::Int64
end
julia> (f::MyFun)(a,b) = a * b + f.k
julia> myfun = MyFun(0);
julia> for k in 1:10
myfun.k = k
println(myfun(1,2))
end
3
4
5
6
7
8
9
10
11
12
Yes, this seems to be a natural way to do what’s needed.
And it is actually very similar to the approach in the OP, which AFAIK is translated under the hood as something akin to:
julia> struct MyFun
k::Int64
end
julia> (f::MyFun)(a,b) = a * b + f.k
julia> for k in 1:10
myfun = MyFun(k)
println(myfun(1,2))
end
3
4
5
6
7
8
9
10
11
12
So I’m wondering if there is something wrong with the solution outlined in the OP, that would rule out this class of techniques.