# Initializing types across modules does not preserve original type

**URL:** <https://discourse.julialang.org/t/initializing-types-across-modules-does-not-preserve-original-type/7514>\
**Category:** New to Julia\
**Created:** [December 5, 2017, 12:07am UTC](https://discourse.julialang.org/t/initializing-types-across-modules-does-not-preserve-original-type/7514 "2017-12-05T00:07:25Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Faber](https://avatars.discourse-cdn.com/v4/letter/f/97f17d/32.png) [@Faber](https://discourse.julialang.org/u/Faber)\
**Post date:** [December 5, 2017, 12:07am UTC](https://discourse.julialang.org/t/initializing-types-across-modules-does-not-preserve-original-type/7514/1 "2017-12-05T00:07:25Z")

</div>

Hello all!  
Many thanks in advance for all your answers. I am a bit confused with the types defined in a module.  
I am constructing two modules A and B, each of which has two defined types, say Type A and Type B, respectively. Initialization of Type A requires type B. Here is a simple code to generate it

the file “TestModuleA.jl” (edited…)

```julia
module A
 include("TestModuleB.jl")
    type TypeA
    b::B.TypeB
        function TypeA(args...)
            obj = new(B.TypeB())
            # assuming args would contain name-value argument pair
            length(args)>0? setfield!(obj,Symbol(args[1]),args[2]):nothing
            return obj                
        end
    end
end

```

and the file “TestModuleB.jl”

```julia
module B

type TypeB
    b::Int64
    function TypeB(args...)
      new(0)
    end
end

end

```

Now, in the REPL

```julia
Main> include("TestModuleA.jl"), include("TestModuleB.jl")

```

Initialization of A goes smoothly with default field value

Trying to initialize a new Type A, with say new field of TypeB.b=9 (instead of the default 0)

```julia
Main> A.TypeA("b",B.TypeB(9))

```

I get the error

```julia
ERROR: TypeError: setfield!: expected A.B.TypeB, got B.TypeB

```

however,

```julia
Main> typeof(B.TypeB(9))
B.TypeB

```

as expected.

Why is the type of TypeB changed to A.B.TypeB? why is it not the expected B.TypeB?

as I wrote the lines above I discovered that

```julia
Main> A.TypeA("b",A.B.TypeB(9))

```

would do the job, however, the syntax is a bit awkward, specifically if I want to initialize a new TypeA by a Type B created by a third module, or another piece of code.

many thanks!

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [December 5, 2017, 12:27am UTC](https://discourse.julialang.org/t/initializing-types-across-modules-does-not-preserve-original-type/7514/2 "2017-12-05T00:27:52Z")

</div>

You’ve actually created two copies of module `B`, but it’s difficult to tell because they have the same name. What you’ve done is equivalent to:

```julia
module A
  module B
    struct TypeB
    end
  end
end

module B
  struct TypeB
  end
end

```

from which it should be pretty clear that there are two module `B`s, and thus an `A.B.TypeB` is a different type than a `B.TypeB`.

This is easy to fix. For example, you can just `include("TestModuleA.jl")` at the REPL, and then, if you want to avoid saying `A.B.TypeB()`, you can do:

```julia
include("TestModuleA.jl")
import A.B
B.TypeB(9)

```

to avoid creating a duplicate `module B`.

---

<div class="post-metadata">

**Author:** ![Faber](https://avatars.discourse-cdn.com/v4/letter/f/97f17d/32.png) [@Faber](https://discourse.julialang.org/u/Faber)\
**Post date:** [December 5, 2017, 11:45am UTC](https://discourse.julialang.org/t/initializing-types-across-modules-does-not-preserve-original-type/7514/3 "2017-12-05T11:45:28Z")

</div>

Thanks @rdeits !  
I see, but I’m not sure I completely follow the logic. The type of the field b in TypeA is b::B.TypeB  
when I initialize TypeA with a B.TypeB created outside of module A I get an error, which means that the field b is actually A.B.TypeB.  
Intuitively I thought it should be the same as

```julia
module A
    type TypeA
    b::Array{Float64,2}
        function TypeA(args...)
            obj = new(zeros(1,2))
            # assuming args would contain name-value argument pair
            length(args)>0? setfield!(obj,Symbol(args[1]),args[2]):nothing
            return obj                
        end
    end
end

```

in which the field b is not of type A.Array{Float64,2}, or is it? sorry if the question sounds trivial.

how can I then initialize a type in module A using other types which should be ‘unaware’ of the existence of module A? or maybe Types is not the way to go?  
I want to have a context-dependent type, I can use with other modules and change its values throughout simulations.

thanks!

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [December 5, 2017, 1:58pm UTC](https://discourse.julialang.org/t/initializing-types-across-modules-does-not-preserve-original-type/7514/4 "2017-12-05T13:58:54Z")

</div>

If you use Julia’s built-in `import/using` mechanisms, then you won’t have to worry about duplicate module definitions (because `import` and `using` are smart enough not to generate duplicate modules when you run `import B` twice). All you need to do is rename your files to match the names of their modules (so, `A.jl` and `B.jl`) and add their path to your LOAD\_PATH.

Then you can simplify your code to:

`A.jl`:

```julia
module A
  import B
  struct TypeA
    b::B.TypeB
  end
end

```

`B.jl`:

```julia
module B
  struct TypeB
  end
end

```

and use it like this:

```julia
push!(LOAD_PATH, "/path/to/your/modules")
import A # automatically searches LOAD_PATH for A.jl or A/src/A.jl
import B
A.TypeA(B.TypeB())

```

---

<div class="post-metadata">

**Author:** ![Faber](https://avatars.discourse-cdn.com/v4/letter/f/97f17d/32.png) [@Faber](https://discourse.julialang.org/u/Faber)\
**Post date:** [December 5, 2017, 2:46pm UTC](https://discourse.julialang.org/t/initializing-types-across-modules-does-not-preserve-original-type/7514/5 "2017-12-05T14:46:35Z")

</div>

Brilliant, thanks @rdeits!
