# Metaprogramming help

**URL:** <https://discourse.julialang.org/t/metaprogramming-help/75807>\
**Category:** New to Julia\
**Tags:** metaprogramming\
**Created:** [February 4, 2022, 4:49pm UTC](https://discourse.julialang.org/t/metaprogramming-help/75807 "2022-02-04T16:49:32Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ribeiro](https://avatars.discourse-cdn.com/v4/letter/r/d9b06d/32.png) [@Ribeiro](https://discourse.julialang.org/u/Ribeiro)\
**Post date:** [February 4, 2022, 4:49pm UTC](https://discourse.julialang.org/t/metaprogramming-help/75807/1 "2022-02-04T16:49:32Z")

</div>

Hello,  
I want to change the value of a variable within a function in a for loop. Here’s a silly example.

```julia
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!

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [February 4, 2022, 4:56pm UTC](https://discourse.julialang.org/t/metaprogramming-help/75807/2 "2022-02-04T16:56:42Z")

</div>

`eval` is not metaprogramming. `eval` should not be used outside select circumstances.

Maybe try reading through [this blog post](https://jkrumbiegel.com/pages/2021-06-07-macros-for-beginners/) giving lots of explanation about metaprogramming.

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [February 4, 2022, 5:17pm UTC](https://discourse.julialang.org/t/metaprogramming-help/75807/3 "2022-02-04T17:17:12Z")

</div>

Perhaps use a callable mutable struct instead of a closure, which is syntactic sugar for a callable immutable struct. Then no metaprogramming is required.

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [February 4, 2022, 5:17pm UTC](https://discourse.julialang.org/t/metaprogramming-help/75807/4 "2022-02-04T17:17:35Z")

</div>

> [@Ribeiro](#):
>
> I want to change the value of a variable within a function in a for loop.

But your example is working, right? (apart from a syntax error, which I assume is related to copy-pasting here)

```julia
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?

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [February 4, 2022, 5:44pm UTC](https://discourse.julialang.org/t/metaprogramming-help/75807/5 "2022-02-04T17:44:55Z")

</div>

> [@Ribeiro](#):
>
> I have good reasons for this, don’t worry ;).

FWIW, I still worry 🙂

---

<div class="post-metadata">

**Author:** ![Ribeiro](https://avatars.discourse-cdn.com/v4/letter/r/d9b06d/32.png) [@Ribeiro](https://discourse.julialang.org/u/Ribeiro)\
**Post date:** [February 4, 2022, 6:20pm UTC](https://discourse.julialang.org/t/metaprogramming-help/75807/6 "2022-02-04T18:20:26Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [February 4, 2022, 6:23pm UTC](https://discourse.julialang.org/t/metaprogramming-help/75807/7 "2022-02-04T18:23:04Z")

</div>

Okay so your setup is like the following?

```julia
function foo(x, y, z)
    # complicated stuff involving some number k
    k = 100
    k + x + y + z
end

```

and you want to change the internals of `foo` on the fly so that it’s definition is akin to

```julia
foo_new(x, y, z)
    k = 200
    k + x + y + z
end

```

?

---

<div class="post-metadata">

**Author:** ![Ribeiro](https://avatars.discourse-cdn.com/v4/letter/r/d9b06d/32.png) [@Ribeiro](https://discourse.julialang.org/u/Ribeiro)\
**Post date:** [February 4, 2022, 6:27pm UTC](https://discourse.julialang.org/t/metaprogramming-help/75807/8 "2022-02-04T18:27:11Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [February 4, 2022, 6:30pm UTC](https://discourse.julialang.org/t/metaprogramming-help/75807/9 "2022-02-04T18:30:41Z")

</div>

Was the function `f` defined while capturing a global variable `k`?

What you are asking for is not possible, unfortunately. You have have the function `f` take `k` as an input.

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [February 4, 2022, 6:34pm UTC](https://discourse.julialang.org/t/metaprogramming-help/75807/10 "2022-02-04T18:34:01Z")

</div>

Making explicit the suggestion by @Jeff_Emanuel:

```julia
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

```

---

<div class="post-metadata">

**Author:** ![Ribeiro](https://avatars.discourse-cdn.com/v4/letter/r/d9b06d/32.png) [@Ribeiro](https://discourse.julialang.org/u/Ribeiro)\
**Post date:** [February 4, 2022, 6:47pm UTC](https://discourse.julialang.org/t/metaprogramming-help/75807/11 "2022-02-04T18:47:52Z")

</div>

There’s no equivalent to the eval in Matlab, where you can run a string?  
Like

```julia
k=1
tmp="myfun(a,b)=a+b*$k"
eval(tmp)

```

Or something in these lines?

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [February 4, 2022, 6:49pm UTC](https://discourse.julialang.org/t/metaprogramming-help/75807/12 "2022-02-04T18:49:08Z")

</div>

you need to first parse that String

```julia
julia> eval(Meta.parse(tmp))
myfun (generic function with 1 method)

```

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [February 4, 2022, 6:49pm UTC](https://discourse.julialang.org/t/metaprogramming-help/75807/13 "2022-02-04T18:49:29Z")

</div>

> [@carstenbauer](#):
>
> Making explicit the suggestion by @Jeff_Emanuel:

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
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.

---

<div class="post-metadata">

**Author:** ![Ribeiro](https://avatars.discourse-cdn.com/v4/letter/r/d9b06d/32.png) [@Ribeiro](https://discourse.julialang.org/u/Ribeiro)\
**Post date:** [February 4, 2022, 6:52pm UTC](https://discourse.julialang.org/t/metaprogramming-help/75807/14 "2022-02-04T18:52:57Z")

</div>

Thanks, folks.  
I think both of these options work!  
Thanks again!

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [February 4, 2022, 8:08pm UTC](https://discourse.julialang.org/t/metaprogramming-help/75807/15 "2022-02-04T20:08:47Z")

</div>

> [@ffevotte](#):
>
> in the OP

I believe he wants to change the value of `k` in the closure, which requires mutability, so the more verbose mutable struct is require.
