# FunctionWrapper somewhat dodges world age restrictions

**URL:** https://discourse.julialang.org/t/functionwrapper-somewhat-dodges-world-age-restrictions/107025
**Category:** General Usage
**Created:** [December 2, 2023, 12:04am UTC](https://discourse.julialang.org/t/functionwrapper-somewhat-dodges-world-age-restrictions/107025 "2023-12-02T00:04:34Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [December 2, 2023, 12:04am UTC](https://discourse.julialang.org/t/functionwrapper-somewhat-dodges-world-age-restrictions/107025/1 "2023-12-02T00:04:34Z")

</div>

MWE below, it appears that rather than using a function in a preexisting world age, FunctionWrapper uses the first `eval`ed method inside a function but not any after that; EDIT unless you redefine the function after a call even with identical code, or if the inner `eval`ed function was called before. If someone has an explanation that would be great, but otherwise this could just be an FYI. EDIT: Just in case, you should never do this without `invokelatest` because there’s no benefit to making a method invalidate its own compiled code on every call.

```julia
julia> function foo(n)
         for i in n:n+1
           @eval fooi() = $i
           println(fooi())
         end
       end
           
julia> foo(1)
ERROR: MethodError: no method matching fooi()
The applicable method may be too new: running in world age 32434, while current world is 32435.
Closest candidates are:
  fooi() at REPL[1]:3 (method too new to be called from this world context.)
...
julia> fooi() # foo(1) made fooi()=1 before error
1

julia> foo(2) # uses preexisting fooi()=1
1
1

```

```julia
julia> using FunctionWrappers: FunctionWrapper as Fw

julia> function bar(n)
         for i in n:n+1
           @eval bari() = $i
           println(Fw{Int, Tuple{}}(bari)())
         end
       end
bar (generic function with 1 method)

julia> bar(1) # doesn't error, but only uses 1st bari()=1
1
1

julia> bari() # last run made final bari()=2
2

julia> bar(3) # uses 1st bari()=3, not preexisting bari()=2
3
3

julia> function bar(n)
         for i in n:n+1
           @eval bari() = $i
           println(Fw{Int, Tuple{}}(bari)())
         end
       end
bar (generic function with 1 method)

julia> bari()
4

julia> bar(5) # now uses preexisting bari()=4
4
4

```

Now evading this effect to be more in line with world age issues:

```julia
julia> using FunctionWrappers: FunctionWrapper as Fw

julia> bari() = 0
bari (generic function with 1 method)

julia> function bar(n)
         for i in n:n+1
           @eval bari() = $i
           println(Fw{Int, Tuple{}}(bari)())
         end
       end
bar (generic function with 1 method)

julia> bari() # this call is crucial to avoid the previous effect
0

julia> bar(1) # uses preexisting bari()=0
0
0

```

---

<div class="post-metadata">

### Author: ![Tarny\_GG\_Channie](https://avatars.discourse-cdn.com/v4/letter/t/3bc359/32.png) [@Tarny\_GG\_Channie](https://discourse.julialang.org/u/Tarny_GG_Channie)
#### Post date: [December 2, 2023, 12:50am UTC](https://discourse.julialang.org/t/functionwrapper-somewhat-dodges-world-age-restrictions/107025/2 "2023-12-02T00:50:15Z")

</div>

World age was made for optimization reasons, for example, by inlining then doing a bunch of stuff. Function wrapper was likely implemented as a function pointer and thus can use the newest version of the function.

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [December 2, 2023, 1:36am UTC](https://discourse.julialang.org/t/functionwrapper-somewhat-dodges-world-age-restrictions/107025/3 "2023-12-02T01:36:07Z")

</div>

> [@Tarny\_GG\_Channie](#):
>
> thus can use the newest version of the function.

It doesn’t, if it did then the looped println would show two adjacent integers, not the same one twice.

---

<div class="post-metadata">

### Author: ![Tarny\_GG\_Channie](https://avatars.discourse-cdn.com/v4/letter/t/3bc359/32.png) [@Tarny\_GG\_Channie](https://discourse.julialang.org/u/Tarny_GG_Channie)
#### Post date: [December 2, 2023, 1:53am UTC](https://discourse.julialang.org/t/functionwrapper-somewhat-dodges-world-age-restrictions/107025/4 "2023-12-02T01:53:23Z")

</div>

I think some weird optimization issues. I don’t think it’s a good idea to rely on these internal behaviors then.

---

<div class="post-metadata">

### Author: ![jameson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jameson/32/23_2.png) [@jameson](https://discourse.julialang.org/u/jameson)
#### Post date: [December 6, 2023, 5:32am UTC](https://discourse.julialang.org/t/functionwrapper-somewhat-dodges-world-age-restrictions/107025/5 "2023-12-06T05:32:26Z")

</div>

That sounds like a codegen bug if reproduceable, as FunctionWrappers always should see the latest world when the code is called

Edit: I think I recall now that we didn’t add support for functions that are inferred to be constant. We should, but haven’t yet, and might not have an issue open for it?
