# Where on abstract type and parameters

**URL:** <https://discourse.julialang.org/t/where-on-abstract-type-and-parameters/128584>\
**Category:** General Usage\
**Tags:** question, type, parametric-types\
**Created:** [April 30, 2025, 7:49pm UTC](https://discourse.julialang.org/t/where-on-abstract-type-and-parameters/128584 "2025-04-30T19:49:40Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![croberts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/croberts/32/9465_2.png) [@croberts](https://discourse.julialang.org/u/croberts)\
**Post date:** [April 30, 2025, 7:49pm UTC](https://discourse.julialang.org/t/where-on-abstract-type-and-parameters/128584/1 "2025-04-30T19:49:40Z")

</div>

Is there a way to use a type signature that imposes that two arguments are the same subtype of an abstract type and also have the same parameter for some but not necessarily all parameters?

For example, the hypothetical method of `bob` below should dispatch whenever the two arguments (1) are both subtypes of AbstractArray (2) have the same concrete type (e.g. both are SparseArray or both are Array) (3) have the same number of dimensions. But they may have different eltypes.

```julia
""" method 1"""
bob(x::A{T1, D} , y::A{T2, D} ) where {A <: AbstractArray, T1, T2, D} = 
"same array type, same number of dimensions, possibly different eltypes"

```

The above throws an error (“TypeError: in Type{…} expression, expected UnionAll, got a value of type TypeVar”).

Methods that do not accomplish what I want, but are syntactically valid:

```julia
""" method 2"""
bob(x::AbstractArray{<:Any, D}, y::AbstractArray{<:Any, D}) where D = 
"abstract arrays with same number of dimensions"

""" method 3"""
bob(x::T, y::T) where T <: AbstractArray = 
"same subtype of abstract array"

""" method 4 """ 
bob(x::A, y::A) where A <: AbstractArray{T, D} where {T, D} = 
"same parametric type"

A = SentinelVector{Float64}(undef, 10)
bob(A, [1,2]) # dispatches to method 2. I do not want it to dispatch to method 1

bob([1 2; 3 4], [1,2]) # dispatches to method 3. I do not want it to dispatch to method 1

bob([1.], [2.]) # would dispatch to method 4.  

bob([1. 2.; 3. 4.], [1 2 3; 4 5 6]) # would want to dispatch to method 1.  
# does not match type signature for method 4.  
# matches type signature for method 2 and 3.  

```

Is there a syntax for method 1 that actually works, or is there no way to directly accomplish my intent with a single method signature? (note, I am not actually doing this for AbstractArray but for a user-defined type. The reason I am doing this is because if method 1 matches, then I can skip to directly doing a thing, but if method 1 does not match, then I want to do a bunch of checks before doing the thing, accomplished by `bob(x, y) = "do checks"`.

There are obvious workarounds – I could, for example, check in the function body for the conditions, but it seems like I should be able to directly and more parsimoniously accomplish this with a type signature.

---

<div class="post-metadata">

**Author:** ![JonasWickman](https://avatars.discourse-cdn.com/v4/letter/j/9de0a6/32.png) [@JonasWickman](https://discourse.julialang.org/u/JonasWickman)\
**Post date:** [April 30, 2025, 9:00pm UTC](https://discourse.julialang.org/t/where-on-abstract-type-and-parameters/128584/2 "2025-04-30T21:00:59Z")

</div>

I think this is what you want for method 1:

```julia
bob(x::AbstractArray{T1, D} , y::AbstractArray{T2, D} ) where {T1, T2, D} = 
"same array type, same number of dimensions, possibly different eltypes"

```

Edit: Nope, that will not guarantee that they are the same array type, nevermind.

---

<div class="post-metadata">

**Author:** ![VinceNeede](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vinceneede/32/215744_2.png) [@VinceNeede](https://discourse.julialang.org/u/VinceNeede)\
**Post date:** [April 30, 2025, 9:03pm UTC](https://discourse.julialang.org/t/where-on-abstract-type-and-parameters/128584/3 "2025-04-30T21:03:54Z")

</div>

The thing that I would expect to work is:

```julia
bob(x::A, y::A) where {D, A <: (AbstractArray{T, D} where T)}

```

But it seems to be treated as your method 4

---

<div class="post-metadata">

**Author:** ![croberts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/croberts/32/9465_2.png) [@croberts](https://discourse.julialang.org/u/croberts)\
**Post date:** [April 30, 2025, 9:17pm UTC](https://discourse.julialang.org/t/where-on-abstract-type-and-parameters/128584/4 "2025-04-30T21:17:44Z")

</div>

Thanks for trying! I suspect that the syntax might not exist. It’s not a crippling problem (because there are workarounds), but it feels wrong that this is not possible.

---

<div class="post-metadata">

**Author:** ![VinceNeede](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vinceneede/32/215744_2.png) [@VinceNeede](https://discourse.julialang.org/u/VinceNeede)\
**Post date:** [April 30, 2025, 9:40pm UTC](https://discourse.julialang.org/t/where-on-abstract-type-and-parameters/128584/5 "2025-04-30T21:40:57Z")

</div>

This should be a way to do that: [Dispatching on Types with the Same UnionAll (but You Don’t Know the Type Beforehand)](https://mcognetta.github.io/posts/dispatch-unionall-julia/)

But yes, it would be great to have an easy way to do it implemented in the language itself

---

<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:** [April 30, 2025, 11:28pm UTC](https://discourse.julialang.org/t/where-on-abstract-type-and-parameters/128584/6 "2025-04-30T23:28:32Z")

</div>

> [@croberts](#):
>
> (2) have the same concrete type (e.g. both are SparseArray or both are Array)

Nits aside (there are terminological issues, but I get what you mean), this condition is not expressible in Julia’s type system. What you really want when you say “concrete type” (which means something else) is the “base type”. However, an issue is that “base type” does not mean anything generically.

Relevant section in the docs:

- [Building a similar type with a different type parameter](https://docs.julialang.org/en/v1/manual/methods/#Building-a-similar-type-with-a-different-type-parameter)

> [@VinceNeede](#):
>
> This should be a way to do that: [Dispatching on Types with the Same UnionAll (but You Don’t Know the Type Beforehand)](https://mcognetta.github.io/posts/dispatch-unionall-julia/)

Don’t do that, it’s a horrible hack.

---

<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:** [April 30, 2025, 11:37pm UTC](https://discourse.julialang.org/t/where-on-abstract-type-and-parameters/128584/7 "2025-04-30T23:37:37Z")

</div>

> [@croberts](#):
>
> are the same subtype of an abstract type

One more thing to keep in mind is that the type system has no notion of the concept you call “same subtype” here. Basically what I think you mean by “subtype of an abstract type” is “declared with `struct` or `mutable struct`”, however that concept doesn’t exist in the type system.

---

<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:** [May 1, 2025, 12:19am UTC](https://discourse.julialang.org/t/where-on-abstract-type-and-parameters/128584/8 "2025-05-01T00:19:17Z")

</div>

> [@nsajko](#):
>
> What you really want when you say “concrete type” (which means something else) is the “base type”. However, an issue is that “base type” does not mean anything generically.

Some clarification:

- The definition of “concrete type” for Julia is, I guess, the `isconcretetype` doc string:

- Regarding the meaning of “base type”, for example:

- Some doc strings relevant for Julia’s subtyping in general:

---

<div class="post-metadata">

**Author:** ![croberts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/croberts/32/9465_2.png) [@croberts](https://discourse.julialang.org/u/croberts)\
**Post date:** [May 1, 2025, 1:00pm UTC](https://discourse.julialang.org/t/where-on-abstract-type-and-parameters/128584/9 "2025-05-01T13:00:59Z")

</div>

Thank you Neven!

Very helpful, and I appreciate you taking the time to clarify concepts and terminology!

---

<div class="post-metadata">

**Author:** ![FerreolS](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ferreols/32/216854_2.png) [@FerreolS](https://discourse.julialang.org/u/FerreolS)\
**Post date:** [May 1, 2025, 7:19pm UTC](https://discourse.julialang.org/t/where-on-abstract-type-and-parameters/128584/10 "2025-05-01T19:19:23Z")

</div>

Why dispatching using Holy trait mechanism is not a good solution?:

```julia-repl
julia> struct SameArray{d} end

julia> issamearray(a::A,b::B) where {A,B} = SameArray{A.name== B.name}()
issamearray (generic function with 1 method)

julia> bob(x::A, y::B ) where {D,T1,T2,A <: AbstractArray{T1,D}, B<:AbstractArray{T2,D}} = bob(issamearray(x,y),x,y)
bob (generic function with 3 methods)

julia> bob(::SameArray{false},x::A, y::B ) where {D,T1,T2,A <: AbstractArray{T1,D}, B<:AbstractArray{T2,D}} = 
       "different array type, same number of dimensions, possibly different eltypes"
bob (generic function with 3 methods)

julia> bob(::SameArray{true},x::A, y::B ) where {D,T1,T2,A <: AbstractArray{T1,D}, B<:AbstractArray{T2,D}} = 
       "same array type, same number of dimensions, possibly different eltypes"
bob (generic function with 3 methods)

julia> bob([1. 2.; 3. 4.], [1 2 3; 4 5 6])
"same array type, same number of dimensions, possibly different eltypes"

julia> bob([1. 2.; 3. 4.], sparse([1 2 3; 4 5 6]))
"different array type, same number of dimensions, possibly different eltypes"

```
