# Help with circular type/inner constructor

**URL:** https://discourse.julialang.org/t/help-with-circular-type-inner-constructor/16020
**Category:** General Usage
**Created:** [October 8, 2018, 2:18pm UTC](https://discourse.julialang.org/t/help-with-circular-type-inner-constructor/16020 "2018-10-08T14:18:43Z")
**Posts on this page:** 16
**Page:** 1

<div class="post-metadata">

### Author: ![randyzwitch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/randyzwitch/32/15955_2.png) [@randyzwitch](https://discourse.julialang.org/u/randyzwitch)
#### Post date: [October 8, 2018, 2:18pm UTC](https://discourse.julialang.org/t/help-with-circular-type-inner-constructor/16020/1 "2018-10-08T14:18:43Z")

</div>

(continued from Slack)

As part of creating types that are originally created in a C++ project, I get the following:

```julia
mutable struct TDatumVal <: Thrift.TMsg
  int_val::Int64
  real_val::Float64
  str_val::String
  arr_val::Vector{TDatum}
  TDatumVal() = (o=new(); fillunset(o); o)
end # mutable struct TDatumVal

mutable struct TDatum <: Thrift.TMsg
  val::TDatumVal
  is_null::Bool
  TDatum() = (o=new(); fillunset(o); o)
end # mutable struct TDatum

```

The above code is auto-generated from Thrift.jl ([issue](https://github.com/tanmaykm/Thrift.jl/issues/37)). I tried to just make `arr_val` in `TDatumVal` an `AbstractVector`, but this doesn’t work.

Can someone tell me how I can remedy this? I’ve looked at the inner constructor section of the manual, but I’m still not really clear about how I can fix this (and especially, since the type code was generated in the first place)

---

<div class="post-metadata">

### Author: ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)
#### Post date: [October 8, 2018, 2:21pm UTC](https://discourse.julialang.org/t/help-with-circular-type-inner-constructor/16020/2 "2018-10-08T14:21:32Z")

</div>

[https://github.com/JuliaLang/julia/issues/269](https://github.com/JuliaLang/julia/issues/269)

Workaround:

[https://github.com/JuliaLang/julia/issues/269#issuecomment-68421745](https://github.com/JuliaLang/julia/issues/269#issuecomment-68421745)

---

<div class="post-metadata">

### Author: ![randyzwitch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/randyzwitch/32/15955_2.png) [@randyzwitch](https://discourse.julialang.org/u/randyzwitch)
#### Post date: [October 8, 2018, 2:29pm UTC](https://discourse.julialang.org/t/help-with-circular-type-inner-constructor/16020/3 "2018-10-08T14:29:36Z")

</div>

```julia
mutable struct TDatumVal{T} <: Thrift.TMsg
  int_val::Int64
  real_val::Float64
  str_val::String
  arr_val::Vector{T}
  TDatumVal() = (o=new(); fillunset(o); o)
end # mutable struct TDatumVal

mutable struct TDatum{T} <: Thrift.TMsg
  val::T
  is_null::Bool
  TDatum() = (o=new(); fillunset(o); o)
end # mutable struct TDatum

julia> using OmniSci
[Info: Precompiling OmniSci [f1ee3d5f-0699-5209-8f21-83915c40971f]
ERROR: LoadError: LoadError: syntax: too few type parameters specified in "new{...}"
Stacktrace:
 [1] include at ./boot.jl:317 [inlined]
 [2] include_relative(::Module, ::String) at ./loading.jl:1041
 [3] include at ./sysimg.jl:29 [inlined]
 [4] include(::String) at /home/randyzwitch/.julia/dev/OmniSci/src/OmniSci.jl:1
 [5] top-level scope at none:0
 [6] include at ./boot.jl:317 [inlined]
 [7] include_relative(::Module, ::String) at ./loading.jl:1041
 [8] include(::Module, ::String) at ./sysimg.jl:29
 [9] top-level scope at none:2
 [10] eval at ./boot.jl:319 [inlined]
 [11] eval(::Expr) at ./client.jl:389
 [12] top-level scope at ./none:3
in expression starting at /home/randyzwitch/.julia/dev/OmniSci/src/mapd_types.jl:4
in expression starting at /home/randyzwitch/.julia/dev/OmniSci/src/OmniSci.jl:48
ERROR: Failed to precompile OmniSci [f1ee3d5f-0699-5209-8f21-83915c40971f] to /home/randyzwitch/.julia/compiled/v1.0/OmniSci/AxjCm.ji.
Stacktrace:
 [1] macro expansion at ./logging.jl:313 [inlined]
 [2] compilecache(::Base.PkgId, ::String) at ./loading.jl:1187
 [3] macro expansion at ./logging.jl:311 [inlined]
 [4] _require(::Base.PkgId) at ./loading.jl:944
 [5] require(::Base.PkgId) at ./loading.jl:855
 [6] macro expansion at ./logging.jl:311 [inlined]
 [7] require(::Module, ::Symbol) at ./loading.jl:837

```

---

<div class="post-metadata">

### Author: ![ssfrr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ssfrr/32/3736_2.png) [@ssfrr](https://discourse.julialang.org/u/ssfrr)
#### Post date: [October 8, 2018, 2:39pm UTC](https://discourse.julialang.org/t/help-with-circular-type-inner-constructor/16020/4 "2018-10-08T14:39:44Z")

</div>

You only need the type parameter in the first type, which can’t “see” the 2nd type.

Here’s a simpler example with a circular reference:

```julia
mutable struct Foo{T}
    x::Union{Nothing, T}
end

mutable struct Bar
    x::Foo{Bar}
end

f = Foo{Bar}(nothing)
f.x = Bar(f)

```

---

<div class="post-metadata">

### Author: ![randyzwitch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/randyzwitch/32/15955_2.png) [@randyzwitch](https://discourse.julialang.org/u/randyzwitch)
#### Post date: [October 8, 2018, 2:42pm UTC](https://discourse.julialang.org/t/help-with-circular-type-inner-constructor/16020/5 "2018-10-08T14:42:34Z")

</div>

Still the same issue

```julia
mutable struct TDatumVal{T} <: Thrift.TMsg
  int_val::Int64
  real_val::Float64
  str_val::String
  arr_val::Vector{T}
  TDatumVal() = (o=new(); fillunset(o); o)
end # mutable struct TDatumVal

mutable struct TDatum <: Thrift.TMsg
  val::TDatumVal
  is_null::Bool
  TDatum() = (o=new(); fillunset(o); o)
end # mutable struct TDatum

julia> using OmniSci
[Info: Recompiling stale cache file /home/randyzwitch/.julia/compiled/v1.0/OmniSci/AxjCm.ji for OmniSci [f1ee3d5f-0699-5209-8f21-83915c40971f]
ERROR: LoadError: LoadError: syntax: too few type parameters specified in "new{...}"
Stacktrace:
 [1] include at ./boot.jl:317 [inlined]
 [2] include_relative(::Module, ::String) at ./loading.jl:1041
 [3] include at ./sysimg.jl:29 [inlined]
 [4] include(::String) at /home/randyzwitch/.julia/dev/OmniSci/src/OmniSci.jl:1
 [5] top-level scope at none:0
 [6] include at ./boot.jl:317 [inlined]
 [7] include_relative(::Module, ::String) at ./loading.jl:1041
 [8] include(::Module, ::String) at ./sysimg.jl:29
 [9] top-level scope at none:2
 [10] eval at ./boot.jl:319 [inlined]
 [11] eval(::Expr) at ./client.jl:389
 [12] top-level scope at ./none:3
in expression starting at /home/randyzwitch/.julia/dev/OmniSci/src/mapd_types.jl:4
in expression starting at /home/randyzwitch/.julia/dev/OmniSci/src/OmniSci.jl:48

```

---

<div class="post-metadata">

### Author: ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)
#### Post date: [October 8, 2018, 2:44pm UTC](https://discourse.julialang.org/t/help-with-circular-type-inner-constructor/16020/6 "2018-10-08T14:44:08Z")

</div>

That seems to work, not sure of performance.

```julia
julia> mutable struct Type1{T}
           a::T
           Type1{T}() where {T} = new{T}()
       end

julia> mutable struct Type2{T}
           a::T
           Type2{T}() where {T} = new{T}()
       end

julia> t = Type1{Type2}()
Type1{Type2}(#undef)

julia> t.a = Type2{Type1}()
Type2{Type1}(#undef)

julia> t.a.a = t
Type1{Type2}(Type2{Type1}(Type1{Type2}(#= circular reference @-2 =#)))

```

---

<div class="post-metadata">

### Author: ![randyzwitch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/randyzwitch/32/15955_2.png) [@randyzwitch](https://discourse.julialang.org/u/randyzwitch)
#### Post date: [October 8, 2018, 2:52pm UTC](https://discourse.julialang.org/t/help-with-circular-type-inner-constructor/16020/7 "2018-10-08T14:52:22Z")

</div>

Thanks. While this allows for the package to precompile, it still causes the error “UnionAll has no field types”.

```julia
mutable struct TDatumVal{T} <: Thrift.TMsg
  int_val::Int64
  real_val::Float64
  str_val::String
  arr_val::Vector{T}
  TDatumVal{T}() where T = (o=new(); fillunset(o); o)
end # mutable struct TDatumVal

mutable struct TDatum{T} <: Thrift.TMsg
  val::T
  is_null::Bool
  TDatum{T}() where T = (o=new(); fillunset(o); o)
end # mutable struct TDatum

julia> se = sql_execute(conn, "select count(*) as records from mapd_counties", false, 100, 100)
ERROR: type UnionAll has no field types
Stacktrace:
 [1] getproperty at ./sysimg.jl:15 [inlined]
 [2] meta(::Type, ::Array{Symbol,1}, ::Array{Int64,1}, ::Dict{Symbol,Any}, ::Bool) at /home/randyzwitch/.julia/packages/Thrift/BxShm/src/base.jl:510
 [3] meta(::Type, ::Array{Symbol,1}, ::Array{Int64,1}, ::Dict{Symbol,Any}) at /home/randyzwitch/.julia/packages/Thrift/BxShm/src/base.jl:503
 [4] meta(::Type) at /home/randyzwitch/.julia/packages/Thrift/BxShm/src/base.jl:494
 [5] meta(::Type, ::Array{Symbol,1}, ::Array{Int64,1}, ::Dict{Symbol,Any}, ::Bool) at /home/randyzwitch/.julia/packages/Thrift/BxShm/src/base.jl:522
 [6] meta(::Type, ::Array{Symbol,1}, ::Array{Int64,1}, ::Dict{Symbol,Any}) at /home/randyzwitch/.julia/packages/Thrift/BxShm/src/base.jl:503
 [7] meta(::Type) at /home/randyzwitch/.julia/packages/Thrift/BxShm/src/base.jl:494
 [8] meta(::Type, ::Array{Symbol,1}, ::Array{Int64,1}, ::Dict{Symbol,Any}, ::Bool) at /home/randyzwitch/.julia/packages/Thrift/BxShm/src/base.jl:522
 [9] meta(::Type, ::Array{Symbol,1}, ::Array{Int64,1}, ::Dict{Symbol,Any}) at /home/randyzwitch/.julia/packages/Thrift/BxShm/src/base.jl:503
 [10] meta(::Type) at /home/randyzwitch/.julia/packages/Thrift/BxShm/src/base.jl:494
 [11] meta(::Type, ::Array{Symbol,1}, ::Array{Int64,1}, ::Dict{Symbol,Any}, ::Bool) at /home/randyzwitch/.julia/packages/Thrift/BxShm/src/base.jl:520
 [12] meta(::Type, ::Array{Symbol,1}, ::Array{Int64,1}, ::Dict{Symbol,Any}) at /home/randyzwitch/.julia/packages/Thrift/BxShm/src/base.jl:503
 [13] meta(::Type) at /home/randyzwitch/.julia/packages/Thrift/BxShm/src/base.jl:494
 [14] meta(::Type, ::Array{Symbol,1}, ::Array{Int64,1}, ::Dict{Symbol,Any}, ::Bool) at /home/randyzwitch/.julia/packages/Thrift/BxShm/src/base.jl:520
 [15] meta at /home/randyzwitch/.julia/packages/Thrift/BxShm/src/base.jl:503 [inlined]
 [16] meta(::Type{OmniSci.sql_execute_result}) at /home/randyzwitch/.julia/dev/OmniSci/src/mapd_types.jl:828
 [17] read_container(::Thrift.TBinaryProtocol, ::OmniSci.sql_execute_result) at /home/randyzwitch/.julia/packages/Thrift/BxShm/src/base.jl:174
 [18] read(::Thrift.TBinaryProtocol, ::OmniSci.sql_execute_result) at /home/randyzwitch/.julia/packages/Thrift/BxShm/src/base.jl:169
 [19] sql_execute(::MapDClient, ::String, ::String, ::Bool, ::String, ::Int32, ::Int32) at /home/randyzwitch/.julia/dev/OmniSci/src/mapd_client.jl:531
 [20] sql_execute(::OmniSciConnection, ::String, ::Bool, ::Int64, ::Int64) at /home/randyzwitch/.julia/dev/OmniSci/src/misc.jl:93
 [21] top-level scope at none:0

```

---

<div class="post-metadata">

### Author: ![ssfrr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ssfrr/32/3736_2.png) [@ssfrr](https://discourse.julialang.org/u/ssfrr)
#### Post date: [October 8, 2018, 2:59pm UTC](https://discourse.julialang.org/t/help-with-circular-type-inner-constructor/16020/8 "2018-10-08T14:59:31Z")

</div>

Ah, sorry, your constructor for the parametric type needs to be `TDatumVal{T}() where T = ...`.

Here’s a more similar example:

```julia
mutable struct Foo{T}
    x::Union{Nothing, T}
    Foo{T}() where T = new(nothing)
end

Foo() = Foo{Bar}()

mutable struct Bar
    x::Foo{Bar}
end

f = Foo()
f.x = Bar(f)

```

I’m not sure how you’re constructing your type, but you’ll have to make sure you either explicitly create it with `TDatumVal{TDatum}()` or create a new method (like in my example above) that fills in the type parameter for you.

---

<div class="post-metadata">

### Author: ![ssfrr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ssfrr/32/3736_2.png) [@ssfrr](https://discourse.julialang.org/u/ssfrr)
#### Post date: [October 8, 2018, 3:02pm UTC](https://discourse.julialang.org/t/help-with-circular-type-inner-constructor/16020/9 "2018-10-08T15:02:54Z")

</div>

> [@randyzwitch](#):
>
> type UnionAll has no field types

Though this error might be a bug similar to [MethodInstance display errors with UnionAll has no field parameters · Issue #20332 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/20332)? (I’m not sure). Can you reproduce with a MWE?

---

<div class="post-metadata">

### Author: ![randyzwitch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/randyzwitch/32/15955_2.png) [@randyzwitch](https://discourse.julialang.org/u/randyzwitch)
#### Post date: [October 8, 2018, 3:09pm UTC](https://discourse.julialang.org/t/help-with-circular-type-inner-constructor/16020/10 "2018-10-08T15:09:14Z")

</div>

Unfortunately, creating a MWE is difficult as the package I’m trying to create is for accessing a database. And whatever Thrift.jl is trying to do after it gets the message but before creating the type is pretty difficult to understand as well.

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [October 8, 2018, 3:38pm UTC](https://discourse.julialang.org/t/help-with-circular-type-inner-constructor/16020/11 "2018-10-08T15:38:04Z")

</div>

We really need to implement something for mutually recursive types at some point soon. It’s always been a low priority since you can work around it, but it’s just one of those features you occasionally need and it’s irritating that it’s not more straightforward. Should really be done in an early 1.x version.

---

<div class="post-metadata">

### Author: ![randyzwitch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/randyzwitch/32/15955_2.png) [@randyzwitch](https://discourse.julialang.org/u/randyzwitch)
#### Post date: [October 8, 2018, 3:51pm UTC](https://discourse.julialang.org/t/help-with-circular-type-inner-constructor/16020/12 "2018-10-08T15:51:33Z")

</div>

Do you have a suggestion how to proceed @StefanKarpinski? It seems like no matter how I proceed, I run into an issue:

1. If I use AbstractVector like I have now ([link](https://github.com/omnisci/OmniSci.jl/blob/master/src/mapd_types.jl#L8)), I get a `ArgumentError: type does not have a definite number of fields`
2. If I do the Parametric type definition, I get a `UnionAll` error

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [October 8, 2018, 4:18pm UTC](https://discourse.julialang.org/t/help-with-circular-type-inner-constructor/16020/13 "2018-10-08T16:18:42Z")

</div>

I would file an issue; I’m not sure about a workaround, I’m afraid.

---

<div class="post-metadata">

### Author: ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)
#### Post date: [October 9, 2018, 12:06am UTC](https://discourse.julialang.org/t/help-with-circular-type-inner-constructor/16020/14 "2018-10-09T00:06:32Z")

</div>

A complete working example will help to see where the problem is. I don’t know why your example is failing but if mine is working, it seems like yours should. Not an expert though, so I may be wrong.

---

<div class="post-metadata">

### Author: ![randyzwitch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/randyzwitch/32/15955_2.png) [@randyzwitch](https://discourse.julialang.org/u/randyzwitch)
#### Post date: [October 9, 2018, 12:20am UTC](https://discourse.julialang.org/t/help-with-circular-type-inner-constructor/16020/15 "2018-10-09T00:20:46Z")

</div>

I’m not saying your example doesn’t work, but it also causes a problem downstream with `UnionAll`.

---

<div class="post-metadata">

### Author: ![randyzwitch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/randyzwitch/32/15955_2.png) [@randyzwitch](https://discourse.julialang.org/u/randyzwitch)
#### Post date: [October 9, 2018, 1:03pm UTC](https://discourse.julialang.org/t/help-with-circular-type-inner-constructor/16020/16 "2018-10-09T13:03:28Z")

</div>

Thanks to Tanmay, I now have an [answer](https://github.com/tanmaykm/Thrift.jl/issues/37#issuecomment-428024388). It’s Thrift.jl specific instead of fixing the circular issue, but that’s okay since that’s where the errors started.

Thanks everyone who tried to help, I really appreciate it!
