# Redefining structs without restart?

**URL:** <https://discourse.julialang.org/t/redefining-structs-without-restart/50826>\
**Category:** Internals & Design\
**Created:** [November 24, 2020, 5:08pm UTC](https://discourse.julialang.org/t/redefining-structs-without-restart/50826 "2020-11-24T17:08:10Z")\
**Posts on this page:** 1\
**Showing post:** 40

<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:** [November 26, 2020, 11:46am UTC](https://discourse.julialang.org/t/redefining-structs-without-restart/50826/40 "2020-11-26T11:46:16Z")

</div>

> [@FedericoStra](#):
>
> Now that I think about it, the following macro **almost** does the trick: […]  
> The only thing which is missing is that the actual name of the structure is some garbage such as `var"##S#259"` .

I worked around the limitation of the displayed name with the new macro

```julia-auto
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
        $name = $real_name # this should be `const $name = $real_name`
        Base.show_datatype(io::Base.IO, ::Base.Type{$real_name}) = Base.print(io, $(QuoteNode(name)))
    end)
end

```

A small example:

```julia-auto
abstract type A end

foo(a::A) = (a, a.x)

@redefinable struct T <: A
    x::Int
end

@show foo(T(42))
# (T(42), 42)

@redefinable struct T <: A
    x::Float64
end

@show foo(T(3.14))
# (T(3.14), 3.14)

```

Again, this implements the semantic of Option 1: there are two independent types (secretly named `##T#***`) that know nothing about each other, and the name `T` in the current namespace switches from one to the other.

Now, there is still a problem with this macro: the third to last line should be `const $name = $real_name`, so that usage of `$name` (`T` in the example) would be inlined by the compiler.

* * *

#### Edit

In the macro, instead of the `Base.show_datatype` hack, one can assign to `$real_name.name.name`, that is, the return value of the macro becomes

```julia-auto
    esc(quote
        $struct_def
        $real_name.name.name = $(QuoteNode(name)) # fix the name
        $name = $real_name # this should be `const $name = $real_name`
    end)

```

---

_[View the full topic](https://discourse.julialang.org/t/redefining-structs-without-restart/50826)._
