# Tuples of "any container" of a parametric type - give me the parameter

**URL:** <https://discourse.julialang.org/t/tuples-of-any-container-of-a-parametric-type-give-me-the-parameter/8560>\
**Category:** General Usage\
**Created:** [January 24, 2018, 10:31am UTC](https://discourse.julialang.org/t/tuples-of-any-container-of-a-parametric-type-give-me-the-parameter/8560 "2018-01-24T10:31:04Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Philippe\_Maincon](https://avatars.discourse-cdn.com/v4/letter/p/a4c791/32.png) [@Philippe\_Maincon](https://discourse.julialang.org/u/Philippe_Maincon)\
**Post date:** [January 24, 2018, 10:31am UTC](https://discourse.julialang.org/t/tuples-of-any-container-of-a-parametric-type-give-me-the-parameter/8560/1 "2018-01-24T10:31:04Z")

</div>

I wish to write a function foo, which takes, among arguments, a Tuple. **Each** element in the Tuple can be a scalar or an Array of arbitrary dimension. The scalars and array elements are all of the same type Mytype{Nmy} (Nmy shall be common for all elements in the Tuple).

My function will return a scalar or an Array of scalars, where the scalars are of type Mytype{Nmy}

I need to know N, so that I can write typestable code

```julia
using StaticArrays

struct Mytype{N}
    x :: Float64
    dx :: SVector{N,Float64}
end
Mytype(x,dx::Vector{Float64}) =Mytype(x,SVector{size(dx,1),Float64}(dx))
Base.:(+)(a::Mytype{N},b::Mytype{N}) where {N} = Mytype{N}(a.x+b.x,a.dx+b.dx)

MytypeContainer{N} = Union{Mytype{N},Array{Mytype{N}}}

function foo(args::NTuple{nx,MytypeContainer{N}}) where {N,nx}
    s = Mytype{N}(0.,zeros(N))
    for arg in args 
        if isa(arg,Mytype{N})
            s += arg
        else
            for x in arg
                s += x
            end
        end
    end
    return s
end

v1 = Mytype{2}(3.,[1.,2.])
v2 = Mytype{2}(4.,[5.,6.])
v = [v1,v2]
@show foo((v,))
@show foo((v1,))
@show foo((v1,v2))
@show foo((v,v))
@show foo((v1,v))

```

In ways I do not understand,

```julia
::Tuple{Union{Mytype{N},Array{Mytype{N}}}}

```

is not expressing what I intend: a tuple of any type of containers of Mytype{N}, and give me N for typestable allocation.

P.S. The code above is now updated and seems to pass the test.

---

<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:** [January 24, 2018, 11:12am UTC](https://discourse.julialang.org/t/tuples-of-any-container-of-a-parametric-type-give-me-the-parameter/8560/2 "2018-01-24T11:12:27Z")

</div>

It is not entirely clear what you want, but

1. `Mytype(0.,zeros(N))` is not type stable to start with,
2. use `@code_warntype` to investigate type stability,
3. why are you wrapping a single argument in a `Tuple`? it should be inferrable, but hard to see the reason for it.

---

<div class="post-metadata">

**Author:** ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)\
**Post date:** [January 24, 2018, 11:55am UTC](https://discourse.julialang.org/t/tuples-of-any-container-of-a-parametric-type-give-me-the-parameter/8560/3 "2018-01-24T11:55:30Z")

</div>

> [@Philippe\_Maincon](#):
>
> Mytype(x,dx::Vector{Float64})

Use

```julia
Mytype(x,dx::NTuple{N,Float64}) where {N}

```

instead. And use

```julia
s = Mytype{N}(0.,ntuple((i)->0., Val{N}))

```

to initialize in a type-stable way.

Also give a minimum working example (MWE) to make it easier to help you.

---

<div class="post-metadata">

**Author:** ![Philippe\_Maincon](https://avatars.discourse-cdn.com/v4/letter/p/a4c791/32.png) [@Philippe\_Maincon](https://discourse.julialang.org/u/Philippe_Maincon)\
**Post date:** [January 24, 2018, 12:03pm UTC](https://discourse.julialang.org/t/tuples-of-any-container-of-a-parametric-type-give-me-the-parameter/8560/4 "2018-01-24T12:03:18Z")

</div>

Tamas, Mohamed,

I see from your answers that I have been very poor at explaining myself! Apologies and thank your for your effort.

I have provided some code above, intended as a MWE. Note that I have updated it since my first post. At present, _it works_ (as in: it compiles, and gives all the expected answers). Whether the code is typestable is an open question, I am still learning the ropes there.

Typing

```julia
@code_warntype foo((v,))

```

gives me

```julia
Variables:
  #self#::#foo
  args::Tuple{Array{Mytype{2},1}}
  x::Mytype{2}
  #temp#@_4::Int64
  arg::Array{Mytype{2},1}
  #temp#@_6::Int64
  s::Mytype{2}

Body:
  begin 
      s::Mytype{2} = $(Expr(:invoke, MethodInstance for Mytype{2}(::Float64, ::Array{Float64,1}), Mytype{2}, 0.0, :($(Expr(:invoke, MethodInstance for fill!(::Array{Float64,1}, ::Float64), :(Base.fill!), :($(Expr(:foreigncall, :(:jl_alloc_array_1d), Array{Float64,1}, svec(Any, Int64), Array{Float64,1}, 0, :($(Expr(:static_parameter, 1))), 0))), :((Base.sitofp)(Float64, 0)::Float64)))))) # line 14:
      #temp#@_6::Int64 = 1
      4: 
      unless (Base.not_int)((Base.slt_int)(1, #temp#@_6::Int64)::Bool)::Bool goto 28
      SSAValue(5) = (Base.getfield)(args::Tuple{Array{Mytype{2},1}}, #temp#@_6::Int64)::Array{Mytype{2},1}
      SSAValue(6) = (Base.add_int)(#temp#@_6::Int64, 1)::Int64
      arg::Array{Mytype{2},1} = SSAValue(5)
      #temp#@_6::Int64 = SSAValue(6) # line 15:
      goto 13 # line 16:
      13: # line 18:
      #temp#@_4::Int64 = 1
      16: 
      unless (Base.not_int)((#temp#@_4::Int64 === (Base.add_int)((Base.arraylen)(arg::Array{Mytype{2},1})::Int64, 1)::Int64)::Bool)::Bool goto 26
      SSAValue(7) = (Base.arrayref)(arg::Array{Mytype{2},1}, #temp#@_4::Int64)::Mytype{2}
      SSAValue(8) = (Base.add_int)(#temp#@_4::Int64, 1)::Int64
      x::Mytype{2} = SSAValue(7)
      #temp#@_4::Int64 = SSAValue(8) # line 19:
      s::Mytype{2} = $(Expr(:invoke, MethodInstance for +(::Mytype{2}, ::Mytype{2}), :(Main.+), :(s), :(x)))
      24: 
      goto 16
      26: 
      goto 4
      28: # line 23:
      return s::Mytype{2}
  end::Mytype{2}

```

which could be bad news or good news!  
🙂

---

<div class="post-metadata">

**Author:** ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)\
**Post date:** [January 24, 2018, 12:07pm UTC](https://discourse.julialang.org/t/tuples-of-any-container-of-a-parametric-type-give-me-the-parameter/8560/5 "2018-01-24T12:07:19Z")

</div>

Please give some code I can copy and paste to REPL 🙂

Edit: oh it’s above, sorry didn’t see it.

---

<div class="post-metadata">

**Author:** ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)\
**Post date:** [January 24, 2018, 12:18pm UTC](https://discourse.julialang.org/t/tuples-of-any-container-of-a-parametric-type-give-me-the-parameter/8560/6 "2018-01-24T12:18:15Z")

</div>

> [@Philippe\_Maincon](#):
>
> ```julia
> Mytype(x,dx::Vector{Float64}) = Mytype(x,SVector{size(dx,1),Float64}(dx))
> 
> ```

You are not calling the above function at all by running `Mytype{2}(3.,[1.,2.])`. Instead, you are calling the inner constructor, that is you are telling Julia that you want an instance of the concrete type `MyType{2}` thus `N` is now known to the compiler, and a conversion of the second argument happens behind the scene from the array you are passing to `SVector{2,Float64}` as `N` is 2 in your example. Your code therefore seems type stable because you are avoiding this type unstable function.

---

<div class="post-metadata">

**Author:** ![Philippe\_Maincon](https://avatars.discourse-cdn.com/v4/letter/p/a4c791/32.png) [@Philippe\_Maincon](https://discourse.julialang.org/u/Philippe_Maincon)\
**Post date:** [January 24, 2018, 12:19pm UTC](https://discourse.julialang.org/t/tuples-of-any-container-of-a-parametric-type-give-me-the-parameter/8560/7 "2018-01-24T12:19:26Z")

</div>

😁
