# Confused with type definition

**URL:** <https://discourse.julialang.org/t/confused-with-type-definition/53115>\
**Category:** New to Julia\
**Created:** [January 10, 2021, 2:18pm UTC](https://discourse.julialang.org/t/confused-with-type-definition/53115 "2021-01-10T14:18:27Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![alemelis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alemelis/32/208433_2.png) [@alemelis](https://discourse.julialang.org/u/alemelis)\
**Post date:** [January 10, 2021, 2:18pm UTC](https://discourse.julialang.org/t/confused-with-type-definition/53115/1 "2021-01-10T14:18:27Z")

</div>

Hello there, say I want to create a new type which is basically the same of `Array{Float64, 1}` except for the behaviour for one operator (for example `+`).

What I’m doing now is the following. First create a new mutable type `MyVec`

```julia
struct MyVec
  v::Array{Float64, 1}
end

```

and then overloading the operator I need as

```julia
Base.:+(v::MyVec, u::MyVec) = MyVec(v.v .+ u.v[end:-1:1])

```

Now the problem I’m facing is that the rest of the operators shouldn’t change their behaviour, but I’m forced to re-define all of them.

Is it possible to tell Julia that `MyVec` is basically an `Array{Float64, 1}` so that I can “inherit” all the `Array` behaviour and simply add the new one?

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [January 10, 2021, 2:39pm UTC](https://discourse.julialang.org/t/confused-with-type-definition/53115/2 "2021-01-10T14:39:34Z")

</div>

That feature does not exist in Julia itself. There are approaches that can ease the work.

```julia
import Base: length
import LinearAlgebra: dot

 struct MyVec{T} <: AbstractVector{T}
   vec::Vector{T}
 end

# required by the AbstractArray interface
Base.size(x::MyVec) = size(x.vec)
Base.getindex(x::MyVec, i::Int) = getindex(x.vec, i)
Base.setindex!(x::MyVec, v, i::Int) = setindex!(x.vec, v, i)

# your customization of +
Base.:(+)(v::MyVec, u::MyVec) = ...
Base.:(+)(v::MyVec, u::Vector{Float64}) = v + MyVec(u)
Base.:(+)(v::Vector{Float64}, u::MyVec) = MyVec(v) + u

for F in (:length,) # add other appropriate unary functions
  @eval begin
    $F(v::MyVec,) = length(v.v)
  end
end

for F in (:dot,) # add other appropriate binary functions
  @eval begin
    $F(v::MyVec, u::MyVec) = $F(v.v, u.v)
    $F(v::MyVec, u::Vector{Float64}) = $F(v.v, u)
    $F(v::Vector{Float64}, u::MyVec) = $F(v, u.v)
  end
end
``
```

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [January 10, 2021, 2:46pm UTC](https://discourse.julialang.org/t/confused-with-type-definition/53115/3 "2021-01-10T14:46:55Z")

</div>

Why not just define a function

```julia
add(x::Vector{T}, y::Vector{T}) where {T} =
   dot(x,y) + dot(y, reverse(x))

```

or whatever you want it to do –  
rather than needing all the special type support

---

<div class="post-metadata">

**Author:** ![alemelis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alemelis/32/208433_2.png) [@alemelis](https://discourse.julialang.org/u/alemelis)\
**Post date:** [January 10, 2021, 2:52pm UTC](https://discourse.julialang.org/t/confused-with-type-definition/53115/4 "2021-01-10T14:52:23Z")

</div>

I see, thanks @JeffreySarnoff for the `@eval` example.

Creating a new type seems a way to keep the code cleaner (I also don’t want to change `show` behaviour for `Array`) but I’ll probably stick to `Array` and create only the new functions

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [January 10, 2021, 2:57pm UTC](https://discourse.julialang.org/t/confused-with-type-definition/53115/5 "2021-01-10T14:57:52Z")

</div>

Consider also doing `MyVec <: AbstractVector{Float64}`

---

<div class="post-metadata">

**Author:** ![alemelis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alemelis/32/208433_2.png) [@alemelis](https://discourse.julialang.org/u/alemelis)\
**Post date:** [January 10, 2021, 3:05pm UTC](https://discourse.julialang.org/t/confused-with-type-definition/53115/6 "2021-01-10T15:05:49Z")

</div>

would that be in the struct definition, like

```julia
struct MyVec <: AbstractVector{Float64}
  v::Vector{Float64}
end

```

?

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [January 10, 2021, 3:10pm UTC](https://discourse.julialang.org/t/confused-with-type-definition/53115/7 "2021-01-10T15:10:45Z")

</div>

Yes, in this way your new datastructure can be used in all methods which accept AbstractVector

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [January 10, 2021, 3:17pm UTC](https://discourse.julialang.org/t/confused-with-type-definition/53115/8 "2021-01-10T15:17:04Z")

</div>

edited my example accordingly

---

<div class="post-metadata">

**Author:** ![alemelis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alemelis/32/208433_2.png) [@alemelis](https://discourse.julialang.org/u/alemelis)\
**Post date:** [January 10, 2021, 3:24pm UTC](https://discourse.julialang.org/t/confused-with-type-definition/53115/9 "2021-01-10T15:24:35Z")

</div>

not sure why it’s not working in the REPL tho

```julia
julia> struct MyVec <: AbstractVector{Float64}
         v::Vector{Float64}
       end

julia> MyVec([0.0, 0.0, 0.0])
Error showing value of type MyVec:
ERROR: MethodError: no method matching size(::MyVec)
Closest candidates are:
  size(::AbstractArray{T,N}, ::Any) where {T, N} at abstractarray.jl:38
  size(::Base.AsyncGenerator) at asyncmap.jl:409
  size(::Core.Compiler.StmtRange) at show.jl:1874
  ...

```

---

<div class="post-metadata">

**Author:** ![sostock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sostock/32/5546_2.png) [@sostock](https://discourse.julialang.org/u/sostock)\
**Post date:** [January 10, 2021, 3:40pm UTC](https://discourse.julialang.org/t/confused-with-type-definition/53115/10 "2021-01-10T15:40:56Z")

</div>

It does not work (or rather, cannot be printed) because a subtype of `AbstractVector` must implement some methods, see [here](https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-array).

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [January 10, 2021, 3:41pm UTC](https://discourse.julialang.org/t/confused-with-type-definition/53115/11 "2021-01-10T15:41:08Z")

</div>

That happens on showing the structure, add `;` at the end of the line to not show it. To fully implement the iteration interface see [Interfaces · The Julia Language](https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-iteration)

---

<div class="post-metadata">

**Author:** ![alemelis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alemelis/32/208433_2.png) [@alemelis](https://discourse.julialang.org/u/alemelis)\
**Post date:** [January 10, 2021, 3:48pm UTC](https://discourse.julialang.org/t/confused-with-type-definition/53115/12 "2021-01-10T15:48:03Z")

</div>

I see!

thanks for pointing out the interfaces docs page

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [January 10, 2021, 4:05pm UTC](https://discourse.julialang.org/t/confused-with-type-definition/53115/13 "2021-01-10T16:05:25Z")

</div>

I am kinda surprised nobody mentioned [Lazy.jl](https://github.com/MikeInnes/Lazy.jl) and its macro [`@forward`](https://github.com/MikeInnes/Lazy.jl/blob/master/src/macros.jl#L276).

Basically you can do:

```julia
import Base: length, getindex, setindex
using Lazy: @forward

struct MyVec <: AbstractVector{Float64}
  v::Vector{Float64} # same as Array{Float64, 1}
end

@forward MyVec.v Base.size, Base.getindex, Base.setindex!

```

For all function you just delegate to the field.

---

<div class="post-metadata">

**Author:** ![alemelis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alemelis/32/208433_2.png) [@alemelis](https://discourse.julialang.org/u/alemelis)\
**Post date:** [January 10, 2021, 4:56pm UTC](https://discourse.julialang.org/t/confused-with-type-definition/53115/14 "2021-01-10T16:56:41Z")

</div>

thanks @Henrique_Becker !

`@forward` provides the cherry on top of the previous answers 🙂
