I am trying to have a struct
for one of my types, that (among others for the nonMWE) keeps an array as a value. I would like to have a size
function that works on the encapsulated array. The MWE is as follows
import Base: size
struct MyType
value::Array{Float64,N} where N
name::String
end
getValue(a::MyType) = a.value
size(a::MyType,k...) = size(getValue(a),k...)
function f(a::MyType,b::MyType)::MyType
if size(a)==size(b)
c = MyType( a.value .+ b.value, string(a.name,"-",b.name) )
end
return c
end
a = MyType(ones(3,3), "A")
b = MyType(zeros(3,3), "B")
f(a,b)
@code_warntype f(a,b)
So the function f
creates a new MyType
based on two types and needs size as a check. However, the return type of size
that I implemented. The complete code_warntype
is
Body::MyType
10 1 ─ %1 = invoke Main.size(_2::MyType)::Any │
│ %2 = invoke Main.size(_3::MyType)::Any │
│ %3 = (%1 == %2)::Any │
└── goto #3 if not %3 │
11 2 ─ %5 = Base.Broadcast.materialize::Core.Compiler.Const(Base.Broadcast.materialize, false) │
│ %6 = (Base.getfield)(a, :value)::Array{Float64,N} where N │╻ getproperty
│ %7 = (Base.getfield)(b, :value)::Array{Float64,N} where N ││
│ %8 = Main.:+::Core.Compiler.Const(+, false) │
│ %9 = (Base.Broadcast.combine_styles)(%6, %7)::Any │╻ broadcasted
│ %10 = (Base.Broadcast.broadcasted)(%9, %8, %6, %7)::Any ││
│ %11 = (%5)(%10)::Any │
│ %12 = (Base.getfield)(a, :name)::String │╻ getproperty
│ %13 = (Base.getfield)(b, :name)::String ││
│ %14 = invoke Main.string(%12::String, "-"::String, %13::Vararg{String,N} where N)::String │
└── %15 = (Main.MyType)(%11, %14)::MyType │
13 3 ─ %16 = φ (#2 => true, #1 => false)::Bool │
│ %17 = φ (#2 => %15, #1 => #undef)::Core.Compiler.MaybeUndef(MyType) │
│ $(Expr(:throw_undef_if_not, :c, :(%16))) │
└── return %17
(and I am still trying to understand all of this output) - but directly the first two ones (and from that the third) worries me a little – how can i get my own size
function to have the same return type as the original size
?
and a short side question – is it (performance wise) the best way to create an own MyType
for the result c
?
Any further ideas to optimize a code like this are of course also welcome.