# Struct variables explicit setting

**URL:** <https://discourse.julialang.org/t/struct-variables-explicit-setting/57396>\
**Category:** New to Julia\
**Created:** [March 17, 2021, 4:11pm UTC](https://discourse.julialang.org/t/struct-variables-explicit-setting/57396 "2021-03-17T16:11:29Z")\
**Posts on this page:** 11\
**Page:** 2

<div class="post-metadata">

**Author:** ![Ribeiro](https://avatars.discourse-cdn.com/v4/letter/r/d9b06d/32.png) [@Ribeiro](https://discourse.julialang.org/u/Ribeiro)\
**Post date:** [March 18, 2021, 7:13pm UTC](https://discourse.julialang.org/t/struct-variables-explicit-setting/57396/21 "2021-03-18T19:13:45Z")

</div>

FYI, I tested:  
`Vector{StaticArrays.SVector{3,Int}}`  
vs  
`Vector{Union{ StaticArrays.SVector{3,Int},StaticArrays.SVector{4,Int} }}`  
or  
`Array{SArray{S,Int64,1,L} where L where S<:Tuple,1}`  
and the first is by far the best (though not flexible), the second is 20-30% slower, and the third is 2x slower! I may need to look into TypeSortedCollections.  
Thanks!

---

<div class="post-metadata">

**Author:** ![Ribeiro](https://avatars.discourse-cdn.com/v4/letter/r/d9b06d/32.png) [@Ribeiro](https://discourse.julialang.org/u/Ribeiro)\
**Post date:** [March 18, 2021, 9:01pm UTC](https://discourse.julialang.org/t/struct-variables-explicit-setting/57396/22 "2021-03-18T21:01:40Z")

</div>

Ok, I need one more tip:  
when I first build my struct I will have a certain number N that will be defined then and won’t change.  
I noticed that declaring StaticArrays with unknown numbers of elements is no good. Is there some way to have that number in the definition so the compiler treats it as hard coded?  
Right now, I’m declaring my vectors like this:

```julia
a :: Vector{StaticArrays.SVector{L,StaticArrays.SVector{4,Int}} where L}
b :: Vector{StaticArrays.MArray{L,Float64} where L}

```

and again, I will know L at struct creation time.  
Thanks!

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [March 18, 2021, 9:23pm UTC](https://discourse.julialang.org/t/struct-variables-explicit-setting/57396/23 "2021-03-18T21:23:17Z")

</div>

> [@Ribeiro](#):
>
> Is there some way to have that number in the definition so the compiler treats it as hard coded?

You can parameterize your struct by N, see [Types · The Julia Language](https://docs.julialang.org/en/v1.7-dev/manual/types/#Parametric-Types)

But, if N is too great or variable, it may be better to instead just use Core.Vector instead of StaticArrays.

---

<div class="post-metadata">

**Author:** ![Ribeiro](https://avatars.discourse-cdn.com/v4/letter/r/d9b06d/32.png) [@Ribeiro](https://discourse.julialang.org/u/Ribeiro)\
**Post date:** [March 19, 2021, 8:27am UTC](https://discourse.julialang.org/t/struct-variables-explicit-setting/57396/24 "2021-03-19T08:27:02Z")

</div>

So that would look like this:

```julia
struct whatever{L}
a :: Vector{StaticArrays.SVector{L,StaticArrays.SVector{4,Int}}}
b :: Vector{StaticArrays.MArray{L,Float64}}
end

```

but this

```julia
a=whatever([SA[SA[1,2,3,4],SA[2,3,4,5]]],[MVector(1.2,2.2)])

```

does not work.

Also, do I have to declare my functions as `fun(whatev{N})`, to get good performance?  
Oh, and how do I declare a regular Vector? I tried

```julia
c::Vector{L,Float64} # and {Float64,L}

```

but that did not work.  
Thanks a lot!

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [March 19, 2021, 3:06pm UTC](https://discourse.julialang.org/t/struct-variables-explicit-setting/57396/25 "2021-03-19T15:06:20Z")

</div>

> [@Ribeiro](#):
>
> So that would look like this:
> 
> ```julia
> struct whatever{L}
> a :: Vector{StaticArrays.SVector{L,StaticArrays.SVector{4,Int}}}
> b :: Vector{StaticArrays.MArray{L,Float64}}
> end
> 
> ```

In `b`, your declaration of an StaticArrays.MArray type is wrong, the REPL says the first argument should be a `Tuple` type instead of an `Int` value. Take a look at the StaticArrays documentation.

> Also, do I have to declare my functions as `fun(whatev{N})`, to get good performance?

See this section of the performance tips and the surrounding sections:  
[https://docs.julialang.org/en/v1.7-dev/manual/performance-tips/#Type-declarations](https://docs.julialang.org/en/v1.7-dev/manual/performance-tips/#Type-declarations)

Regarding Vectors, see  
[Multi-dimensional Arrays · The Julia Language](https://docs.julialang.org/en/v1.7-dev/manual/arrays/). The gist of it is that Vectors are defined to be Arrays with only one dimension, and they do **not** take a _length_ parameter. So use `Vector{Float64}`.

---

<div class="post-metadata">

**Author:** ![Ribeiro](https://avatars.discourse-cdn.com/v4/letter/r/d9b06d/32.png) [@Ribeiro](https://discourse.julialang.org/u/Ribeiro)\
**Post date:** [March 19, 2021, 4:59pm UTC](https://discourse.julialang.org/t/struct-variables-explicit-setting/57396/26 "2021-03-19T16:59:18Z")

</div>

Ok, but this here doesn’t work either:

```julia-auto
struct whatever{L}
  a :: Vector{StaticArrays.SVector{L,StaticArrays.SVector{4,Int}}}
  b :: Vector{StaticArrays.MArray{Tuple{L},Float64}}
end
a=whatever([SA[SA[1,2,3,4],SA[2,3,4,5]]],[MVector(1.2,2.2)])
ERROR: MethodError: no method matching whatever(::Array{SArray{Tuple{2},SArray{Tuple{4},Int64,1,4},1,2},1}, ::Array{MArray{Tuple{2},Float64,1,2},1})
Closest candidates are:
  whatever(::Array{SArray{Tuple{L},SArray{Tuple{4},Int64,1,4},1,L},1}, ::Array{MArray{Tuple{L},Float64,N,L1} where L1 where N,1}) where L at REPL[4]:2
Stacktrace:
 [1] top-level scope at REPL[5]:1

```

> [@nsajko](#):
>
> See this section of the performance tips and the surrounding sections:

The performance tips don’t really mention using {N} when calling or declaring functions and I guess my vars are all super type safe, so I guess I’m good from that perspective.

> [@nsajko](#):
>
> Vectors are defined to be Arrays with only one dimension, and they do **not** take a _length_ parameter.

Oh, so I can’t declare the length of Vectors. Thought it might help performance, but ok, then!  
Thanks again!

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [March 19, 2021, 6:01pm UTC](https://discourse.julialang.org/t/struct-variables-explicit-setting/57396/27 "2021-03-19T18:01:34Z")

</div>

> [@Ribeiro](#):
>
> Thought it might help performance

This is the case for static arrays. It is important when the vectors are small, in particular, because they can be manipulated in the stack or processor registry. When they are large they go to the heap and that does not make sense anymore.

> [@Ribeiro](#):
>
> `Vector{StaticArrays.SVector{L,StaticArrays.SVector{4,Int}}}`

This a vector of static vectors of static vectors (three levels of vector nested). Are you sure that is what you want?

Also, you can be more relaxed about type signatures. For example:

```julia
struct Whatever{T1,T2}
  a :: Vector{T1}
  b :: T2
end
Whatever(x::Vector{T1},y::T2) where {T1,T2} = Whatever{T1,T2}(x,y)

```

```julia
julia> Whatever( [SA[1,2], SA[3,4] ], MVector(1.0,2.0) )
Whatever{SArray{Tuple{2},Int64,1,2},MArray{Tuple{2},Float64,1,2}}(SArray{Tuple{2},Int64,1,2}[[1, 2], [
3, 4]], [1.0, 2.0])

```

The _instance_ of `Whatever` created here is completely signed with the type of element of vector `a` and the static mutable type and size of `b`. That will allow dispatch and specialization for these types. This specialization results from what was given to `Whatever` on construction of the instance, not on the definition of the `Whatever` struct. A great advantage of this approach is that you can use and test your code with many different types of variables in those fields without having to redefine your structs. (this is one of the reasons of the great composability of Julia code).

Edited according to @rdeits note

---

<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 19, 2021, 6:36pm UTC](https://discourse.julialang.org/t/struct-variables-explicit-setting/57396/28 "2021-03-19T18:36:52Z")

</div>

> [@lmiq](#):
>
> ```julia
> struct Whatever{T1,T2}
> a :: AbstractVector{T1}
> b :: T2
> end
> 
> ```

This is not recommended for performance, see: [Performance Tips · The Julia Language](https://docs.julialang.org/en/v1/manual/performance-tips/#Avoid-fields-with-abstract-type)

---

<div class="post-metadata">

**Author:** ![Ribeiro](https://avatars.discourse-cdn.com/v4/letter/r/d9b06d/32.png) [@Ribeiro](https://discourse.julialang.org/u/Ribeiro)\
**Post date:** [March 19, 2021, 6:45pm UTC](https://discourse.julialang.org/t/struct-variables-explicit-setting/57396/29 "2021-03-19T18:45:40Z")

</div>

Can anyone telll me how to do the Vector of MArrays? I still struggle a lot with these declarations.  
Thanks!

---

<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 19, 2021, 6:55pm UTC](https://discourse.julialang.org/t/struct-variables-explicit-setting/57396/30 "2021-03-19T18:55:59Z")

</div>

You can use `MVector{N, T}` instead. The `MVector` type is just a convenient alias designed to make it easier to specify an `MArray` type by hand, which is exactly what you’re trying to do:

```julia
julia> MVector{3, Float64}
MArray{Tuple{3},Float64,1,3}

julia> v = Vector{MVector{3, Float64}}();

julia> push!(v, MVector(1, 2, 3))
1-element Array{MArray{Tuple{3},Float64,1,3},1}:
 [1.0, 2.0, 3.0]

```

---

<div class="post-metadata">

**Author:** ![Ribeiro](https://avatars.discourse-cdn.com/v4/letter/r/d9b06d/32.png) [@Ribeiro](https://discourse.julialang.org/u/Ribeiro)\
**Post date:** [March 19, 2021, 7:21pm UTC](https://discourse.julialang.org/t/struct-variables-explicit-setting/57396/31 "2021-03-19T19:21:08Z")

</div>

@rdeits Ah, ok! I had tried that before, but I had messed up some other stuff.  
This works:

```julia
using StaticArrays
struct whatever{L}
  a :: Vector{StaticArrays.SVector{L,StaticArrays.SVector{4,Int}}}
  b :: Vector{StaticArrays.MVector{L,Float64}}
end
a=whatever([SA[SA[1,2,3,4],SA[2,3,4,5]]],[MVector(1.2,2.2)])

```

Thanks a lot!

[Previous page](https://discourse.julialang.org/t/struct-variables-explicit-setting/57396.md?page=1)
