# Advice for dealing with \`struct\` during development

**URL:** <https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732>\
**Category:** New to Julia\
**Created:** [March 11, 2019, 11:16am UTC](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732 "2019-03-11T11:16:38Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [March 11, 2019, 11:16am UTC](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732/1 "2019-03-11T11:16:38Z")

</div>

I find it quite annoying that I can’t replace a `struct` that I made. I read somewhere that I should put them in a module because a module can be replaced.

E.g.

```julia
module Distances
    struct KM{T <: Real}
        value::T
    end
end

```

Now if I run the below twice I get an error

```julia
import Main.Distances: KM

```

the error is

> WARNING: ignoring conflicting import of Distances.KM into Main

Is there a way to allow me to import `KM` even after I’ve redefined it? I need this to iterate as I am in the design phase of many of my `struct`s and I do tend to change their design quite regularly.

---

<div class="post-metadata">

**Author:** ![anon67531922](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@anon67531922](https://discourse.julialang.org/u/anon67531922)\
**Post date:** [March 11, 2019, 11:29am UTC](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732/2 "2019-03-11T11:29:56Z")

</div>

Have you seen Revise.jl? 🙂

Edit: Revise.jl cannot handle changes to types like you’re asking about, but types tend to be more stable than methods, so still good to know about Revise.jl 🙂

---

<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:** [March 11, 2019, 11:36am UTC](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732/3 "2019-03-11T11:36:29Z")

</div>

> [@xiaodai](#):
>
> I need this to iterate as I am in the design phase of many of my `struct` s and I do tend to change their design quite regularly.

Unfortunately, this is an outstanding issue. See

> <https://github.com/JuliaLang/julia/pull/22721>
>
> Several of us have found \[Revise.jl\](https://github.com/timholy/Revise.jl) to be… a significant productivity booster. In principle, it's now possible to keep a Julia session open for a week or more, at which point one of the main negatives of Julia---the cost of JITting your, e.g., plotting package---becomes a non-issue.
> 
> However, there are two events which prevent this from being commonplace. One is method-deletion (#20048) and the other is type redefinition (https://github.com/timholy/Revise.jl/issues/18). It occurred to me that type redefinition may not be quite as nasty a problem as I've thought. A demo with this PR:
> \`\`\`julia
> julia\> struct Mine
> arg
> end
> 
> julia\> a = Mine(1)
> Mine(1)
> 
> julia\> foo(val::Mine) = val.arg
> foo (generic function with 1 method)
> 
> julia\> Base.shunt\_binding(Main, :Mine)
> Mine#1
> 
> julia\> a
> Mine#1(1)
> 
> julia\> foo(a)
> 1
> 
> julia\> struct Mine{T}
> arg::T
> end
> 
> julia\> x = Mine(3)
> Mine{Int64}(3)
> \`\`\`
> 
> The only catch I'm aware of is:
> \`\`\`julia
> julia\> foo(x)
> ERROR: MethodError: no method matching foo(::Mine{Int64})
> Closest candidates are:
> foo(::Mine#1) at REPL\[3\]:1
> \`\`\`
> 
> However, I wonder if this might be solvable via \`methodswith\` \*plus\* maintaining a cache of the source-code expressions so that they can be re-evaluated. (Revise would like that anyway, since it re-parses and caches every source file so that it can detect diffs. This adds considerably to the package load time, but caching the Exprs to the \`.ji\` file seems both cheap and effective.)

Some people recommend that you keep renaming said types, eg `KM1`, `KM2`, etc, and finalize when done. Personally, just restarting the process is less of a hassle for me.

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [March 11, 2019, 11:38am UTC](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732/4 "2019-03-11T11:38:14Z")

</div>

I think this should work (I haven’t used it yet): use Revise.jl, prototype with NamedTuples, once +/- set turn them into a struct. You can use a constructor for the NamedTuple as provided by Parameters.jl: `MyType = @with_kw (a=1, b, c=3)`, then later replace it with `@with_kw struct MyType ...`.

Edit: doing dispatch on the NamedTuples will be not easy/possible though.

---

<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:** [March 11, 2019, 6:06pm UTC](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732/5 "2019-03-11T18:06:31Z")

</div>

> [@Tamas\_Papp](#):
>
> Some people recommend that you keep renaming said types, eg `KM1` , `KM2` , etc, and finalize when done.

That is what I do. I have configured my editor (emacs in my case, but this could probably be done in any serious editor / IDE) so that it performs this kind of search/replace for me. As long as you keep your type definition in one file, it is really easy to work in this way.

You can also define constructor functions with a non-numbered name so that client code can create instances of the correct type without having to know about the current iteration number.

Maybe an example is worth a thousand words:

```julia
module Bar

# Export a non-numbered name
export Foo

# Forward exported non-numbered functions / constructors to numbered ones
#
# Such definitions will disappear when the structure is stabilized and
# renamed "Foo".
Foo() = Foo_1()

# Bump this number when modifying the struct
struct Foo_1
    f::Int
end

# Update all uses in the relevant scope (file/module)
# this should be as simple as a find/replace
Foo_1() = Foo_1(0)

end

```

```julia
# External use:
# client code doesn't need to be adapted to the internal numbering in the
# module
julia> Bar.Foo()
# but you *see* that the structure has changed (useful to avoid
# hard-to-debug errors when different types have the same name)
Main.Bar.Foo_1(0)

```

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [March 11, 2019, 7:50pm UTC](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732/6 "2019-03-11T19:50:03Z")

</div>

Along the same lines, it occurred to me that with named tuples and `getproperty`, one could have

```julia
@flexible struct Foo
    x::Int
    y::Float64
end

```

expand into

```julia
struct Foo{NT}
    _vals::NamedTuple
end
Foo(x, y) = Foo((x=x, y=y))
getproperty(f::Foo) = ...

```

Then with Revise.jl one could change the fields of `Foo` as much as you want without restarting and strip off the `@flexible` once it’s “frozen”. It would have a few restrictions, but at least it would work in functions

```julia
f(::Foo, ...) = ...

```

---

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [March 11, 2019, 9:17pm UTC](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732/7 "2019-03-11T21:17:08Z")

</div>

> [@mauro3](#):
>
> Edit: doing dispatch on the NamedTuples will be not easy/possible though.

I would not say so:

```julia
julia> TupleStruct = NamedTuple{(:a, :b), Tuple{Float64,Float64}}
NamedTuple{(:a, :b),Tuple{Float64,Float64}}

julia> subtract(x::TupleStruct) = x.a - x.b
subtract (generic function with 1 method)

julia> ts = (a=10.5, b=3.2)
(a = 10.5, b = 3.2)

julia> subtract(ts)
7.3

```

---

<div class="post-metadata">

**Author:** ![jonathanBieler](https://avatars.discourse-cdn.com/v4/letter/j/82dd89/32.png) [@jonathanBieler](https://discourse.julialang.org/u/jonathanBieler)\
**Post date:** [March 11, 2019, 10:06pm UTC](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732/8 "2019-03-11T22:06:48Z")

</div>

> [@xiaodai](#):
>
> his to iterate as I am in the design phase of many of my `struct` s and I do tend to change their design quite regula

That’s what I do usually:

1. Don’t import, just use `Distances.KM` in your test code (maybe with `const D = Distances`).

2. Or, search and replace `KM -> KM1`, `KM1 -> KM2`, etc.

---

<div class="post-metadata">

**Author:** ![Ralph\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ralph_smith/32/10344_2.png) [@Ralph\_Smith](https://discourse.julialang.org/u/Ralph_Smith)\
**Post date:** [March 12, 2019, 2:47am UTC](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732/9 "2019-03-12T02:47:22Z")

</div>

> [@xiaodai](#):
>
> I read somewhere that I should put them in a module because a module can be replaced.

If you put your test code into another module (rather than `Main`), it will bind to the current version of the module you are working on every time you load it. So suppose `DT.jl` contains

```julia
module DistanceTests
using ..Distances # or Main.Distances, if always run there
function mytest(x)
  km = Distances.KM(x)
  useful_test(km)
end
end # module

```

then after you revise and reload `Distances`, just `include("DT.jl")` again and invoke the test functions.

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [March 12, 2019, 3:35am UTC](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732/10 "2019-03-12T03:35:58Z")

</div>

> [@cstjean](#):
>
> Then with Revise.jl one could change the fields of `Foo` as much as you want without restarting and strip off the `@flexible` once it’s “frozen”.

My usual approach while prototyping is to put the new types in a temporary module inside a temporary file and just `include` that file multiple times while I sketch out the design. Once the sketch is done, the structures get copied into the package I’m working on. This is kind of ok, but awkward if the new structures need to interact with the rest of the package in a meaningful way.

Having said that, I like this idea of `@flexible struct` a lot more. It’s very simple, yet captures a lot of the behaviors you would want from this kind of thing.

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [March 12, 2019, 4:45am UTC](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732/11 "2019-03-12T04:45:08Z")

</div>

> [@Ralph\_Smith](#):
>
> using …Distances

What does the `..` mean?

---

<div class="post-metadata">

**Author:** ![Ralph\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ralph_smith/32/10344_2.png) [@Ralph\_Smith](https://discourse.julialang.org/u/Ralph_Smith)\
**Post date:** [March 12, 2019, 4:58am UTC](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732/12 "2019-03-12T04:58:41Z")

</div>

From the “Modules” section in the manual:

`using ..Utils` would look for `Utils` in `Parent` 's enclosing module rather than in `Parent` itself.

(implied context:

```julia
module Parent
using ..Utils
# something using bindings defined in Utils
end

```

)

---

<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:** [March 12, 2019, 7:13am UTC](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732/13 "2019-03-12T07:13:48Z")

</div>

> [@heliosdrm](#):
>
> > Edit: doing dispatch on the NamedTuples will be not easy/possible though.
> 
> I would not say so:

The problem is not that you cannot alias a `NamedTuple` type and dispatch on it, but that you

1. cannot distinguish this from another such type with the same layout,
2. parametric types become tricky.

(Cf [nominative](https://en.wikipedia.org/wiki/Nominal_type_system) vs [structural](https://en.wikipedia.org/wiki/Structural_type_system) type systems, Julia `struct`s are nominative but the above solution is closer to structural).

---

<div class="post-metadata">

**Author:** ![BeastyBlacksmith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/beastyblacksmith/32/4741_2.png) [@BeastyBlacksmith](https://discourse.julialang.org/u/BeastyBlacksmith)\
**Post date:** [June 14, 2019, 3:16pm UTC](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732/14 "2019-06-14T15:16:30Z")

</div>

I recently needed this and here it is [https://github.com/BeastyBlacksmith/ProtoStructs.jl](https://github.com/BeastyBlacksmith/ProtoStructs.jl)

---

<div class="post-metadata">

**Author:** ![hhaensel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hhaensel/32/1207_2.png) [@hhaensel](https://discourse.julialang.org/u/hhaensel)\
**Post date:** [March 12, 2021, 4:03pm UTC](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732/15 "2021-03-12T16:03:27Z")

</div>

I know this is an old thread, but I think the question not out-dated. I just stumbled across a [blog](https://discourse.julialang.org/t/redefining-structs-without-restart/50826/40) with the following proposal

EDIT: I adapted the macro `@kwredef` to also include cases with typed structs.

```julia
macro redefinable(struct_def)
    struct_def isa Expr && struct_def.head == :struct || error("struct definition expected")
    if struct_def.args[2] isa Symbol
        name = struct_def.args[2]
        real_name = struct_def.args[2] = gensym(name)
    elseif struct_def.args[2].head == :<:
        name = struct_def.args[2].args[1]
        real_name = struct_def.args[2].args[1] = gensym(name)
    end
    esc(quote
        $struct_def
        $real_name.name.name = $(QuoteNode(name)) # fix the name
        $name = $real_name # this should be `const $name = $real_name`
    end)
end

```

This approach is somewhat similar to one of the approaches above in that it creates a true `struct`. The advantage is that the name is identical to the struct that you would normally define.  
The only disadvantage could be that it creates a lot of structs and doesn’t check whether the new structure is identical to the old one. But for development purposes this shouldn’t be a problem. Also, the variable which holds the struct type could be overwritten.

I was about doing a similar thing for `Base.@kwdef` and borrowed some of this ideas:

```julia
macro kwredef(expr)
  expr = macroexpand( __module__ , expr) # to expand @static
  expr isa Expr && expr.head === :struct || error("Invalid usage of @kwredef")
  expr = expr::Expr

  t = expr.args; n = 2
  if t[n] isa Expr && t[n].head === :<:
      t = t[n].args
      n = 1
  end
  curly = t[n] isa Expr && t[n].head === :curly
  if curly
      t = t[n].args
      n=1
  end

  T_old = t[n]
  t[n] = T_new = gensym(T_old)

  esc(quote
    Base.@kwdef $expr
    $T_old = $T_new
    $curly ? $T_new.body.name.name = $(QuoteNode(T_old)) : $T_new.name.name = $(QuoteNode(T_old)) # fix the name
  end)
end

```

---

<div class="post-metadata">

**Author:** ![BeastyBlacksmith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/beastyblacksmith/32/4741_2.png) [@BeastyBlacksmith](https://discourse.julialang.org/u/BeastyBlacksmith)\
**Post date:** [March 13, 2021, 7:30pm UTC](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732/16 "2021-03-13T19:30:14Z")

</div>

Brave souls could check out the branch of the upcoming Protostructs version: [https://github.com/BeastyBlacksmith/ProtoStructs.jl/pull/4](https://github.com/BeastyBlacksmith/ProtoStructs.jl/pull/4)

Ideally all you’d need to do then is put `@proto` in front of the struct definition, and remove it once development is done.

Any feedback appreciated.

---

<div class="post-metadata">

**Author:** ![hhaensel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hhaensel/32/1207_2.png) [@hhaensel](https://discourse.julialang.org/u/hhaensel)\
**Post date:** [March 23, 2021, 9:49am UTC](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732/17 "2021-03-23T09:49:33Z")

</div>

What do you think about also supporting `Proto.@kwdef`?  
Youmight either use my above code example, which I adapted to also support typed structs, or you go back to the original definition of Base.@kwdef and insert your @proto macro in the the upper part.

---

<div class="post-metadata">

**Author:** ![BeastyBlacksmith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/beastyblacksmith/32/4741_2.png) [@BeastyBlacksmith](https://discourse.julialang.org/u/BeastyBlacksmith)\
**Post date:** [March 23, 2021, 7:56pm UTC](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732/18 "2021-03-23T19:56:21Z")

</div>

Thats definitely a worthwile extension and might be added before the release

---

<div class="post-metadata">

**Author:** ![FedericoStra](https://avatars.discourse-cdn.com/v4/letter/f/76d3ee/32.png) [@FedericoStra](https://discourse.julialang.org/u/FedericoStra)\
**Post date:** [April 9, 2021, 3:09pm UTC](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732/19 "2021-04-09T15:09:29Z")

</div>

Very recently I’ve put that blog post into a package and uploaded it to the registry. You can check it out here (and contribute new ideas!):

- [https://github.com/FedericoStra/RedefStructs.jl](https://github.com/FedericoStra/RedefStructs.jl)

_Edit_: I [added](https://github.com/FedericoStra/RedefStructs.jl/commit/3ad998fcc934309bd9991ce9a45c91121f730531) `@kwredef` to the latest [`RedefStructs.jl`](https://github.com/FedericoStra/RedefStructs.jl).

---

<div class="post-metadata">

**Author:** ![BeastyBlacksmith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/beastyblacksmith/32/4741_2.png) [@BeastyBlacksmith](https://discourse.julialang.org/u/BeastyBlacksmith)\
**Post date:** [April 9, 2021, 8:11pm UTC](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732/20 "2021-04-09T20:11:18Z")

</div>

Okay, I merged that PR and triggered the registration of the new version, where keyword definitions should also work

[Next page](https://discourse.julialang.org/t/advice-for-dealing-with-struct-during-development/21732.md?page=2)
