# Unitful and generic function types

**URL:** <https://discourse.julialang.org/t/unitful-and-generic-function-types/119198>\
**Category:** General Usage\
**Tags:** array, type, unitful\
**Created:** [September 8, 2024, 10:29pm UTC](https://discourse.julialang.org/t/unitful-and-generic-function-types/119198 "2024-09-08T22:29:10Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![mesonepigreco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mesonepigreco/32/46262_2.png) [@mesonepigreco](https://discourse.julialang.org/u/mesonepigreco)\
**Post date:** [September 8, 2024, 10:29pm UTC](https://discourse.julialang.org/t/unitful-and-generic-function-types/119198/1 "2024-09-08T22:29:10Z")

</div>

I have a function not using Unitful that reads like

```julia
function foo(x :: Matrix{T}, y :: Vector{T}) where T
    my_array = zeros(T, 100)
    # other stuff 
end

```

Now, I want to implement my code using Unitful to make it easier to spot bugs with dimensional checks, allow the user to pass data in whatever units he/she likes the most, and have Unitful handle the conversion.  
However, I am struggling to get information about the underlying type. For example, it is nice that the function checks that the type of elements of x and y are the same when called. And I also can use the T to initialize new vectors inside the function to the correct type.

However, not necessary the x, y might have the same units, in that case, Unitful will return an error. I can avoid the check, but then also initializing my\_array to something with different units from x and y is a nightmare.  
I have to do something like (if I want an array of seconds)

```julia
my_array = zeros(typeof(zero(eltype(ustrip(x))) * u"s"), 100)

```

Which is definitively horrible to read and understand.

Is there a proper way to manage the numeric type besides the units and easily create and manage arrays with Unitful?

---

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [September 8, 2024, 10:31pm UTC](https://discourse.julialang.org/t/unitful-and-generic-function-types/119198/2 "2024-09-08T22:31:43Z")

</div>

One option is to use `AbstractMatrix{T}` and `AbstractVector{R}` rather than using `T` for both. That way you can get the type without requiring the arguments have the same units.

Another option would be to convert both arguments to the same units before calling this function.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [September 9, 2024, 2:45am UTC](https://discourse.julialang.org/t/unitful-and-generic-function-types/119198/3 "2024-09-09T02:45:08Z")

</div>

> [@mesonepigreco](#):
>
> `typeof(zero(eltype(ustrip(x))) * u"s")`

It’s a little weird to me that `ustrip` doesn’t take the `Quantity` type as an input like `unit` can, so this would be what that would look like:

```julia
julia> extra_ustrip(::Type{Q}) where {T, Q<:Quantity{T}} = T
extra_ustrip (generic function with 1 method)

julia> extra_ustrip(typeof(1*u"s")) # replace input with `T` in your code
Int64

julia> extra_ustrip(typeof(1im*u"s"))
Complex{Int64}

```

But I don’t know how that would be multiplied with `u"s"`.

> [@mesonepigreco](#):
>
> not necessary the x, y might have the same units

You don’t provide much detail, so let’s say we write the results of `bar(x, y)` to `my_array`. For that to work, we need `eltype(my_array) == eltype(bar(x,y))`. This isn’t easy to deal with automatically; the output type of the first elementwise operation is not necessarily the same as the following ones, which is why the output type mechanisms for broadcasting are complex and stayed internal. The common practice is to pass the output `eltype` or the preallocated output array itself to `foo`, leaving another function to figure out the automatic output type mechanism for your own context or allowing you to manually provide the expected output type for `x` and `y`.

---

<div class="post-metadata">

**Author:** ![mesonepigreco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mesonepigreco/32/46262_2.png) [@mesonepigreco](https://discourse.julialang.org/u/mesonepigreco)\
**Post date:** [September 9, 2024, 5:50am UTC](https://discourse.julialang.org/t/unitful-and-generic-function-types/119198/4 "2024-09-09T05:50:15Z")

</div>

Thanks @Benny and @jar1  
Looking at your code, probably the solution is replacing my definition of foo into

```julia
function foo(x :: AbstractMatrix{T}, y :: AbstractVector{U}) where {V, T <: Quantity{V}, U <: Quantity{V}}
    unit_type = typeof(zero(V) * u"s")
    my_array = zeros(unit_type, 100)
    # other stuff
end

```

In this way, I am forcing the underlying float representation of input to be the same. I wonder if this function signature is generic enough to work with GPU arrays.
