# What exactly are the arguments of \`Base.require\`?

**URL:** <https://discourse.julialang.org/t/what-exactly-are-the-arguments-of-base-require/33373>\
**Category:** New to Julia\
**Tags:** module\
**Created:** [January 15, 2020, 1:28am UTC](https://discourse.julialang.org/t/what-exactly-are-the-arguments-of-base-require/33373 "2020-01-15T01:28:43Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [January 15, 2020, 1:28am UTC](https://discourse.julialang.org/t/what-exactly-are-the-arguments-of-base-require/33373/1 "2020-01-15T01:28:43Z")

</div>

It may be my stupidity, but I do not seem to find exactly what I should pass to Base.require.

[The docs](https://docs.julialang.org/en/v1/base/base/#Base.require) are not very clear on what I should pass as first parameter (is it the current module? is it Main?). And the only mention with a small tidbit of code in the [module documentation](https://docs.julialang.org/en/v1/manual/modules/#Relative-and-absolute-module-paths-1) treat Base.require as it had only the second parameter.

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [January 15, 2020, 9:05am UTC](https://discourse.julialang.org/t/what-exactly-are-the-arguments-of-base-require/33373/2 "2020-01-15T09:05:38Z")

</div>

I think the docs didn’t fully update when the `into` argument was added. Note that there is still a 1-argument method.

In brief, the 2-argument version is used for handling dependencies. If `PkgA` depends on `PkgB` but you haven’t said `using PkgB`, then `PkgB` will not be available as a name in `Main`. But `PkgA` needs to know about it.

`Base.require` is definitely not something I think of as “first steps”—in general there should be no need to call it directly. What are you trying to do?

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [January 15, 2020, 5:23pm UTC](https://discourse.julialang.org/t/what-exactly-are-the-arguments-of-base-require/33373/3 "2020-01-15T17:23:07Z")

</div>

I did not see the Base.require with just one argument still existed.

I think I maybe misfiled the question, XD, as I had the feeling I was not understanding something I believed to be basic I filed it as first steps.

I have some code that implements many mathematical models and that I will make available as a package in the future. This code includes a module that makes easier to a package user (but mostly to myself) to call some model over some file using some solver. I do not want to add all possible solvers as dependencies of the package just for this. I want that based on the “use this solver” parameter given by the user, the code dynamically loads the specific solver package (assuming the user must have installed if they told the method to use it).

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [January 15, 2020, 6:07pm UTC](https://discourse.julialang.org/t/what-exactly-are-the-arguments-of-base-require/33373/4 "2020-01-15T18:07:37Z")

</div>

You know about [Requires.jl](https://github.com/MikeInnes/Requires.jl)?

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [January 15, 2020, 6:22pm UTC](https://discourse.julialang.org/t/what-exactly-are-the-arguments-of-base-require/33373/5 "2020-01-15T18:22:02Z")

</div>

I did not study it fully, but I knew about its existence. It seems overkill for what I want. I do not want to a part of my code to be loaded only if some package is available. The part that changes from solver to solver is small (thanks to JuMP) I just want to not need to define them as dependencies, nor have Julia print a message to the user saying that there is a bug with my code because I import packages that are not dependencies.

---

<div class="post-metadata">

**Author:** ![kevbonham](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kevbonham/32/216165_2.png) [@kevbonham](https://discourse.julialang.org/u/kevbonham)\
**Post date:** [January 16, 2020, 1:59am UTC](https://discourse.julialang.org/t/what-exactly-are-the-arguments-of-base-require/33373/6 "2020-01-16T01:59:21Z")

</div>

> [@Henrique\_Becker](#):
>
> nor have Julia print a message to the user saying that there is a bug with my code because I import packages that are not dependencies

I’m not 100% sure, but I think that this is not currently possible. In order to import a package and use its types, it needs to be a dependency. This is why there are a bunch of `<Domain>Base.jl` packages that define abstract types that other packages can use for interoperability without taking on massive dependencies.

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [January 16, 2020, 2:08am UTC](https://discourse.julialang.org/t/what-exactly-are-the-arguments-of-base-require/33373/7 "2020-01-16T02:08:30Z")

</div>

I’ve found it works better to just require the user to pass a solver (just as JuMP itself does); the alternative is to depend on solvers and/or use Requires.jl, neither of which is ideal (especially with non-free solvers that the user might not have). I think things like choosing solver-specific parameters are better handled in the documentation (e.g. say to use such-and-such solver, do `using Solver` and pass the solver with these parameters). Or, possibly, depend on just one default (ideally open source) solver and require the user to pass a solver if they want to use a non-default one.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [January 16, 2020, 3:22am UTC](https://discourse.julialang.org/t/what-exactly-are-the-arguments-of-base-require/33373/8 "2020-01-16T03:22:11Z")

</div>

> [@kevbonham](#):
>
> I’m not 100% sure, but I think that this is not currently possible.

I think you can use packages that are not dependencies, otherwise [Requires.jl](https://github.com/MikeInnes/Requires.jl) would not be possible.

I have not tested my specific approach yet, but I think I can `require` a package that is not a dependency and risk having an exception if it is not present in the system. The idea here is that this require will only execute if the user explicitly orders it to use some solver, and all code that depends on such specific package will be just below the `require` call. The method that uses the non-dependency package will not even be called if the user do not order the use of the specific solver.

> [@ericphanson](#):
>
> I’ve found it works better to just require the user to pass a solver (just as JuMP itself does); the alternative is to depend on solvers and/or use Requires.jl, neither of which is ideal (especially with non-free solvers that the user might not have).

This really does not work for this specific case, as what I want is to provide such solver selection and configuration as flags of a script I will be the main user, but other users/scientists may find useful too. The core functionality of my package uses the approach you describe (all model building methods take a model object as a parameter and do not meddle with the specific solver), but this non-core functionality is a command-line script that should be ready to use the solver the user wants with the most common parameters among the solvers without having the user to install all solvers for this. I use it to do my experiments, and it would be an easy way to other scientists reproduce my results. If they want to pass additional flags they can mess with the code.

> [@tim.holy](#):
>
> I think the docs didn’t fully update when the `into` argument was added. Note that there is still a 1-argument method.

I would also like to point that the `require` method that takes just one parameter [is not documented](https://docs.julialang.org/en/v1/base/base/#Base.require) even if [yet present in the code](https://github.com/JuliaLang/julia/blob/2d5741174ce3e6a394010d2e470e4269ca54607f/base/loading.jl#L920)

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [January 16, 2020, 6:42am UTC](https://discourse.julialang.org/t/what-exactly-are-the-arguments-of-base-require/33373/9 "2020-01-16T06:42:15Z")

</div>

The docstrings of `require` is heavily outdated ([https://github.com/JuliaLang/julia/issues/27822](https://github.com/JuliaLang/julia/issues/27822))

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [January 16, 2020, 10:34am UTC](https://discourse.julialang.org/t/what-exactly-are-the-arguments-of-base-require/33373/10 "2020-01-16T10:34:17Z")

</div>

> [@Henrique\_Becker](#):
>
> This really does not work for this specific case, as what I want is to provide such solver selection and configuration as flags of a script I will be the main user, but other users/scientists may find useful too. The core functionality of my package uses the approach you describe (all model building methods take a model object as a parameter and do not meddle with the specific solver), but this non-core functionality is a command-line script that should be ready to use the solver the user wants with the most common parameters among the solvers wit

The way I would address that situation is to have the command-line script outside of the package code, in a separate folder with its own Project and Manifest files. Then that script can load the package as well as the solver you used and do the computation. That way the Manifest will help make it reproducible. If reproducibility is the goal, I don’t think optional dependencies are a good idea since then the script does slightly different things depending on their environment.

---

<div class="post-metadata">

**Author:** ![kevbonham](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kevbonham/32/216165_2.png) [@kevbonham](https://discourse.julialang.org/u/kevbonham)\
**Post date:** [January 16, 2020, 2:51pm UTC](https://discourse.julialang.org/t/what-exactly-are-the-arguments-of-base-require/33373/11 "2020-01-16T14:51:33Z")

</div>

> [@Henrique\_Becker](#):
>
> I think you can use packages that are not dependencies, otherwise [Requires.jl](https://github.com/MikeInnes/Requires.jl) would not be possible.

I **think** that’s because Requires.jl makes a macro that allows you to write code that’s not actually evaluated when you load your package.

> [@Henrique\_Becker](#):
>
> I have not tested my specific approach yet, but I think I can `require` a package that is not a dependency and risk having an exception if it is not present in the system.

By all means, try and report back. My confidence is only at ~60% on this. But I’m pretty certain that if you include things that aren’t defined, even if they’re inside functions or other blocks, julia typically throws the error when it tries to compile.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [January 28, 2020, 5:53am UTC](https://discourse.julialang.org/t/what-exactly-are-the-arguments-of-base-require/33373/12 "2020-01-28T05:53:22Z")

</div>

I had a lot to work to do before answering your question, XD. Seems like I would be able to do what I wanted (i.e., not use Requires.jl but use a package that is not a hard dependency of mine) if my use case was simpler but, unfortunately, my use case is more convoluted. My idea was using the code below:

```julia
function import_if_necessary(module_sym :: Symbol) :: Nothing
  if !Base.isdefined(@ __MODULE__ , module_sym)
    Base.include_string(@ __MODULE__ , "import $(module_sym)")
  end 
end

function empty_configured_model(::Val{:CPLEX}, p_args)
  Base.invokelatest(import_if_necessary, :CPLEX)
  Base.invokelatest(cplex_empty_configured_model, p_args)
end

```

The method `cplex_empty_configured_model` in question called methods defined by package/module CPLEX inside it. This worked. The problem was in the function that called `optimize!`, it did not work even putting the call to `optimize!` in the same module, calling it with `Base.invokelatest` and, therefore, giving it access to the CPLEX module. As `optimize!` is not a CPLEX method but calls a MathOptInterface method that has an specialization defined in CPLEX.jl, this workaround did not in fact work. If I just wanted to build the model using a specific solver, it would have worked, but as I need to call `optimize!` the problem becomes harder.

I had to settle for using Requires.jl and asking the user to manually add an “import SolverPackageX” (with the solver package they will use) in the script before calling a method that collects all command-line arguments and do what needs to be done (i.e., the user has to manually add a line to a 5-line script or Requires.jl will also not solve my problem).

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [January 28, 2020, 6:41am UTC](https://discourse.julialang.org/t/what-exactly-are-the-arguments-of-base-require/33373/13 "2020-01-28T06:41:52Z")

</div>

If you are OK with `invokelatest` you can use `require` like this

```julia
withpkg(f, pkgid::Base.PkgId) = Base.invokelatest(f, Base.require(pkgid))

withpkg(Base.PkgId(Base.UUID(0x682c06a0de6a54aba142c8b1cf79cde6), "JSON")) do JSON
    JSON.print(Dict("hello" => "world"))
end

```

This is likely a “bad” strategy, but sometimes it’s handy.

This does not require the package to be importable:

```julia
(@v1.x) pkg> rm JSON
  Updating `~/.julia/environments/v1.x/Project.toml`
  [682c06a0] - JSON v0.21.0
  Updating `~/.julia/environments/v1.x/Manifest.toml`
 [no changes]

julia> withpkg(f, pkgid::Base.PkgId) = Base.invokelatest(f, Base.require(pkgid))
withpkg (generic function with 1 method)

julia> withpkg(Base.PkgId(Base.UUID(0x682c06a0de6a54aba142c8b1cf79cde6), "JSON")) do JSON
           JSON.print(Dict("hello" => "world"))
       end
{"hello":"world"}
julia> using JSON
ERROR: ArgumentError: Package JSON not found in current path:
- Run `import Pkg; Pkg.add("JSON")` to install the JSON package.

Stacktrace:
 [1] require(::Module, ::Symbol) at ./loading.jl:892

```
