# Subtyped parameters in constructors

**URL:** <https://discourse.julialang.org/t/subtyped-parameters-in-constructors/127287>\
**Category:** General Usage\
**Tags:** question, constructors\
**Created:** [March 23, 2025, 7:48pm UTC](https://discourse.julialang.org/t/subtyped-parameters-in-constructors/127287 "2025-03-23T19:48:40Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Deduction42](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/deduction42/32/9206_2.png) [@Deduction42](https://discourse.julialang.org/u/Deduction42)\
**Post date:** [March 23, 2025, 7:48pm UTC](https://discourse.julialang.org/t/subtyped-parameters-in-constructors/127287/1 "2025-03-23T19:48:40Z")

</div>

I was playing around with vague constructors and I noticed some very interesting and useful behavior of arrays. I can use “subtype” notation in array constructors!

```julia
julia> S = Diagonal(randn(5))
5×5 Diagonal{Float64, Vector{Float64}}:
 0.324104 ⋅ ⋅ ⋅ ⋅
  ⋅ -0.561848 ⋅ ⋅ ⋅
  ⋅ ⋅ 1.56105 ⋅ ⋅
  ⋅ ⋅ ⋅ -1.21263 ⋅
  ⋅ ⋅ ⋅ ⋅ 2.01912

julia> Array{<:Any,2}(S)
5×5 Matrix{Float64}:
 0.324104 0.0 0.0 0.0 0.0
 0.0 -0.561848 0.0 0.0 0.0
 0.0 0.0 1.56105 0.0 0.0
 0.0 0.0 0.0 -1.21263 0.0
 0.0 0.0 0.0 0.0 2.01912

```

How can I make my own structs do this? For example, I have a type called Quantity:

```julia
struct Quantity{T<:Any,U<:AbstractUnitLike}
    value :: T
    units :: U
end

```

I would like to get this behaviour if I do something like what follows instead of getting this error:

```julia
Quantity{Float64, <:AffineUnits}(v, u)
ERROR: MethodError: no method matching (Quantity{Float64, <:AffineUnits})(::Float64, ::AffineUnits{Dimensions{FixedRational{Int32, 25200}}})
The type `Quantity{Float64, <:AffineUnits}` exists, but no method is defined for this combination of argument types when trying to construct it.
Stacktrace:
 [1] top-level scope
   @ REPL[20]:1

```

How do I define the behaviour of a broader class like  
`Quantity{Float64, <:AbstractUnits}(v, u)`  
without defining a whole bunch of methods?

---

<div class="post-metadata">

**Author:** ![Deduction42](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/deduction42/32/9206_2.png) [@Deduction42](https://discourse.julialang.org/u/Deduction42)\
**Post date:** [March 23, 2025, 8:13pm UTC](https://discourse.julialang.org/t/subtyped-parameters-in-constructors/127287/2 "2025-03-23T20:13:23Z")

</div>

Just an update, I managed to get _some_ of my desired behaviour with this:

```julia
struct Quantity{T<:Any,U<:AbstractUnitLike}
    value :: T
    units :: U
    function Quantity{T,U}(v0::T0, u0::U0) where {T,U,T0,U0}
        u = u0 isa U ? u0 : convert(U, u0)
        v = v0 isa T ? v0 : convert(T, v0)
        return new{typeof(v), typeof(u)}(v,u)
    end
    Quantity(v,u) = new{typeof(v), typeof(u)}(v,u)
end

```

In this way, I can get my desired behaviour using

```julia
Quantity{Float64, AbstractUnits}(1.2, u"kg")

```

I was wondering how to make something like this work for

```julia
Quantity{Float64, <:AbstractUnits}(1.2, u"kg")

```

---

<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 23, 2025, 8:27pm UTC](https://discourse.julialang.org/t/subtyped-parameters-in-constructors/127287/3 "2025-03-23T20:27:16Z")

</div>

Not sure why you want this, but one approach is to dispatch on all subtypes of your type. For correctness, you may need to keep in mind that `Union{}` subtypes all types.

```julia
function (::Type{Q})(v, u) where {Q <: Quantity}
    # constructor code here
end

```

Also keep in mind there’s currently no generic way to access a bound (either lower or upper) of a type variable, see:

- [[FR] a new variant on method static parameter matching for getting the upper bound](https://discourse.julialang.org/t/fr-a-new-variant-on-method-static-parameter-matching-for-getting-the-upper-bound/118261)

---

<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 23, 2025, 8:42pm UTC](https://discourse.julialang.org/t/subtyped-parameters-in-constructors/127287/4 "2025-03-23T20:42:36Z")

</div>

Also see this section in the Manual: [Constructors are just callable objects](https://docs.julialang.org/en/v1/manual/constructors/#Constructors-are-just-callable-objects)

---

<div class="post-metadata">

**Author:** ![Deduction42](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/deduction42/32/9206_2.png) [@Deduction42](https://discourse.julialang.org/u/Deduction42)\
**Post date:** [March 24, 2025, 12:01am UTC](https://discourse.julialang.org/t/subtyped-parameters-in-constructors/127287/5 "2025-03-24T00:01:01Z")

</div>

Thanks, that pattern helped me with some other things, but on this behavior I think you’re right. This isn’t needed, and is less useful than I thought it would be. Conversions really should be specifying concrete types if that’s what you want returned.
