# Loading from parent scope in package

**URL:** <https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434>\
**Category:** General Usage\
**Created:** [April 2, 2024, 6:01pm UTC](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434 "2024-04-02T18:01:02Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![lancejnelson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lancejnelson/32/21898_2.png) [@lancejnelson](https://discourse.julialang.org/u/lancejnelson)\
**Post date:** [April 2, 2024, 6:01pm UTC](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434/1 "2024-04-02T18:01:03Z")

</div>

I have one package that contains all types and another packages that uses those types. Here is the types package:

```julia
module MatTypes

using LinearAlgebra
using StaticArrays

include("types.jl")

end # module MatTypes

```

and here is another package that will use those types:

```julia
module MatML

using ..MatTypes:Crystal, DataSet

using StaticArrays

include("LennardJones.jl")
#include("metrop.jl")

end # module MatML

```

Both of these modules have been turned into packages and added as dependencies.

Notice that in MatML, I’m trying to use the types from the parent scope, not directly from MatTypes. It needs to be this way because objects with these types are going be passed around to functions in various packages so they need to be the same type.

My problem: When I load the second package it doesn’t recognize MatTypes, even though it’s been loaded in the parent scope. In other words:

```julia
using MatTypes # Successful 
using MatML # Failed: UndefVarError:MatTypes not defined.

```

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [April 2, 2024, 6:07pm UTC](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434/2 "2024-04-02T18:07:35Z")

</div>

Well, MatML must have MatTypes as dependency…

If you go to the project MathML, activate it and type:

```julia
using Pkg
Pkg.add("MatTypes")

```

Does that work?

Of course you could also use a local path for Pkg.add if that is what you want…

---

<div class="post-metadata">

**Author:** ![lancejnelson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lancejnelson/32/21898_2.png) [@lancejnelson](https://discourse.julialang.org/u/lancejnelson)\
**Post date:** [April 2, 2024, 6:08pm UTC](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434/3 "2024-04-02T18:08:12Z")

</div>

It does…

```julia

Activating project at `~/MatML`

Status `~/MatML/Project.toml`
  [b127de0a] MatTypes v0.1.0 `/codes/MatTypes`

```

---

<div class="post-metadata">

**Author:** ![lancejnelson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lancejnelson/32/21898_2.png) [@lancejnelson](https://discourse.julialang.org/u/lancejnelson)\
**Post date:** [April 2, 2024, 6:11pm UTC](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434/4 "2024-04-02T18:11:52Z")

</div>

If I

```julia
using MatTypes:Crystal, DataSet

```

instead of

```julia
using ..MatTypes:Crystal, DataSet

```

It loads just fine.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [April 2, 2024, 6:13pm UTC](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434/5 "2024-04-02T18:13:01Z")

</div>

So is the issue solved?

---

<div class="post-metadata">

**Author:** ![lancejnelson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lancejnelson/32/21898_2.png) [@lancejnelson](https://discourse.julialang.org/u/lancejnelson)\
**Post date:** [April 2, 2024, 6:13pm UTC](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434/6 "2024-04-02T18:13:21Z")

</div>

No. I need to use the Crystal type defined in the parent scope.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [April 2, 2024, 6:14pm UTC](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434/7 "2024-04-02T18:14:15Z")

</div>

Why? What is that good for?

To be honest, I don’t think that this is possible with Julia.

---

<div class="post-metadata">

**Author:** ![lancejnelson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lancejnelson/32/21898_2.png) [@lancejnelson](https://discourse.julialang.org/u/lancejnelson)\
**Post date:** [April 2, 2024, 6:17pm UTC](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434/8 "2024-04-02T18:17:38Z")

</div>

I have functions in two different packages that have arguments of type `Crystal`. If I load Crystal inside the MatML module then its functions are expecting a type MatML.Crystal. But I’m using another module/package to build the variables of type Crystal and when I pass those variables in to the MatML function it doesn’t recognize it as the right type.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [April 2, 2024, 6:21pm UTC](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434/9 "2024-04-02T18:21:57Z")

</div>

Well, they also need to have a common, abstract super-type, don’t they?

I have:

- package A defining AbstractKiteModel
- package B depending on A defining a GreenKiteModel \<: AbstractKiteModel
- package C depending on A defining a RedKiteModel \<: AbstractKiteModel
- package D depending on A and B or A and C defining operations on AbstractKiteModels

Would that work for you?

---

<div class="post-metadata">

**Author:** ![lancejnelson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lancejnelson/32/21898_2.png) [@lancejnelson](https://discourse.julialang.org/u/lancejnelson)\
**Post date:** [April 2, 2024, 6:27pm UTC](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434/10 "2024-04-02T18:27:08Z")

</div>

Let me see if I can make a simplified example. Here’s one module with a function that returns a variable of type Crystal.

```julia
module VASP

using MatTypes

function buildCrystal(file::String)

## Does some stuff and returns a Crystal object.
return Crystal(...)

end

end

```

And here is another module with a function that takes an argument of type `Crystal`

```julia
module analyze

using MatTypes

function samples(crystal::Crystal)

## Does some stuff

end

end

```

Now if I try to call functions from both of these modules like this:

```julia
# Main

using VASP
using analyze

filename = "thisfile.out"
myCrystal = buildCrystal(filename)
sample(myCrystal)

```

I get an error because the variable that `buildCrystal` returned had type `VASP.Crystal` but the function named `sample` is expecting a variable with type `analyze.Crystal`

My solution is to load the Crystal type from the parent scope in both modules so they refer to the same type…  
Is that making any sense?

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [April 2, 2024, 6:28pm UTC](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434/11 "2024-04-02T18:28:33Z")

</div>

> [@lancejnelson](#):
>
> Is that making any sense?

Well, you need to define a common abstract type AbstractCrystal …

All Chrystals must have something in common, and you can only define operations on fields they have in common…

---

<div class="post-metadata">

**Author:** ![lancejnelson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lancejnelson/32/21898_2.png) [@lancejnelson](https://discourse.julialang.org/u/lancejnelson)\
**Post date:** [April 2, 2024, 6:30pm UTC](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434/12 "2024-04-02T18:30:34Z")

</div>

Hmm. I see what you’re saying, but not sure how to do it… 🙂

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [April 2, 2024, 6:34pm UTC](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434/13 "2024-04-02T18:34:27Z")

</div>

This is my definition of the type KPS4: [KiteModels.jl/src/KPS4.jl at 36be0d9ea438442d20b7976670b2828d4a468123 · aenarete/KiteModels.jl · GitHub](https://github.com/aenarete/KiteModels.jl/blob/36be0d9ea438442d20b7976670b2828d4a468123/src/KPS4.jl#L82C1-L82C66)

of the type KPS3: [KiteModels.jl/src/KPS3.jl at 36be0d9ea438442d20b7976670b2828d4a468123 · aenarete/KiteModels.jl · GitHub](https://github.com/aenarete/KiteModels.jl/blob/36be0d9ea438442d20b7976670b2828d4a468123/src/KPS3.jl#L48C1-L48C59)

and of AbstractKiteModel: [KiteModels.jl/src/KiteModels.jl at 36be0d9ea438442d20b7976670b2828d4a468123 · aenarete/KiteModels.jl · GitHub](https://github.com/aenarete/KiteModels.jl/blob/36be0d9ea438442d20b7976670b2828d4a468123/src/KiteModels.jl#L90C1-L96C36)

in case this is of any help…

---

<div class="post-metadata">

**Author:** ![lancejnelson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lancejnelson/32/21898_2.png) [@lancejnelson](https://discourse.julialang.org/u/lancejnelson)\
**Post date:** [April 2, 2024, 6:48pm UTC](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434/14 "2024-04-02T18:48:49Z")

</div>

Thank you. Would you say this is the “correct” way to solve this particular problem; can you see any advantages/disadvantages to doing this over just always loading from the parent scope?

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [April 2, 2024, 7:05pm UTC](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434/15 "2024-04-02T19:05:34Z")

</div>

Well, as far as I know “loading from parent scope” will not work with Julia packages, it will only work when you use includes.

The question is, how closely or how loose you want to have your code components coupled. For loose coupling use abstract types.

---

<div class="post-metadata">

**Author:** ![lancejnelson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lancejnelson/32/21898_2.png) [@lancejnelson](https://discourse.julialang.org/u/lancejnelson)\
**Post date:** [April 2, 2024, 7:16pm UTC](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434/16 "2024-04-02T19:16:55Z")

</div>

Not sure what you mean when you say “won’t work”. Isn’t the double dot syntax used to load from the parent scope?

```julia
using ..StaticArrays:SVector

```

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [April 2, 2024, 7:18pm UTC](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434/17 "2024-04-02T19:18:20Z")

</div>

I don’t think that is valid in a package…

---

<div class="post-metadata">

**Author:** ![lancejnelson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lancejnelson/32/21898_2.png) [@lancejnelson](https://discourse.julialang.org/u/lancejnelson)\
**Post date:** [April 2, 2024, 7:19pm UTC](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434/18 "2024-04-02T19:19:16Z")

</div>

Well I guess that explains my original problem. That only works in modules?

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [April 2, 2024, 7:19pm UTC](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434/19 "2024-04-02T19:19:50Z")

</div>

> [@lancejnelson](#):
>
> That only works in modules?

I guess so, but I am not an expert…

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [April 2, 2024, 8:17pm UTC](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434/20 "2024-04-02T20:17:27Z")

</div>

> [@ufechner7](#):
>
> Well, they also need to have a common, abstract super-type, don’t they?

If only one type is needed (`Crystal`, in this case), there shouldn’t be any need for a type hierarchy. Unless I misunderstood something?

> [@lancejnelson](#):
>
> That only works in modules?

Short answer: yes, the dots are only there for submodules to access their parent modules.

Here is a longer answer that could maybe clear things up a bit:  
With `using MatTypes` (without any dot), Julia has to perform two things:

1. Look in the package environment for a dependency named `MatType`, and load the associated code. This step is called _code loading_.
2. Look inside the `MatType` module for exported functions/types, and make them available in the current module.

If several modules/packages do `using MatTypes`, Julia makes sure _code loading_ will happen only exactly once. This means that `MatType.Crystal` should be the same type in all contexts where the `MatType` package is used (this is in contrast to a common mistake where beginners would `include` the same source file in several modules, leading to _different types_ being created in all modules).

With the dotted syntax (`using .MatTypes`), you’re telling Julia to skip the _code loading_ step. Instead, you’re saying: “no need to load any more code, simply look in my parent module, there should already be a `MatType` module there. Simply make any `export`ed name available to me”.

> [@lancejnelson](#):
>
> I get an error because the variable that `buildCrystal` returned had type `VASP.Crystal` but the function named `sample` is expecting a variable with type `analyze.Crystal`

This shouldn’t happen. If several packages do `using MatTypes: Crystal` in a correctly instantiated environment, they should all be referring to the same `MatTypes.Crystal` type.

How did you set things up in terms of dependency management? IIUC you have at least 4 projects:

- `MatTypes` (a full package)
- `VASP` (full package as well)
- `Analyze` (again full package)
- `Main`? (some project that uses both `VASP` and `Analyze`)

Which `Pkg` commands did you use to declare dependencies between them?

[Next page](https://discourse.julialang.org/t/loading-from-parent-scope-in-package/112434.md?page=2)
