# How to analyze complicated struct in julia

**URL:** <https://discourse.julialang.org/t/how-to-analyze-complicated-struct-in-julia/87985>\
**Category:** New to Julia\
**Tags:** question, package\
**Created:** [September 29, 2022, 12:29pm UTC](https://discourse.julialang.org/t/how-to-analyze-complicated-struct-in-julia/87985 "2022-09-29T12:29:01Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![xuanquansheng](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xuanquansheng/32/32400_2.png) [@xuanquansheng](https://discourse.julialang.org/u/xuanquansheng)\
**Post date:** [September 29, 2022, 12:29pm UTC](https://discourse.julialang.org/t/how-to-analyze-complicated-struct-in-julia/87985/1 "2022-09-29T12:29:01Z")

</div>

some ocdes:

```julia
julia> using StatsModels, FixedEffectModels

julia> import StatsModels: capture_call

julia> macro Atest2(ex)
           StatsModels.is_call(ex, :~)
               length(ex.args) == 3
                   StatsModels.terms!(StatsModels.sort_terms!(StatsModels.parse!(ex)))
                   end
@Atest2 (macro with 1 method)

julia> f1 = @Atest2(Sales ~ NDI + fe(State) + fe(Year))
FormulaTerm
Response:
  Sales(unknown)
Predictors:
  NDI(unknown)
  (State)->fe(State)
  (Year)->fe(Year)

julia> typeof(f1)
FormulaTerm{Term, Tuple{Term, FunctionTerm{typeof(fe), var"#3#5", (:State,)}, FunctionTerm{typeof(fe), var"#4#6", (:Year,)}}}

```

- Why the type of `f1` is some complicated? So how developers of julia to tackle with complicated struct?
- Or may be I need some references/books to teach me how to design and write a project with julia.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [September 29, 2022, 2:10pm UTC](https://discourse.julialang.org/t/how-to-analyze-complicated-struct-in-julia/87985/2 "2022-09-29T14:10:49Z")

</div>

Those types look complicated, but sometimes come out naturally when programming, because of nested struct constructs. They end up in the type fields of the outer type because this is the easiest way to avoid abstract field. For example:

This has a very simple type signature, but all fields are abstract, and will be very bad for performance:

```julia
julia> struct A
           x::Function
           y
       end

julia> struct B
           a::A
           b
       end

julia> b = B(A(sin, 1), true)
B(A(sin, 1), true)

julia> typeof(b)
B

```

Now if you use parametric types to annotate the types of each field, the signatures get complicated quite quickly:

```julia
julia> struct C{F,T}
           x::F
           y::T
       end

julia> struct D{A,B}
           a::A
           b::B
       end

julia> d = D(C(sin,1), true)
D{C{typeof(sin), Int64}, Bool}(C{typeof(sin), Int64}(sin, 1), true)

```

But now all fields are concrete, and performance of operations on these types will be better.

You do not need to parameterize every field (you can use for instance `b::Bool`, `c::Float64`, etc, but when the fields contain more complicated objects it starts to be easier just to use a parametric type than to get the correct signature for the field.

---

<div class="post-metadata">

**Author:** ![xuanquansheng](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xuanquansheng/32/32400_2.png) [@xuanquansheng](https://discourse.julialang.org/u/xuanquansheng)\
**Post date:** [September 29, 2022, 2:27pm UTC](https://discourse.julialang.org/t/how-to-analyze-complicated-struct-in-julia/87985/3 "2022-09-29T14:27:22Z")

</div>

thx, I finally understood why this complex struct comes out. So in practice how can we judge an instance with such complicated struct match which method? And developer how to organized structs in pkg?

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [September 29, 2022, 3:24pm UTC](https://discourse.julialang.org/t/how-to-analyze-complicated-struct-in-julia/87985/4 "2022-09-29T15:24:07Z")

</div>

The functions don’t need to be annotated with all parameters for dispatch. For example:

```julia
julia> using StaticArrays

julia> f(x) = 1 # generic
f (generic function with 1 method)

julia> f(x::SVector) = 2 
f (generic function with 2 methods)

julia> f(x::SVector{3}) = 3
f (generic function with 3 methods)

julia> f(x::SVector{3,T}) where T<:Float64 = 4
f (generic function with 4 methods)

julia> f([1,2,2])
1

julia> f(SVector{2,Float64}(1,2))
2

julia> f(SVector{3,Float32}(1,2,3))
3

julia> f(SVector{3,Float64}(1,2,3))
4

```

---

<div class="post-metadata">

**Author:** ![xuanquansheng](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xuanquansheng/32/32400_2.png) [@xuanquansheng](https://discourse.julialang.org/u/xuanquansheng)\
**Post date:** [September 30, 2022, 2:10am UTC](https://discourse.julialang.org/t/how-to-analyze-complicated-struct-in-julia/87985/5 "2022-09-30T02:10:34Z")

</div>

More questions:

- the type of `sin` is a Function, why it reports `typeof(sin)`?
- “The functions don’t need to be annotated with all parameters for dispatch.”. Maybe I understand what you mean, because the specific parameterized types are subtypes of the type itself, so if I want to pass `d` to a method, I don’t have to care about the type structure inside `D`, as long as that method can receive the type `D`

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [September 30, 2022, 2:12am UTC](https://discourse.julialang.org/t/how-to-analyze-complicated-struct-in-julia/87985/6 "2022-09-30T02:12:48Z")

</div>

> [@xuanquansheng](#):
>
> the type of `sin` is a Function, why it reports `typeof(sin)`?

```julia
julia> typeof(sin) === Function
false

julia> typeof(sin) <: Function
true

julia> x = rand(3);

julia> typeof(x) === AbstractArray
false

julia> typeof(x) <: AbstractArray
true

```

`Function` is abstract.

Note that this means you can dispatch on particular functions, and that a function receiving another function as an input can specialize on that particular function (note that as a heuristic, specialization will generally only occur if the function is called, or specialized is forced via making the type a parameter, e.g `foo(f::F) where {F}`.

For example

```julia
julia> foo(::typeof(sin)) = "sin"
foo (generic function with 1 method)

julia> foo(::Function) = "some other function"
foo (generic function with 2 methods)

julia> foo(cos)
"some other function"

julia> foo(sin)
"sin"

```
