# Function with a single method acting on Union{T1, T2} or another function with two methods, for T1 and T2?

**URL:** <https://discourse.julialang.org/t/function-with-a-single-method-acting-on-union-t1-t2-or-another-function-with-two-methods-for-t1-and-t2/52132>\
**Category:** New to Julia\
**Created:** [December 20, 2020, 3:07pm UTC](https://discourse.julialang.org/t/function-with-a-single-method-acting-on-union-t1-t2-or-another-function-with-two-methods-for-t1-and-t2/52132 "2020-12-20T15:07:40Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![mocalvao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mocalvao/32/19318_2.png) [@mocalvao](https://discourse.julialang.org/u/mocalvao)\
**Post date:** [December 20, 2020, 3:07pm UTC](https://discourse.julialang.org/t/function-with-a-single-method-acting-on-union-t1-t2-or-another-function-with-two-methods-for-t1-and-t2/52132/1 "2020-12-20T15:07:40Z")

</div>

I have the following code:

```julia
struct Square{T<:Real}
    width::T = 1
end

struct Rectangle{T<:Real}
    width::T = 1
    height::T = 2
end

Quadrilateral = Union{Square, Rectangle}

function area1(q::Quadrilateral)
    if q isa Square
        return q.width^2
    elseif q isa Rectangle
        return q.width * q.height
    end
end

function area2(q::Square)
    q.width^2
end

function area2(q::Rectangle)
    q.width * q.height
end

```

When I use `@code_warntype`, upon the same concrete Quadrilateral, the output for the `area1` function, which uses the Union{Square, Rectangle} type, is longer and seems to be a little more contrived than the corresponding output for the `area2` function. Using a naive benchmarking does not, however, seem to give appreciable difference.  
Which strategy should I follow/prefer, taking into account better code legibility and performance? Right now, I am inclined to using `area2`, with its specific methods, according to the different calling signatures; does that sound reasonable?

---

<div class="post-metadata">

**Author:** ![hendri54](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hendri54/32/9621_2.png) [@hendri54](https://discourse.julialang.org/u/hendri54)\
**Post date:** [December 20, 2020, 3:41pm UTC](https://discourse.julialang.org/t/function-with-a-single-method-acting-on-union-t1-t2-or-another-function-with-two-methods-for-t1-and-t2/52132/2 "2020-12-20T15:41:38Z")

</div>

This is similar to

> [@Method dispatch](https://discourse.julialang.org/t/method-dispatch/51709):
>
> Julia is a lot about multiple dispatching and I am having trouble to understand what an idiomatic way of using mulitple dispatch is. My question is for small methods if I should define two different methods or if I should just use if else statements? (i.e. if typeof(...)...) Example: I want to format/convert numbers or arrays of numbers into a string. Is the below approach reasonable? Or what is an idiomatic way to deal with the two cases (i) a single number and (ii) an array of things (e.g. n…

Generically, the `area2` approach has two benefits:

- it can be expanded to additional shapes
- it guarantees compile time dispatch (if the rest of the code is type stable)  
Perhaps the logical approach would be to set up `Square` and `Rectangle` as subtypes of `Quadrilateral`. But that depends on what else you are doing with those types.

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [December 20, 2020, 4:07pm UTC](https://discourse.julialang.org/t/function-with-a-single-method-acting-on-union-t1-t2-or-another-function-with-two-methods-for-t1-and-t2/52132/3 "2020-12-20T16:07:40Z")

</div>

Both versions should perform identically, you are just viewing the typed IR before optimization. They actually produce the same optimized code for me:

```julia
julia> @code_warntype area1(Square(1))
Variables
  #self#::Core.Compiler.Const(area1, false)
  q::Square{Int64}

Body::Int64
1 ─ %1 = (q isa Main.Square)::Core.Compiler.Const(true, false)
│ %1
│ %3 = Base.getproperty(q, :width)::Int64
│ %4 = Core.apply_type(Base.Val, 2)::Core.Compiler.Const(Val{2}, false)
│ %5 = (%4)()::Core.Compiler.Const(Val{2}(), false)
│ %6 = Base.literal_pow(Main.:^, %3, %5)::Int64
└── return %6
2 ─ Core.Compiler.Const(:(q isa Main.Rectangle), false)
│ Core.Compiler.Const(:(%8), false)
│ Core.Compiler.Const(:(Base.getproperty(q, :width)), false)
│ Core.Compiler.Const(:(Base.getproperty(q, :height)), false)
│ Core.Compiler.Const(:(%10 * %11), false)
│ Core.Compiler.Const(:(return %12), false)
└── Core.Compiler.Const(:(return), false)

julia> @code_warntype optimize=true area1(Square(1))
Variables
  #self#::Core.Compiler.Const(area1, false)
  q::Square{Int64}

Body::Int64
1 ─ %1 = Base.getfield(q, :width)::Int64
│ %2 = Base.mul_int(%1, %1)::Int64
└── return %2

julia> @code_warntype optimize=true area2(Square(1))
Variables
  #self#::Core.Compiler.Const(area2, false)
  q::Square{Int64}

Body::Int64
1 ─ %1 = Base.getfield(q, :width)::Int64
│ %2 = Base.mul_int(%1, %1)::Int64
└── return %2

```

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [December 20, 2020, 9:35pm UTC](https://discourse.julialang.org/t/function-with-a-single-method-acting-on-union-t1-t2-or-another-function-with-two-methods-for-t1-and-t2/52132/4 "2020-12-20T21:35:41Z")

</div>

One of approaches here, since both structs are immutable, is to define accessor functions `width` and `height` and make a single generic function `area` using accessors:

```julia
width(q::Union{Rectangle, Square}) = q.width
height(q::Square) = q.width
height(q::Rectangle) = q.height

area(q::Union{Rectangle, Square}) = width(q) * height(q)

```

---

<div class="post-metadata">

**Author:** ![hendri54](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hendri54/32/9621_2.png) [@hendri54](https://discourse.julialang.org/u/hendri54)\
**Post date:** [December 21, 2020, 12:08pm UTC](https://discourse.julialang.org/t/function-with-a-single-method-acting-on-union-t1-t2-or-another-function-with-two-methods-for-t1-and-t2/52132/5 "2020-12-21T12:08:50Z")

</div>

For clarification: are you asking about the generic pattern or about the actual code that you posted? I think this will affect the answer.

---

<div class="post-metadata">

**Author:** ![mocalvao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mocalvao/32/19318_2.png) [@mocalvao](https://discourse.julialang.org/u/mocalvao)\
**Post date:** [December 21, 2020, 1:19pm UTC](https://discourse.julialang.org/t/function-with-a-single-method-acting-on-union-t1-t2-or-another-function-with-two-methods-for-t1-and-t2/52132/6 "2020-12-21T13:19:33Z")

</div>

@hendri54: I do not understand exactly what you mean… At any rate, any further comments are much welcome. Your former reply helped a lot and I read the link you mentioned there.

Likewise, I enjoyed the flag optimize=true to @code\_warntype which @simeonschaub used in his post.

---

<div class="post-metadata">

**Author:** ![hendri54](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hendri54/32/9621_2.png) [@hendri54](https://discourse.julialang.org/u/hendri54)\
**Post date:** [December 21, 2020, 9:18pm UTC](https://discourse.julialang.org/t/function-with-a-single-method-acting-on-union-t1-t2-or-another-function-with-two-methods-for-t1-and-t2/52132/7 "2020-12-21T21:18:57Z")

</div>

I asked because some replies (especially mine) discussed the general pattern (similar to the thread I pointed to earlier), while others discussed how to specifically calculate areas.  
This matters, for example, for the question whether one can rely on compiler optimization to remove the unused branch in each call to `area1`.

---

<div class="post-metadata">

**Author:** ![mocalvao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mocalvao/32/19318_2.png) [@mocalvao](https://discourse.julialang.org/u/mocalvao)\
**Post date:** [December 23, 2020, 11:26am UTC](https://discourse.julialang.org/t/function-with-a-single-method-acting-on-union-t1-t2-or-another-function-with-two-methods-for-t1-and-t2/52132/8 "2020-12-23T11:26:24Z")

</div>

My actual post was only a minimal working example (MWE). In fact, I am using that generic pattern in a larger code; I am not particularly concerned with this naive area example, but I think it might make things stripped down to the essential matter… I would like to hear any more generic comments or pointers anyone might deem relevant
