# Macro to create a generated function

**URL:** <https://discourse.julialang.org/t/macro-to-create-a-generated-function/99135>\
**Category:** General Usage\
**Tags:** question, macros, metaprogramming, runtimegeneratedfunc\
**Created:** [May 19, 2023, 8:09pm UTC](https://discourse.julialang.org/t/macro-to-create-a-generated-function/99135 "2023-05-19T20:09:52Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![devetak-m](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/devetak-m/32/50066_2.png) [@devetak-m](https://discourse.julialang.org/u/devetak-m)\
**Post date:** [May 19, 2023, 8:09pm UTC](https://discourse.julialang.org/t/macro-to-create-a-generated-function/99135/1 "2023-05-19T20:09:52Z")

</div>

Hello.

I want to create a macro that reads:

```julia
macro store(agent, value)

    f_name = Symbol("store_", value)

    f = quote 
        @inline @generated function $f_name(a, v)
            return quote a.value = v end
        end
    end

    eval(f)
    return :($f_name($agent, $value))
    
end

```

The idea is that the macro creates a generated function(it needs to be generated as if the agent does not include that field then it returns :(nothing), I did not include that part) to store the value in the agent. Unfortunately, I cannot seem to get the line:

```julia
return quote a.value = v end

```

to work either value is there or the data that is stored in value at call(ie [100]). I think that is because it is a quote within a quote. Does anybody know how to achieve that?

Thank you in advance.

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [May 20, 2023, 6:51am UTC](https://discourse.julialang.org/t/macro-to-create-a-generated-function/99135/2 "2023-05-20T06:51:40Z")

</div>

You don’t need a generated function, I think constant propagation handles this fine these days

```julia
julia> struct MyStruct
           a_field::Int
       end

julia> get_a_field(x) = hasfield(typeof(x), :a_field) ? x.a_field : nothing
get_a_field (generic function with 1 method)

julia> m = MyStruct(1)
MyStruct(1)

julia> @code_typed get_a_field(m)
CodeInfo(
1 ─ %1 = Base.getfield(x, :a_field)::Int64
└── return %1
) => Int64

julia> struct MyOtherStruct
           b_field::Int
       end

julia> mo = MyOtherStruct(2)
MyOtherStruct(2)

julia> @code_typed get_a_field(mo)
CodeInfo(
1 ─ nothing::Nothing
└── return Main.nothing
) => Nothing

```

---

<div class="post-metadata">

**Author:** ![devetak-m](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/devetak-m/32/50066_2.png) [@devetak-m](https://discourse.julialang.org/u/devetak-m)\
**Post date:** [May 20, 2023, 7:48am UTC](https://discourse.julialang.org/t/macro-to-create-a-generated-function/99135/3 "2023-05-20T07:48:25Z")

</div>

Very cool!

I did an experiment where I was checking hasfield() in a for loop and it was noticeably slower. Do you know what triggers constant propagation in this case?

Thank you for answering. You seem very knowledgeable about Julia would you happen also to know how to fix the above code, for future reference?

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [May 20, 2023, 7:51am UTC](https://discourse.julialang.org/t/macro-to-create-a-generated-function/99135/4 "2023-05-20T07:51:57Z")

</div>

The symbol you are checking just needs to be fixed within a function (it can be fixed before and then fed in, it just has to be constant _somewhere_ close enough for the compiler to use it), then the compiler can check the type for the field beforehand. If you pass it in dynamically as a `Symbol` argument, that doesn’t work. All places where you write `obj.field` in some code this is the same as writing `getfield(obj, :field)` so that kind of constant propagation / folding happens all the time.
