# Objects whose structure can be redefined

**URL:** <https://discourse.julialang.org/t/objects-whose-structure-can-be-redefined/47733>\
**Category:** General Usage\
**Tags:** question\
**Created:** [October 4, 2020, 10:12am UTC](https://discourse.julialang.org/t/objects-whose-structure-can-be-redefined/47733 "2020-10-04T10:12:20Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![fusion809](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fusion809/32/6080_2.png) [@fusion809](https://discourse.julialang.org/u/fusion809)\
**Post date:** [October 4, 2020, 10:12am UTC](https://discourse.julialang.org/t/objects-whose-structure-can-be-redefined/47733/1 "2020-10-04T10:12:20Z")

</div>

One thing I’ve noticed about Julia that is a little frustrating is that if I define an object like this:

```julia
struct paramObj
   g::Float64
   l::Float64
end

params = paramObj(9.81, 1.0);

```

and then import a file that contains this:

```julia
struct paramObj
   sigma::Float64
   beta::Float64
   rho::Float64
end

params = paramObj(28.0, 8/3, 10.0); 

```

I’ll get an error essentially saying that paramObj is a constant and hence cannot be redefined (specifically `invalid redefinition of constant paramObj`). Is there a way of creating objects in Julia such that redefining the object structure doesn’t give you an error?

---

<div class="post-metadata">

**Author:** ![jakobnissen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobnissen/32/13477_2.png) [@jakobnissen](https://discourse.julialang.org/u/jakobnissen)\
**Post date:** [October 4, 2020, 10:46am UTC](https://discourse.julialang.org/t/objects-whose-structure-can-be-redefined/47733/2 "2020-10-04T10:46:50Z")

</div>

Yes. You need to have the two object in different namespaces, for example in different modules. For example, check [FASTX.jl](https://github.com/BioJulia/FASTX.jl/tree/master/src/), which contain two different objects called `Record` in distinct submodules. These can then be disambiguated by their module name.  
You can’t have two different objects with the same name in the same namespace. If you did, how would it be possible to distinguish between the two?

---

<div class="post-metadata">

**Author:** ![fusion809](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fusion809/32/6080_2.png) [@fusion809](https://discourse.julialang.org/u/fusion809)\
**Post date:** [October 4, 2020, 10:59am UTC](https://discourse.julialang.org/t/objects-whose-structure-can-be-redefined/47733/3 "2020-10-04T10:59:14Z")

</div>

I was hoping that it’d be like redefining a function, or a variable, where the new definition leads to the old definition no longer existing in memory. I should clarify the context here, I’m not talking about a package I’m building, I’m talking about JL files I’m loading through `include("filename.jl")`, so I’m not sure using different modules will work. Feel free to correct me if I’m wrong.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [October 4, 2020, 11:04am UTC](https://discourse.julialang.org/t/objects-whose-structure-can-be-redefined/47733/4 "2020-10-04T11:04:33Z")

</div>

The problem with redefining structs is that all existing code using that struct would have to be recompiled, as the new number of fields necessarily means a different memory layout as well. Doing this on-the-fly would mean potentially having to recompile the very code you’re running right now while it’s running, and since that’s not allowed, struct redefinition at runtime isn’t either.

If you have the need to explore how your struct should look, try prototyping usind NamedTuples combined with Revise.jl, and only settling on a struct once you know how to best organize youre code.

If you could tell us more about what you’re trying to achieve, we may be able to suggest a more julian approach. Redefining existing structs feels very much like a workflow used in e.g. python (which is interpreted and not compiled, and thus doesn’t suffer from the above problem since everything is a dynamic lookup anyway).

---

<div class="post-metadata">

**Author:** ![fusion809](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fusion809/32/6080_2.png) [@fusion809](https://discourse.julialang.org/u/fusion809)\
**Post date:** [October 4, 2020, 11:13am UTC](https://discourse.julialang.org/t/objects-whose-structure-can-be-redefined/47733/5 "2020-10-04T11:13:14Z")

</div>

> [@Sukera](#):
>
> If you could tell us more about what you’re trying to achieve, we may be able to suggest a more julian approach. Redefining existing structs feels very much like a workflow used in e.g. python (which is interpreted and not compiled, and thus doesn’t suffer from the above problem since everything is a dynamic lookup anyway).

[This other question](https://discourse.julialang.org/t/inconsistent-typing-making-adding-arrays-and-adding-a-vector-to-the-end-of-an-array-difficult/47662) of mine shows how I’m using paramObj. In essence, I’m using it to store parameter values that I hand to an ODE-solving function that then passes it to a function representing the right-hand side of the system of first-order ordinary differential equations being integrated. I know I could use an array instead, it’s just it’s more convenient using an object where you can extract the values using the dot notation, as otherwise you need to remember the order in which you entered the parameters into the array.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [October 4, 2020, 11:18am UTC](https://discourse.julialang.org/t/objects-whose-structure-can-be-redefined/47733/6 "2020-10-04T11:18:53Z")

</div>

> [@fusion809](#):
>
> it’s just it’s more convenient using an object where you can extract the values using the dot notation, as otherwise you need to remember the order in which you entered the parameters into the array.

That’s why I suggested using [NamedTuples](https://docs.julialang.org/en/v1/base/base/#Core.NamedTuple) instead:

```julia
julia> f = (a=4,b="hello!")
(a = 4, b = "hello!")

julia> f.a
4

julia> f.b
"hello!"

```

---

<div class="post-metadata">

**Author:** ![fusion809](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fusion809/32/6080_2.png) [@fusion809](https://discourse.julialang.org/u/fusion809)\
**Post date:** [October 4, 2020, 11:19am UTC](https://discourse.julialang.org/t/objects-whose-structure-can-be-redefined/47733/7 "2020-10-04T11:19:51Z")

</div>

Ah, my apologies I will admit I’m still fairly new to the language, but that sounds like a great idea, thanks!

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [October 4, 2020, 11:21am UTC](https://discourse.julialang.org/t/objects-whose-structure-can-be-redefined/47733/8 "2020-10-04T11:21:34Z")

</div>

No worries! 🙂

Once you know how exactly you want to pass around your data, you can switch the NamedTuple approach to the finalized struct version and you might even get a performance boost.

If you haven’t done so yet, I suggest giving [the manual](https://docs.julialang.org/en/v1/) a read, especially the section about [noteworthy differences from other languages](https://docs.julialang.org/en/v1/manual/noteworthy-differences/).

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [October 4, 2020, 11:30am UTC](https://discourse.julialang.org/t/objects-whose-structure-can-be-redefined/47733/9 "2020-10-04T11:30:17Z")

</div>

> [@Sukera](#):
>
> The problem with redefining structs is that all existing code using that struct would have to be recompiled, as the new number of fields necessarily means a different memory layout as well.

Some variant of it will hopefully work in the long run though, see

> <https://github.com/timholy/Revise.jl/issues/18>
>
> Since \`struct\`s cannot be redefined, attempting to do so currently gives a \`fail…ure to evaluate changes\` warning.
> 
> I wonder if this can be worked around by triggering a reload of the entire module in this case.
