# How to define a function that accepts a vector when all elements are \<: S even if the vector is defined as Vector{T} with S \<: T

**URL:** https://discourse.julialang.org/t/how-to-define-a-function-that-accepts-a-vector-when-all-elements-are-s-even-if-the-vector-is-defined-as-vector-t-with-s-t/83182
**Category:** General Usage
**Created:** [June 22, 2022, 12:53pm UTC](https://discourse.julialang.org/t/how-to-define-a-function-that-accepts-a-vector-when-all-elements-are-s-even-if-the-vector-is-defined-as-vector-t-with-s-t/83182 "2022-06-22T12:53:30Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)
#### Post date: [June 22, 2022, 12:53pm UTC](https://discourse.julialang.org/t/how-to-define-a-function-that-accepts-a-vector-when-all-elements-are-s-even-if-the-vector-is-defined-as-vector-t-with-s-t/83182/1 "2022-06-22T12:53:30Z")

</div>

I have a situation where I want to remain general on the type of a specific container (`AbstractAbstractFoo`), as in the future I may develop other types (say `AbstractFoo2` in the example below), but I have a concrete application for a specific subtype (`AbstractFoo`).

The problem is that when my container is passed to a function defined over the specific type, even if all the elements are of that specific type, of course, it gives a `MethodError`.

How do you deal with situations like this one ? Manual checking of all the elements of the vector?  
Calling `identity.(x)` before bla ? Is this the right function to call to get a container type to the “minimum common denominator” of the element types ?

```julia
abstract type AbstractAbstractFoo end
abstract type AbstractFoo <: AbstractAbstractFoo end

mutable struct Foo <: AbstractFoo end

x = AbstractAbstractFoo[]

push!(x,Foo())
push!(x,Foo())

bla(x::Vector{T}) where {T<:AbstractFoo} = println("hello")

bla(x) # MethodError

```

---

<div class="post-metadata">

### Author: ![Krastanov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krastanov/32/6817_2.png) [@Krastanov](https://discourse.julialang.org/u/Krastanov)
#### Post date: [June 22, 2022, 1:13pm UTC](https://discourse.julialang.org/t/how-to-define-a-function-that-accepts-a-vector-when-all-elements-are-s-even-if-the-vector-is-defined-as-vector-t-with-s-t/83182/2 "2022-06-22T13:13:24Z")

</div>

I do not think you can do that. Your vector can in-principle store entities that are not `AbstractFoo`, so it makes sense to me that your `bla` gives a method error. Basically, you are asking for a method that dispatches **not** on the type of a container (something immutable on which you can efficiently dispatch), rather you are asking for it to dispatch on the content (which would be very inefficient as you have to check the entire content every time you run the method).

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [June 22, 2022, 1:31pm UTC](https://discourse.julialang.org/t/how-to-define-a-function-that-accepts-a-vector-when-all-elements-are-s-even-if-the-vector-is-defined-as-vector-t-with-s-t/83182/3 "2022-06-22T13:31:32Z")

</div>

You can define `bla_elem` for each type of element and have a `bla` that takes a container (a `Vector`{T} where {T}`) and calls `bla\_elem` fo each element (considering the type of the element does not change how the collection is handled only its individual elements). This will not be efficient but will work. You can define specializations for specific vector specializations, but as you perceived, what matters for dispatch is the type of the container (not its actual values).

---

<div class="post-metadata">

### Author: ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)
#### Post date: [June 22, 2022, 1:36pm UTC](https://discourse.julialang.org/t/how-to-define-a-function-that-accepts-a-vector-when-all-elements-are-s-even-if-the-vector-is-defined-as-vector-t-with-s-t/83182/4 "2022-06-22T13:36:25Z")

</div>

I am now using `x = identity.(x)` before the `bla` call. Is this the best way to change the type of a container to the most specific type whose all members are subtypes ?

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [June 22, 2022, 2:00pm UTC](https://discourse.julialang.org/t/how-to-define-a-function-that-accepts-a-vector-when-all-elements-are-s-even-if-the-vector-is-defined-as-vector-t-with-s-t/83182/5 "2022-06-22T14:00:57Z")

</div>

This is probably the easiest way, but I do not know if Julia gives you any guarantees about using the most specific type in the container returned by broadcast. The documentation for `broadcast` does not specify it, but maybe you can implement your own promotion rules to guarantee that.

---

<div class="post-metadata">

### Author: ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)
#### Post date: [June 22, 2022, 8:24pm UTC](https://discourse.julialang.org/t/how-to-define-a-function-that-accepts-a-vector-when-all-elements-are-s-even-if-the-vector-is-defined-as-vector-t-with-s-t/83182/6 "2022-06-22T20:24:21Z")

</div>

YASGuide says don’t use dispatch for this:

> - Dispatching on type parameters should be avoided unless necessary, especially if the method author does not “own” the method and/or the type being parameterized (in which case, this kind of dispatch could be an instance of “type piracy”). This is because naive dispatch on type parameters often does not (and cannot) describe values the way the programmer intends, unless the programmer explicitly accounts for invariance. For example, `AbstractArray{<:MyType}` does not describe “any value of type `<:AbstractArray` containing elements of type `<:MyType`”; it only describes a subset of such values (e.g. `typeof(Any[1]) <: AbstractArray{<:Number}` is `false`). Likewise, `AbstractArray{>:MyType}` describes “any value of type `<:AbstractArray` that _could_ contain elements of type `<:MyType`”, which is likely a superset of what the programmer intended to describe (e.g. `AbstractArray{Any} <: AbstractArray{>:Number}` is `true`). This guideline can generally be relaxed when the method author “owns” both the method and the type being parameterized.

> **[GitHub - jrevels/YASGuide: Yet Another Style Guide For Julia](https://github.com/jrevels/YASGuide#programming-guidelines)**
>
> Yet Another Style Guide For Julia. Contribute to jrevels/YASGuide development by creating an account on GitHub.
