# Eval from macro

**URL:** <https://discourse.julialang.org/t/eval-from-macro/102718>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [August 11, 2023, 3:14pm UTC](https://discourse.julialang.org/t/eval-from-macro/102718 "2023-08-11T15:14:45Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![gitboy16](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gitboy16/32/24906_2.png) [@gitboy16](https://discourse.julialang.org/u/gitboy16)\
**Post date:** [August 11, 2023, 3:14pm UTC](https://discourse.julialang.org/t/eval-from-macro/102718/1 "2023-08-11T15:14:45Z")

</div>

Hi,

Here is some code:

```julia
module mypack

export @my_eval

macro my_eval(pkg)
    pp = pkg |> string
    eval(Meta.parse(string("using ", pp)))
end

end

@my_eval CSV

```

In the code above, I am trying to use a macro to achieve the same as `using CSV`.  
However it does not seem that the package is “loaded”.

How should I correct the code to achieve the same effect as `using CSV`?

Thank you

---

<div class="post-metadata">

**Author:** ![dylanxyz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dylanxyz/32/36646_2.png) [@dylanxyz](https://discourse.julialang.org/u/dylanxyz)\
**Post date:** [August 11, 2023, 4:59pm UTC](https://discourse.julialang.org/t/eval-from-macro/102718/2 "2023-08-11T16:59:57Z")

</div>

Macros and metaprogramming in julia can be a powerful tool, but it is a good idea to only use macros where there’s no other option. I’m not sure what you trying to do, besides loading `CSV`. So, can’t you just `using CSV`, instead?

Another thing, using `eval` inside a macro is not a good practice, because the macro run a _parse_ time. Instead of `eval`’ing the expression inside the macro, you should _return_ it. So, to correct your macro, you should rewrite as:

```julia
macro my_eval(pkg)
    :(using $pkg)
end

```

But again, what would be the point of such macro if you can just write `using pkg`?

---

<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:** [August 11, 2023, 7:50pm UTC](https://discourse.julialang.org/t/eval-from-macro/102718/3 "2023-08-11T19:50:16Z")

</div>

> [@gitboy16](#):
>
> However it does not seem that the package is “loaded”.

Even though I agree macros should mostly return expressions that get evaluated, it does work for me.

```julia
julia> LinearAlgebra
ERROR: UndefVarError: LinearAlgebra not defined

julia> using .mypack; @my_eval LinearAlgebra

julia> LinearAlgebra # not in call scope
ERROR: UndefVarError: LinearAlgebra not defined

julia> mypack.LinearAlgebra # in definition scope
LinearAlgebra

```

The `eval` running in the macro body executes in the global scope of `my_eval`, thus inside `mypack`. It won’t change even if you put the `eval` in a returned expression instead, macro hygiene rules look for functions in the macro definition scope. You can use `esc` on a function expression to make it in the macro call scope:

```julia
julia> module mypack # after restart session

       export @my_eval

       macro my_eval(pkg)
           pp = pkg |> string
           :($(esc(:eval))(Meta.parse(string("using ", $pp))))
       end

       end
Main.mypack

julia> LinearAlgebra
ERROR: UndefVarError: LinearAlgebra not defined

julia> using .mypack; @my_eval LinearAlgebra

julia> LinearAlgebra # now in call scope
LinearAlgebra

julia> mypack.LinearAlgebra # not in definition scope
ERROR: UndefVarError: LinearAlgebra not defined

```

dylanxyz’s version has a keyword `using` instead of a function, so it shows up in the call scope.

---

<div class="post-metadata">

**Author:** ![danielwe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielwe/32/35657_2.png) [@danielwe](https://discourse.julialang.org/u/danielwe)\
**Post date:** [August 11, 2023, 8:22pm UTC](https://discourse.julialang.org/t/eval-from-macro/102718/4 "2023-08-11T20:22:05Z")

</div>

Just a note that if your goal is to load a module programmatically from a name stored in a variable, you can just use `@eval` directly:

```julia
julia> mods = [:LinearAlgebra, "SparseArrays"];

julia> for mod in mods
           @eval using $(Symbol(mod))
       end

julia> LinearAlgebra, SparseArrays
(LinearAlgebra, SparseArrays)

```

---

<div class="post-metadata">

**Author:** ![gitboy16](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gitboy16/32/24906_2.png) [@gitboy16](https://discourse.julialang.org/u/gitboy16)\
**Post date:** [August 12, 2023, 9:24pm UTC](https://discourse.julialang.org/t/eval-from-macro/102718/5 "2023-08-12T21:24:31Z")

</div>

Thank you all for your feedbacks. I am trying to solve the problem I raised in:

> [@Using package / install automatically](https://discourse.julialang.org/t/using-package-install-automatically/70896):
>
> Hi, If I do using DataFrames and the package is not install, Julia 1.7 will ask me if I want to install it and I will have to type y or n. Is there a way to skip that step and have Julia installed the package if it is not available? Of course one can write a function that check if the package is installed or not and then install it. I was wondering if there is an option I can pass to using DataFrames that will automatically install the package if not installed? Could that be a feature reque…

With the answer above, I can now create a macro like :  
`@auto_download using your_package`  
Which will automatically download, install and load the package without having an annoying prompt asking me whether I want to install the package (in case it is not installed).
