Eval of an expression containing :using

I have got a weird result with an expression containing :using.
Let me show you an example.

julia> expression = :(using Gurobi)
:(using Gurobi)

julia> expression2 = Expr(:using, "Gurobi")
:(using Gurobi)

Both expressions appear to be same. But only eval(expression) worked.

julia> eval(expression)
ERROR: ArgumentError: Package Gurobi not found in current path:
- Run `import Pkg; Pkg.add("Gurobi")` to install the Gurobi package.

Stacktrace:
 [1] require(::Module, ::Symbol) at .\loading.jl:823
 [2] eval at .\boot.jl:328 [inlined]
 [3] eval(::Expr) at .\client.jl:404
 [4] top-level scope at none:0

julia> eval(expression2)

julia>

What was wrong with expression2?

Edit: the version of Julia is 1.1.0

You can use dump to find out.

Symbols in the expressions are (almost?) always Symbols and not Strings.

I found a difference between expression and expression2.
I read the manual and saw dump… but maybe I didn’t really understand its uses :sweat_smile:

julia> dump(expression)
Expr
  head: Symbol using
  args: Array{Any}((1,))
    1: Expr
      head: Symbol .
      args: Array{Any}((1,))
        1: Symbol Gurobi

julia> dump(expression2)
Expr
  head: Symbol using
  args: Array{Any}((1,))
    1: String "Gurobi"

And I managed to think a solution out. The expression does not look nice, though.

julia> expression3 = Expr(:using, Expr(:., Symbol("Gurobi")))
:(using Gurobi)

julia> dump(expression3)
Expr
  head: Symbol using
  args: Array{Any}((1,))
    1: Expr
      head: Symbol .
      args: Array{Any}((1,))
        1: Symbol Gurobi

Any simpler suggestions?

  1. Symbols can be constructed directly. :Gurobi.

  2. Are you sure you didn’t change expression to :(using .Gurobi) instead?

  3. It depends on what exactly are you trying to do. If you are looking for a way to not use any expression literal, then, well, this is what you are asking for and it’s as simple as it gets. If you are looking for a way to construct an expression “dynamically”, then you can just use interpolation, :(using $name). You still need Symbol and if it’s a user supplied argument you should ask for Symbol directly.

What I want to do is to check whether a package is installed or not. An array of symbols is given, and the task is performed with a for loop. :(using $name) works nicely with my purpose :slight_smile:.

It is still difficult for me to understand concepts of metaprogramming in Julia. Your comments were really helpful to get the feel of them, although lots of them have already been explained in Docs.