# Make an existing type a child of an abstract type

**URL:** <https://discourse.julialang.org/t/make-an-existing-type-a-child-of-an-abstract-type/28162>\
**Category:** General Usage\
**Tags:** traits\
**Created:** [August 29, 2019, 11:41am UTC](https://discourse.julialang.org/t/make-an-existing-type-a-child-of-an-abstract-type/28162 "2019-08-29T11:41:45Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![zsoerenm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zsoerenm/32/664_2.png) [@zsoerenm](https://discourse.julialang.org/u/zsoerenm)\
**Post date:** [August 29, 2019, 11:41am UTC](https://discourse.julialang.org/t/make-an-existing-type-a-child-of-an-abstract-type/28162/1 "2019-08-29T11:41:45Z")

</div>

Is it possible to make an existing type a child of an abstract type?  
Something like this?

```julia
using StaticArrays
abstract type Abstract3DVector end
struct type SVector{3} <: Abstract3DVector end

```

Unfortunately it does not work:

```julia
julia> SVector{3} <: Abstract3DVector
false

```

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [August 29, 2019, 12:11pm UTC](https://discourse.julialang.org/t/make-an-existing-type-a-child-of-an-abstract-type/28162/2 "2019-08-29T12:11:00Z")

</div>

No. But you can wrap it and type the wrapper.

Heres a toy example, `AbstractVector3D` should actualy be `<: AbstractArray{T,N}`:

```julia
abstract type Vector3D <: AbstracVector3D
    data::SVector{3}
end

Base.parent(a::Vector3D) = a.data

```

Then you can write out all the SVector methods you need manually like:

```julia
getindex(a::Vector3D, I...) = getindex(parent(a), I...)

```

Or use the `@forward` macro in Lazy.jl to do them all at once. I can’t recall exactly what you need here.

But first you should have a good reason why you need such specialized types.

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [August 29, 2019, 12:17pm UTC](https://discourse.julialang.org/t/make-an-existing-type-a-child-of-an-abstract-type/28162/3 "2019-08-29T12:17:26Z")

</div>

Maybe related (and also unsolved): [https://github.com/JuliaArrays/StaticArrays.jl/issues/592](https://github.com/JuliaArrays/StaticArrays.jl/issues/592)

---

<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:** [August 29, 2019, 2:26pm UTC](https://discourse.julialang.org/t/make-an-existing-type-a-child-of-an-abstract-type/28162/4 "2019-08-29T14:26:25Z")

</div>

This seems like a situation where a trait might be more appropriate than an abstract type. Traits, unlike abstract types, are easy to add to any type, even after that type has been defined. For example:

```julia
julia> struct ExistingType
         x::Int
       end

julia> is_cool(::Type{T}) where {T} = false
is_cool (generic function with 1 method)

julia> is_cool(::Type{ExistingType}) = true
is_cool (generic function with 2 methods)

julia> function check_coolness(x::T) where {T}
         if is_cool(T)
           println("Cool!")
         else
           println("nope")
         end
       end
check_coolness (generic function with 1 method)

julia> check_coolness(ExistingType(1))
Cool!

```

In this case, the `is_cool` is just a function that returns a boolean, and we can use that inside an `if` statement to check properties of the type. Note that Julia is pretty clever about propagating types and constants, so the actual `if` statement is optimized away in the resulting code:

```julia
julia> @code_warntype check_coolness(ExistingType(1))
Body::Nothing
1 ─ %1 = invoke Main.println("Cool!"::String)::Core.Compiler.Const(nothing, false)
└── return %1 

```

If you want your trait to help control method dispatch, then you can use “Holy-traits” and define new types to represent the trait of interest:

```julia
julia> struct IsCool end
                                                                                                                                                                                                                                                                                                                                      
julia> struct NotCool end

julia> coolness(::Type{T}) where {T} = NotCool()
coolness (generic function with 1 method)

julia> coolness(::Type{ExistingType}) = IsCool()
coolness (generic function with 2 methods)

julia> check_coolness_trait(x::T) where {T} = check_coolness_trait(coolness(T), x)
check_coolness_trait (generic function with 1 method)

julia> check_coolness_trait(::IsCool, x) = println("$x is cool")
check_coolness_trait (generic function with 2 methods)

julia> check_coolness_trait(::NotCool, x) = println("$x is not cool")
check_coolness_trait (generic function with 3 methods)

```

And we can use it like so:

```julia
julia> check_coolness_trait(1)
1 is not cool

julia> check_coolness_trait(ExistingType(1))
ExistingType(1) is cool

```
