# Constructors a la AbstractArray

**URL:** https://discourse.julialang.org/t/constructors-a-la-abstractarray/5003
**Category:** General Usage
**Tags:** question, type
**Created:** [July 21, 2017, 6:36pm UTC](https://discourse.julialang.org/t/constructors-a-la-abstractarray/5003 "2017-07-21T18:36:53Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [July 21, 2017, 6:36pm UTC](https://discourse.julialang.org/t/constructors-a-la-abstractarray/5003/1 "2017-07-21T18:36:53Z")

</div>

Suppose I have a regular grid defined as follows:

```julia
abstract type AbstractDomain{N,T<:Real} end

struct RegularGrid{N,T<:Real} <: AbstractDomain{N,T}
  dims::Dims{N}
  origin::NTuple{N,T}
  units::NTuple{N,T}
end

```

I am trying to define an outer constructor a la `AbstractArray` where I can specify the dimensions of the grid with a list of integers:

```julia
RegularGrid{T}(dims::Dims{N}) where {N,T<:Real} =
  RegularGrid{N,T}(dims, (zeros(T, length(dims))...), (ones(T, length(dims))...))

```

At the call site I would expect something like the following to work:

```julia
RegularGrid{Float64}(2,3) # creates a 2x3 grid with Float64 coordinates

```

What is the implementation that matches this interface?

---

<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: [July 21, 2017, 6:59pm UTC](https://discourse.julialang.org/t/constructors-a-la-abstractarray/5003/2 "2017-07-21T18:59:38Z")

</div>

You need to use an inner constructor to get this kind of behavior:

```julia
struct Foo{N, T}
    x::Array{T, N}

    Foo{T}(dims::Vararg{<:Integer, N}) where {T, N} = new{N, T}(zeros(T, dims...))
end

julia> Foo{Float64}(2, 3)
Foo{2,Float64}([0.0 0.0 0.0; 0.0 0.0 0.0])

```

---

<div class="post-metadata">

### Author: ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)
#### Post date: [July 21, 2017, 7:22pm UTC](https://discourse.julialang.org/t/constructors-a-la-abstractarray/5003/3 "2017-07-21T19:22:30Z")

</div>

I found that this has become a lot more logical since Julia 0.6.

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [July 21, 2017, 7:46pm UTC](https://discourse.julialang.org/t/constructors-a-la-abstractarray/5003/4 "2017-07-21T19:46:53Z")

</div>

Thank you @rdeits, out of curiosity, why is that the case that we can only achieve this behavior with inner constructors?

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [July 21, 2017, 8:42pm UTC](https://discourse.julialang.org/t/constructors-a-la-abstractarray/5003/5 "2017-07-21T20:42:49Z")

</div>

@rdeits, I am having a hard time trying to adapt your snippet to my specific example, could you please give a hand?

```julia
struct RegularGrid{N,T<:Real} <: AbstractDomain{N,T}
  dims::Dims{N}
  origin::NTuple{N,T}
  units::NTuple{N,T}

  function RegularGrid{T}(dims::Vararg{<:Integer,N}) where {N,T}
    new{N,T}(dims, (zeros(T,length(dims))...), (ones(T,length(dims))...))
  end
end

```

---

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [July 21, 2017, 9:06pm UTC](https://discourse.julialang.org/t/constructors-a-la-abstractarray/5003/6 "2017-07-21T21:06:44Z")

</div>

The trouble is that you’re defining the type as `RegularGrid{N,T}`, but trying to use a shorthand `RegularGrid{T}`.

Swap the order of the parameters in your definition if you want that shorthand.

---

<div class="post-metadata">

### Author: ![juthohaegeman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juthohaegeman/32/8620_2.png) [@juthohaegeman](https://discourse.julialang.org/u/juthohaegeman)
#### Post date: [July 21, 2017, 9:12pm UTC](https://discourse.julialang.org/t/constructors-a-la-abstractarray/5003/7 "2017-07-21T21:12:12Z")

</div>

First, there is another problem with your code. The constructor that should work with your definition is `RegularGrid{Float64}((2,3))`, i.e. with the `dims` specified as a tuple. However, this yields an error, because your type was defined as `RegularGrid{N,T}` with `N` first. But if you want an incomplete type specification with only `T`, you need to have `T` as first parameter (note `AbstractArray{T,N}`).

Then, to get the constructor you want, you need to use `Vararg`, but this does not need to be an inner constructor.

```julia

abstract type AbstractDomain{T<:Real,N} end

struct RegularGrid{T<:Real,N} <: AbstractDomain{T,N}
  dims::Dims{N}
  origin::NTuple{N,T}
  units::NTuple{N,T}
end

RegularGrid{T}(dims::Dims{N}) where {N,T<:Real} =
  RegularGrid{T,N}(dims, (zeros(T, length(dims))...), (ones(T, length(dims))...))

RegularGrid{T}(dims::Vararg{Int,N}) where {N,T<:Real} = RegularGrid{T}(dims)

```

Note that the last definition looks like it is calling itself. This is not true however. In the left, `dims` is a `Vararg`, i.e. multiple arguments. If you would not be interested in `N`, you could write it as `dims::Int...`. On the right hand side, when using the vararg `dims` in the function body, the different arguments to which it correspond will be collected in a tuple. Hense, on the right hand side `dims` is now `NTuple{N,Int}===Dims{N}`. This function call will then be passed on to the constructor you had written.

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [July 22, 2017, 12:09am UTC](https://discourse.julialang.org/t/constructors-a-la-abstractarray/5003/8 "2017-07-22T00:09:11Z")

</div>

That is something I didn’t know. I don’t remember for instance C++ having these types of issues with ordering of the parameters… Is it something that can be improved in future releases of Julia or it will stay like this?

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [July 22, 2017, 12:09am UTC](https://discourse.julialang.org/t/constructors-a-la-abstractarray/5003/9 "2017-07-22T00:09:46Z")

</div>

That is a very nice answer @juthohaegeman, thank you for going step-by-step explaining the nuances of the code. I am digesting and experimenting locally.

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [July 22, 2017, 12:12am UTC](https://discourse.julialang.org/t/constructors-a-la-abstractarray/5003/10 "2017-07-22T00:12:35Z")

</div>

@juthohaegeman, when we write an inner constructor like this:

```julia
struct Foo{T}
  a::Vector{T}
  function Foo{T}(a)
    new(a)
  end

```

are we saying the the argument `a` has type `Any`? Is it good practice to always include the types in the arguments of inner constructors or they are treated differently?

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [July 22, 2017, 12:20am UTC](https://discourse.julialang.org/t/constructors-a-la-abstractarray/5003/11 "2017-07-22T00:20:26Z")

</div>

The code after all your help looks as follows:

```julia
struct RegularGrid{T<:Real,N} <: AbstractDomain{T,N}
  dims::Dims{N}
  origin::NTuple{N,T}
  units::NTuple{N,T}

  function RegularGrid{T,N}(dims, origin, units) where {N,T<:Real}
    @assert all(dims .> 0) "dimensions must be positive"
    @assert all(units .> 0) "units must be positive"
    new(dims, origin, units)
  end
end

RegularGrid{T}(dims::Dims{N}) where {N,T<:Real} =
  RegularGrid{T,N}(dims, (zeros(T,length(dims))...), (ones(T,length(dims))...))

RegularGrid{T}(dims::Vararg{<:Integer,N}) where {N,T<:Real} = RegularGrid{T}(dims)

```

My only question now is about the inner constructor, should I annotate the type of the arguments or this is not necessary? I want to follow good Julian practices, still adapting to the syntax and programming style.

---

<div class="post-metadata">

### Author: ![juthohaegeman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juthohaegeman/32/8620_2.png) [@juthohaegeman](https://discourse.julialang.org/u/juthohaegeman)
#### Post date: [July 27, 2017, 8:20am UTC](https://discourse.julialang.org/t/constructors-a-la-abstractarray/5003/12 "2017-07-27T08:20:54Z")

</div>

I don’t think you need to annotate the arguments by types in the inner constructor (in this case) since they can only be of the type that you want by how the fields of your `struct` are specified. This might not always be the case though, and I don’t know what standard Julia style is.

instead of `(zeros(T,length(dims))...)` you could also use `ntuple(n->zero(T), Val{N})` (on Julia 0.6) or `ntuple(n->zero(T), Val(N))` (on Julia 0.7-) to get inferred types of the argument `origin` (and similar for `units`). Not that it matters much, the result of the function (i.e. a new `RegularGrid{T,N}` instance) will anyway be correctly inferred.

---

<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: [July 27, 2017, 12:07pm UTC](https://discourse.julialang.org/t/constructors-a-la-abstractarray/5003/13 "2017-07-27T12:07:14Z")

</div>

@juthohaegeman is correct about not needing to annotate the inner constructor in your example (and it is best practice to omit what is not needed … as would make your panache less easily seen).
