# About type declarations

**URL:** <https://discourse.julialang.org/t/about-type-declarations/38514>\
**Category:** General Usage\
**Tags:** question\
**Created:** [April 30, 2020, 10:51pm UTC](https://discourse.julialang.org/t/about-type-declarations/38514 "2020-04-30T22:51:24Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![rvignolo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rvignolo/32/33498_2.png) [@rvignolo](https://discourse.julialang.org/u/rvignolo)\
**Post date:** [April 30, 2020, 10:51pm UTC](https://discourse.julialang.org/t/about-type-declarations/38514/1 "2020-04-30T22:51:24Z")

</div>

What is the difference between the following two cases (if there is any difference at all):

```julia
struct Bar{F}
  f::F
end

struct Foo
  bar::Bar
end

```

and:

```julia
struct Bar{F}
  f::F
end

struct Foo{F}
  bar::Bar{F}
end

```

Are both cases completely the same?

Thanks!

---

<div class="post-metadata">

**Author:** ![jebej](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jebej/32/1784_2.png) [@jebej](https://discourse.julialang.org/u/jebej)\
**Post date:** [April 30, 2020, 11:05pm UTC](https://discourse.julialang.org/t/about-type-declarations/38514/2 "2020-04-30T23:05:07Z")

</div>

No, in the first case, the definition of `Foo` contains the abstract type `Bar`, since `F` is not passed as a parameter. In order for `Foo` to be concrete, the parameter of `Bar{F}` must be specified, for instance with a type variable, like in your second example.

Usually, you want `struct`s to be defined with (possibly parameterized) concrete types for performance.

---

<div class="post-metadata">

**Author:** ![rvignolo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rvignolo/32/33498_2.png) [@rvignolo](https://discourse.julialang.org/u/rvignolo)\
**Post date:** [April 30, 2020, 11:13pm UTC](https://discourse.julialang.org/t/about-type-declarations/38514/3 "2020-04-30T23:13:19Z")

</div>

Let’s assume I am using the definitions given in the first case:

```julia
julia> b1 = Bar(t -> sin(t))
Bar{var"#34#35"}(var"#34#35"())

julia> Foo(b1)
Foo(Bar{var"#34#35"}(var"#34#35"()))

```

Now, In the second case I get:

```julia
julia> b1 = Bar(t -> sin(t))
Bar{var"#34#35"}(var"#34#35"())

julia> Foo(b1)
Foo{var"#9#10"}(Bar{var"#9#10"}(var"#9#10"()))

```

For performance, the second case `Foo` instance is better because it has a concrete type Bar instead of the abstract type Bar. This is seen in the output as well, right?

Thanks!

---

<div class="post-metadata">

**Author:** ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)\
**Post date:** [May 1, 2020, 2:05am UTC](https://discourse.julialang.org/t/about-type-declarations/38514/4 "2020-05-01T02:05:05Z")

</div>

I believe if “f” is always going to be a function then you might just want to go:

```julia
struct Bar
    f::Function
end
struct Foo
   bar::Bar
end

```

---

<div class="post-metadata">

**Author:** ![rvignolo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rvignolo/32/33498_2.png) [@rvignolo](https://discourse.julialang.org/u/rvignolo)\
**Post date:** [May 1, 2020, 2:15am UTC](https://discourse.julialang.org/t/about-type-declarations/38514/5 "2020-05-01T02:15:34Z")

</div>

No, I think that is not a good advice because `Function` is an abstract type and for performance we should not have a field of this type inside the object. Instead use:

```julia
struct Bar{F<:Function}
  f::F
end

```

---

<div class="post-metadata">

**Author:** ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)\
**Post date:** [May 1, 2020, 12:41pm UTC](https://discourse.julialang.org/t/about-type-declarations/38514/6 "2020-05-01T12:41:17Z")

</div>

> [@rvignolo](#):
>
> No, I think that is not a good advice because `Function` is an abstract type and for performance we should not have a field of this type inside the object.

Are you sure about that? There is no way with the Function signature. And when I do this:

```julia
function a(v::Int)::Int
    v + 1
end

function b(b::Int)::Int
    v * 2
end

function just_one(f1::F) where F <: Function
    l = Vector{F}()
    push!(l, f1)
    return l
end
function next_one!(l::Vector{F}, f1::F) where F <: Function
    push!(l, f1)
    return l
end

l = just_one(a)
next_one!(l, b)

```

I get:

```julia
ERROR: LoadError: MethodError: no method matching next_one!(::Array{typeof(a),1}, ::typeof(b))
Closest candidates are:
  next_one!(::Array{F,1}, ::F) where F<:Function at /home/pixel27/test.jl:16

```

Even though function a and b have the **same** signature, their Type is different. When calling `just_one` and passing in function `a` Julia would compile just\_one for that parameters. Now I guess it could recompile the function if I call it passing in `b` as well. But I suspect the speed improvement for compiling the function specifically for the function parameter would be negated by having to recompile the function every time a different function is passed in.

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [May 1, 2020, 1:44pm UTC](https://discourse.julialang.org/t/about-type-declarations/38514/7 "2020-05-01T13:44:14Z")

</div>

The problem here is that you probably shouldn’t be storing functions in a vector, as that loses the type info of the function.

---

<div class="post-metadata">

**Author:** ![rvignolo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rvignolo/32/33498_2.png) [@rvignolo](https://discourse.julialang.org/u/rvignolo)\
**Post date:** [May 1, 2020, 4:10pm UTC](https://discourse.julialang.org/t/about-type-declarations/38514/8 "2020-05-01T16:10:15Z")

</div>

> [@pixel27](#):
>
> Are you sure about that?

Yes, I am.

> [@Oscar\_Smith](#):
>
> The problem here is that you probably shouldn’t be storing functions in a vector, as that loses the type info of the function.

Exactly.
