# Call macro created function/types from generated function. world age problem

**URL:** <https://discourse.julialang.org/t/call-macro-created-function-types-from-generated-function-world-age-problem/28859>\
**Category:** Performance\
**Created:** [September 17, 2019, 7:01pm UTC](https://discourse.julialang.org/t/call-macro-created-function-types-from-generated-function-world-age-problem/28859 "2019-09-17T19:01:20Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Orbots](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/orbots/32/3392_2.png) [@Orbots](https://discourse.julialang.org/u/Orbots)\
**Post date:** [September 17, 2019, 7:01pm UTC](https://discourse.julialang.org/t/call-macro-created-function-types-from-generated-function-world-age-problem/28859/1 "2019-09-17T19:01:20Z")

</div>

I want to allow a user of my module to generate some types and functions via a macro which are then supported by generated functions.

For _reasons_, I am able to deduce constant scalar numbers from type information for a pair of types. Could be multiple scalars for a pair. I’d like to exploit this with generated functions to compute this total scalar at compilation time.

Two reasons for wanting this.  
a) performance guarantees ( nothing is faster than if it is guaranteed to be constant scalar vs maybe jit figures out it’s a scalar )  
b) simpler implementation. if I need to chain a bunch of these as `Expr(:call)`s vs reducing into a scalar the implementation becomes much simpler.

Simplified MWE

```julia
julia> module Foo
         macro gen(x)
           name = Symbol("foo"*string(x))
           typ = :(struct $name end)
           fun = :(foo(f::$name) = $x*$x)  
           Expr(:escape, Expr(:block, typ, fun))
         end

         struct foo0 end
         foo(x::foo0) = 0

         @gen(2)
           
         @generated function bar(a,b)
           v = foo(a())*foo(b())
           v
         end

         struct foo1 end
         foo(x::foo1) = 1

         @gen(3)
       end

julia> Foo.bar(Foo.foo0(),Foo.foo1())
ERROR: MethodError: no method matching Main.Foo.foo1()
The applicable method may be too new: running in world age 25591, while current world is 25595.
Closest candidates are:
  Main.Foo.foo1() at REPL[5]:19 (method too new to be called from this world context.)
...

julia> Foo.bar(Foo.foo0(),Foo.foo0())
0

julia> Foo.bar(Foo.foo0(),Foo.foo2())
0

julia> Foo.bar(Foo.foo0(),Foo.foo3())
ERROR: ...world age

julia> Foo.@gen(4); Foo.bar(Foo.foo4(),Foo.foo4()); # ultimate goal

```

I’ve seen a number of threads related to world age “work arounds” which I can’t quite get my head around. There are some packages out there as well ( GG.jl, FunctionWrappers ), not really sure how/if I can apply those to help.

Anyone have a recommendation/code example? I suspect my reason ‘a’ is not doable, but reason ‘b’ would still be nice to have a solution for.

Edit: specify that scalars are constant  
Edit 2: I’ve got a working solution now.

---

<div class="post-metadata">

**Author:** ![Orbots](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/orbots/32/3392_2.png) [@Orbots](https://discourse.julialang.org/u/Orbots)\
**Post date:** [September 17, 2019, 7:26pm UTC](https://discourse.julialang.org/t/call-macro-created-function-types-from-generated-function-world-age-problem/28859/2 "2019-09-17T19:26:50Z")

</div>

I tried out `FunctionWrappers` and I seem to have a workable solution in my toy REPL example. Is this a reasonable way of doing this?

Second question. How do I avoid having to specify `Main.foo`, as it may not be `Main` where `foo` was created?

```julia
julia> module Foo
         using FunctionWrappers: FunctionWrapper
         macro gen(x)
           name = Symbol("foo"*string(x))
           typ = :(struct $name end)
           fun = :(foo(f::Type{$name}) = $x*$x)  
           Expr(:escape, Expr(:block, typ, fun))
         end

         @generated function bar(a,b)
           v = (FunctionWrapper{Int64,Tuple{Type{a}}}(Main.foo))(a)*(FunctionWrapper{Int64,Tuple{Type{b}}}(Main.foo))(b)
           v
         end
       end
Main.Foo

julia> Foo.@gen(2); Foo.@gen(3); Foo.bar(foo2(),foo3())
36

```

---

<div class="post-metadata">

**Author:** ![Orbots](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/orbots/32/3392_2.png) [@Orbots](https://discourse.julialang.org/u/Orbots)\
**Post date:** [September 17, 2019, 8:19pm UTC](https://discourse.julialang.org/t/call-macro-created-function-types-from-generated-function-world-age-problem/28859/3 "2019-09-17T20:19:36Z")

</div>

Sorry, I keep answering my own questions. I seem to to have figured it out. Assuming FunctionWrappers is a reasonable thing to use.

Final piece of the puzzle is to add a `foo` placeholder and then use a `Foo.` module scope in the macro

```julia
module Foo
         export foo
         using FunctionWrappers: FunctionWrapper

         macro gen(x)
           name = Symbol("foo"*string(x))
           typ = :(struct $name end)
           fun = :(Foo.foo(f::Type{$name}) = $x*$x)  
           Expr(:escape, Expr(:block, typ, fun))
         end
         foo(x) = 42
         @generated function bar(a,b)
           v = (FunctionWrapper{Int64,Tuple{Type{a}}}(foo))(a)*(FunctionWrapper{Int64,Tuple{Type{b}}}(foo))(b)
           v
         end
       end

```
