# Macro works in REPL but not in script

**URL:** <https://discourse.julialang.org/t/macro-works-in-repl-but-not-in-script/69685>\
**Category:** General Usage\
**Tags:** macros, metaprogramming\
**Created:** [October 13, 2021, 1:09pm UTC](https://discourse.julialang.org/t/macro-works-in-repl-but-not-in-script/69685 "2021-10-13T13:09:34Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![emanuellima](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/emanuellima/32/25505_2.png) [@emanuellima](https://discourse.julialang.org/u/emanuellima)\
**Post date:** [October 13, 2021, 1:09pm UTC](https://discourse.julialang.org/t/macro-works-in-repl-but-not-in-script/69685/1 "2021-10-13T13:09:34Z")

</div>

So, I have a macro that works fine in the REPL, but doesn’t work when called on a script and I don’t know why. The macro simply creates a struct based on information stored in a NamedTuple. There is a regular function that reads the NamedTuple and produces a schema that is a String, and that string is passed to the macro, so that it can create the struct. Later on, that struct is going to be instantiated many times during the course of the program. My idea was to make all that work during compile time because this is a simulation library, so when the user inputed the NamedTuple, the library would compile itself to produce the correct struct and then proceed to run the simulation. I feel I have misunderstood something very deeply, because once the schema string is built it can be called from other macros such as @show, but not from my macro. It raises an error  
LoadError: LoadError: UndefVarError: state\_signature not defined  
But everything works correctly in the REPL.  
Any help is appreciated.

```julia
export generate_state_signature, @state_factory

macro state_factory(signature::Union{Symbol,String})
    schema = eval(signature)
    fields = map(x -> Meta.parse(x), split(schema))

    return quote
        struct State
            $(fields...)
            timestep::Int64
            substep::Int64

            function State($(fields...), timestep::Int64, substep::Int64)
                new($(fields...), timestep::Int64, substep::Int64)
            end

            State(;$(fields...), timestep::Int64=1, substep::Int64=1) = State($(fields...), timestep::Int64, substep::Int64)
        end
    end
end

function generate_state_signature(initial_conditions::NamedTuple)
    state_signature = ""

    for (variable, value) in pairs(initial_conditions)
        type = typeof(value)
        state_signature *= "$variable::$type "
    end

    return state_signature
end

```

These are the function and macro used on the script.

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [October 13, 2021, 1:21pm UTC](https://discourse.julialang.org/t/macro-works-in-repl-but-not-in-script/69685/2 "2021-10-13T13:21:55Z")

</div>

Difficult to help with no code, but I am guessing you haven’t thought about [macro hygiene](https://docs.julialang.org/en/v1/manual/metaprogramming/#Hygiene).

---

<div class="post-metadata">

**Author:** ![emanuellima](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/emanuellima/32/25505_2.png) [@emanuellima](https://discourse.julialang.org/u/emanuellima)\
**Post date:** [October 13, 2021, 1:24pm UTC](https://discourse.julialang.org/t/macro-works-in-repl-but-not-in-script/69685/3 "2021-10-13T13:24:58Z")

</div>

Thanks, will take a look. I added the code.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [October 13, 2021, 5:27pm UTC](https://discourse.julialang.org/t/macro-works-in-repl-but-not-in-script/69685/4 "2021-10-13T17:27:07Z")

</div>

I don’t know if that has anything to do with your problem, but the REPL loads, by default, the `InteractiveUtils` package. If you are using any of its functions, you should add `using` it in your script as well.

---

<div class="post-metadata">

**Author:** ![emanuellima](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/emanuellima/32/25505_2.png) [@emanuellima](https://discourse.julialang.org/u/emanuellima)\
**Post date:** [October 14, 2021, 12:44pm UTC](https://discourse.julialang.org/t/macro-works-in-repl-but-not-in-script/69685/5 "2021-10-14T12:44:14Z")

</div>

I tried both suggestions, but it didn’t work. Don’t know what else to do…

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [October 14, 2021, 12:58pm UTC](https://discourse.julialang.org/t/macro-works-in-repl-but-not-in-script/69685/6 "2021-10-14T12:58:46Z")

</div>

Provide a minimial (not) working example 🙂

---

<div class="post-metadata">

**Author:** ![emanuellima](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/emanuellima/32/25505_2.png) [@emanuellima](https://discourse.julialang.org/u/emanuellima)\
**Post date:** [October 14, 2021, 1:08pm UTC](https://discourse.julialang.org/t/macro-works-in-repl-but-not-in-script/69685/7 "2021-10-14T13:08:20Z")

</div>

So, for future reference, I fixed it by not using a macro, but by using a function that returns a quote and then eval() it. Macros remain a mystery to me. I could provide more code because the repo is still private, sorry.

---

<div class="post-metadata">

**Author:** ![timacro](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/timacro/32/32196_2.png) [@timacro](https://discourse.julialang.org/u/timacro)\
**Post date:** [January 3, 2022, 1:09pm UTC](https://discourse.julialang.org/t/macro-works-in-repl-but-not-in-script/69685/8 "2022-01-03T13:09:37Z")

</div>

> [@emanuellima](#):
>
> ```julia
> macro state_factory(signature::Union{Symbol,String})
> schema = eval(signature)
> 
> ```

by the [doc](https://docs.julialang.org/en/v1/manual/metaprogramming/) , perhaps the use of [`eval`](https://docs.julialang.org/en/v1/base/base/#Base.MainInclude.eval) in macros or generated functions is a sign that you’re doing something the wrong way.
