# What is the difference between abstract, composite, and concrete types.

**URL:** <https://discourse.julialang.org/t/what-is-the-difference-between-abstract-composite-and-concrete-types/9599>\
**Category:** General Usage\
**Created:** [March 8, 2018, 4:16pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-abstract-composite-and-concrete-types/9599 "2018-03-08T16:16:38Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![affans](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/affans/32/11911_2.png) [@affans](https://discourse.julialang.org/u/affans)\
**Post date:** [March 8, 2018, 4:16pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-abstract-composite-and-concrete-types/9599/1 "2018-03-08T16:16:38Z")

</div>

Can someone help me understand the difference? I understand the concept from object oriented languages, but there are a few things from the documentation I don’t understand.

For example

```julia
struct Point{T}
           x::T
           y::T
       end

```

This is a composite type, but to me its also “abstract” since you can create a `Point` object of any primitive type. Soon after the documentation talks about

```julia
abstract type Pointy{T} end
struct Point{T} <: Pointy{T}
           x::T
           y::T
       end

```

I dont understand why this is neccessary. Is it performance reasons? Should I be creating an abstract type for every concrete type I want to use? What if its a `mutable struct`?

Thanks

---

<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 8, 2018, 4:24pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-abstract-composite-and-concrete-types/9599/2 "2018-03-08T16:24:27Z")

</div>

Please read the manual, and ask clarifying questions after:  
[https://docs.julialang.org/en/latest/manual/types/#Abstract-Types-1](https://docs.julialang.org/en/latest/manual/types/#Abstract-Types-1)

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [March 8, 2018, 4:44pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-abstract-composite-and-concrete-types/9599/3 "2018-03-08T16:44:51Z")

</div>

> [@Tamas\_Papp](#):
>
> Please read the manual

I think @affans was implying that he had, but was still confused about some things.

In your example above, `Point` is indeed an (implicitly defined) abstract type, while `Point{T}` are instances of it (i.e. `Point{T}` is a “subtype” of `Point`). Note here that `Point` and `Point{T}` should be thought of as distinct types.

You wouldn’t necessarily need to define `Pointy`. If `Point` provides all the functionality you need, you are done. Your example `Pointy{T}` would be like a parent class in an OO language. You would have the option of having types other than `Point` inherit from it, and dispatch functions on `Pointy` when desired (in which case those functions would work for all `T <: Pointy` types, depending on type parameters). One difference between `Pointy{T}` and `Point` is that `Pointy{T}` is explicitly defined, while the existence of `Point` is implied by the existence of `Point{T}`.

So to explicitly answer your question, no you don’t necessarily need to create an `abstract type` for every concrete type you use. It doesn’t matter whether it’s a `mutable struct` or a `struct`.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [March 8, 2018, 4:46pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-abstract-composite-and-concrete-types/9599/4 "2018-03-08T16:46:54Z")

</div>

The `Pointy{T}` example is just showing that it’s _possible_ to have an abstract type with a parameter, and that you can have a concrete parameterized type `Point{T}` that shares that parameter. There’s no inherent reason to do this (it neither helps nor hurts performance on its own), but it can be extremely useful.

For example, the abstract type that I refer to most often is probably `AbstractVector{T}` (which is, itself, just an alias for `AbstractArray{T, 1}`, i.e. a 1-dimensional array). The fact that the abstract type has a `T` parameter makes it very easy to do something like:

```julia
function foo(x::AbstractVector{Int})
  # Do something with x
end

```

and have my function `foo()` work with _any_ kind of vector of `Int`s (like a regular `Vector{Int}` or a vector from StaticArrays.jl or something else). If the abstract type didn’t have the `T` parameter, then I wouldn’t be able to express this behavior as easily.

This fits into a general philosophy in Julia that abstract types are primarily for controlling and organizing method dispatch (that is, deciding which method to call for a particular type).

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [March 8, 2018, 4:58pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-abstract-composite-and-concrete-types/9599/5 "2018-03-08T16:58:41Z")

</div>

Abstract types are for dispatching on ideas and interfaces when you don’t care about implementation. `AbstractArray`s are a great example of this. I want the user to give me some vector `v` and I want them to give me a matrix `A` so that I can compute `A*v`. I don’t need to restrict it to `Vector` and `Matrix` since these can conceivably be `SparseMatrixCSC` and some weird `OffsetArray`: my algorithm will still work if `*` is defined correctly.

So, instead of setting dispatch on `Vector` and `Matrix`, I dispatch on `AbstractVector` and `AbstractMatrix`, basically saying “give me anything that acts like a vector and that acts like a matrix, regardless of implementation”.

What are some nice things that come out of this? GPUArrays are an alternative implementation of abstract arrays, and so the algorithm I describe could do well on the GPU without modification simply by having the user pass in a GPUArray. That kind of generic programming is powerful.

---

<div class="post-metadata">

**Author:** ![affans](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/affans/32/11911_2.png) [@affans](https://discourse.julialang.org/u/affans)\
**Post date:** [March 10, 2018, 8:11pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-abstract-composite-and-concrete-types/9599/6 "2018-03-10T20:11:00Z")

</div>

@ChrisRackauckas Dont you lose performance over this?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [March 10, 2018, 9:09pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-abstract-composite-and-concrete-types/9599/7 "2018-03-10T21:09:34Z")

</div>

> [@affans](#):
>
> @ChrisRackauckas Dont you lose performance over this?

No, functions auto-specialize.

---

<div class="post-metadata">

**Author:** ![path-doc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/path-doc/32/19183_2.png) [@path-doc](https://discourse.julialang.org/u/path-doc)\
**Post date:** [March 15, 2021, 11:48pm UTC](https://discourse.julialang.org/t/what-is-the-difference-between-abstract-composite-and-concrete-types/9599/8 "2021-03-15T23:48:49Z")

</div>

That link is now out of date (dead), see the following:  
[https://docs.julialang.org/en/v1/manual/types/](https://docs.julialang.org/en/v1/manual/types/)
