That’s a good start, I would simplify a few things and to make it more idiomatic and efficient, add some type parameters. First, the type definitions:

```
struct Point{R<:Real}
x :: R
y :: R
end
abstract type ConvexShape{R} end
struct Circle{R<:Real} <: ConvexShape{R}
center :: Point{R}
radius :: R
end
struct Rectangle{R<:Real} <: ConvexShape{R}
left :: R
right :: R
bottom :: R
top :: R
end
Rectangle(p::Point, q::Point) =
Rectangle(minmax(p.x, q.x)..., minmax(p.y, q.y)...)
# a matrix of the corners of a rectangle
corners(r::Rectangle) = [Point(x, y) for x in (r.left, r.right), y in (r.bottom, r.top)]
```

Now some geometric computational methods:

```
dist(p::Point, q::Point) = sqrt((p.x - q.x)^2 + (p.y - q.y)^2)
inside(p::Point, q::Point) = p == q
inside(p::Point, c::Circle) = dist(p, c.center) ≤ c.radius
inside(p::Point, r::Rectangle) =
r.left ≤ p.x ≤ r.right && r.bottom ≤ p.y ≤ r.top
inside(c::Circle, c′::Circle) =
c.radius + dist(c.center, c′.center) ≤ c′.radius
inside(c::Circle, r::Rectangle) =
r.left ≤ c.center.x - c.radius && c.center.x + c.radius ≤ r.right &&
r.bottom ≤ c.center.y - c.radius && c.center.y + c.radius ≤ r.top
inside(r::Rectangle, c::ConvexShape) =
all(inside(p, c) for p in corners(r))
const ⊆ = inside
```

A few points about why I wrote things this way:

- Type parameters allow structs to be much more efficient and always have matching types for fields
- These allow you to use whatever real number type you want for the dimensions, e.g.
`Float64`

, `Int`

or something slightly exotic like `Rational{BigInt}`

- No need to define constructors most of the time—the defaults just work
- Also no need to provide show methods often, the default is pretty good
- Since you can put types on arguments, it’s often clearer to use short argument names for math formulas—you can tell that
`p`

is a `Point`

and `c`

is a `Circle`

, etc. from the method signature
- It is conventional in Julia to express “subject verb object” relationships as
`verb(subject, object)`

; accordingly one should read `inside(c::Circle, r::Rectangle)`

as “`c`

is inside `r`

”; at the end I create `⊆`

as an alias for `inside`

which allows write this using infix operator notation as `c ⊆ r`

which matches mathematical notation.

About the representation and construction of Rectangles:

- There are many ways to represent and construct this type
- I like
`Rectangle(::Point, ::Point)`

for construction because you don’t have to remember which corner is special or which which order the arguments are in—if you give any two points it constructs the rectangle between them
- Internal representation doesn’t really matter, but a list of left, right, bottom and top coordinates seems simple and allows easy construction from two points.

The only bit of type system cleverness here:

- I create an abstract type
`ConvexShape`

and make `Circle`

and `Rectangle`

implementations of it
- Checking if a rectangle is contained in any convex shape can be done by checking if all its corners are inside the convex shape, so we can define a single method

Note that the way these types are defined they work great if you use the same `Real`

type everywhere (e.g. all `Int`

or all `Float64`

), but they start breaking as soon as you try mixing integers and floats for example. If you want to allow mixing types, then you can define these additional mixed type constructors for convenience:

```
Point(x::Real, y::Real) =
Point(promote(x, y)...)
Rectangle(left::Real, right::Real, bottom::Real, top::Real) =
Rectangle(promote(left, right, bottom, top)...)
function Circle(center::Point{R}, radius::S) where {R<:Real, S<:Real}
T = promote_type(R, S)
Circle(Point{T}(center.x, center.y), convert(T, radius))
end
```

Here’a a fun example that ends up using a lot of the above functionality:

```
julia> o = Point(0, 0) # origin
Point{Int64}(0, 0)
julia> c₁ = Circle(o, 1)
Circle{Int64}(Point{Int64}(0, 0), 1)
julia> c₂ = Circle(o, 2)
Circle{Int64}(Point{Int64}(0, 0), 2)
julia> c₁ ⊆ c₂
true
julia> c₁ ⊆ c₁
true
julia> c₂ ⊆ c₁
false
julia> r = Rectangle(Point(-1, -1), Point(1, 1))
Rectangle{Int64}(-1, 1, -1, 1)
julia> c₁ ⊆ r ⊆ c₂
true
```