# Creating a function that only takes specific units

**URL:** <https://discourse.julialang.org/t/creating-a-function-that-only-takes-specific-units/35108>\
**Category:** New to Julia\
**Tags:** functions, unitful\
**Created:** [February 25, 2020, 11:10am UTC](https://discourse.julialang.org/t/creating-a-function-that-only-takes-specific-units/35108 "2020-02-25T11:10:58Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![snowgum](https://avatars.discourse-cdn.com/v4/letter/s/ecc23a/32.png) [@snowgum](https://discourse.julialang.org/u/snowgum)\
**Post date:** [February 25, 2020, 11:10am UTC](https://discourse.julialang.org/t/creating-a-function-that-only-takes-specific-units/35108/1 "2020-02-25T11:10:58Z")

</div>

I’m new to Julia and currently trying to use Unitful.jl to create a function that only accepts arguments of a particular type of unit dimension, for example only length. Ideally, the type of the argument should be an array of AbstractFloat (or subtype) with any number of dimensions, and the only restriction is that the units should always be of a certain kind. Without this last restriction, I can already do it like this:

```julia
using Unitful

function test(a::Array{<:Quantity{<:AbstractFloat}})
    # something inside function
end

```

But I now would like to restrict the type of `a` to be of a unit of with a dimension of length (e.g. metres, km, nm, etc.). The following seems to work:

```julia
function test(a::typeof([1.0]u"m"))
    # something inside function
end

```

But this has several issues: it is now limited to 1D arrays, Float64, and it only takes units in metres (not km, or nm). Is there a way to write a type definition that will take an array of AbstractFloat, any dimension, and units of length?

I tried to build on the units of Unitful quantities, e.g:

```julia
julia> typeof(1.0u"m")
Quantity{Float64,𝐋,Unitful.FreeUnits{(m,),𝐋,nothing}}

```

Trying to copy paste and modifying that definition doesn’t work, e.g. I get an error `ERROR: UndefVarError: m not defined`. I get the feeling that there is probably a very simple way to get around this, but I couldn’t find it.

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [February 25, 2020, 11:39am UTC](https://discourse.julialang.org/t/creating-a-function-that-only-takes-specific-units/35108/2 "2020-02-25T11:39:14Z")

</div>

> **[GitHub - HolyLab/UnitAliases.jl: A convenient set of aliases for types from...](https://github.com/HolyLab/UnitAliases.jl)**
>
> A convenient set of aliases for types from Unitful.jl - GitHub - HolyLab/UnitAliases.jl: A convenient set of aliases for types from Unitful.jl

is an unregistered package that defines a bunch of convenience types: [https://github.com/HolyLab/UnitAliases.jl/blob/master/src/UnitAliases.jl](https://github.com/HolyLab/UnitAliases.jl/blob/master/src/UnitAliases.jl). If you find it useful perhaps we should integrate it into Unitful.

---

<div class="post-metadata">

**Author:** ![klaff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/klaff/32/7637_2.png) [@klaff](https://discourse.julialang.org/u/klaff)\
**Post date:** [February 25, 2020, 12:04pm UTC](https://discourse.julialang.org/t/creating-a-function-that-only-takes-specific-units/35108/3 "2020-02-25T12:04:07Z")

</div>

Are you wanting to force a DimensionError to happen earlier than it would naturally? It feels like you’re trying to ask the library to do static checking when it is really designed to do it dynamically.

But if that’s what you need, perhaps a broadcast addition with `0u"m"` would suffice?

---

<div class="post-metadata">

**Author:** ![snowgum](https://avatars.discourse-cdn.com/v4/letter/s/ecc23a/32.png) [@snowgum](https://discourse.julialang.org/u/snowgum)\
**Post date:** [February 25, 2020, 12:27pm UTC](https://discourse.julialang.org/t/creating-a-function-that-only-takes-specific-units/35108/4 "2020-02-25T12:27:18Z")

</div>

Thank you. I found it quite convenient, and looking inside `UnitAliases.jl` I also found what I was missing: a way to access that caligraphic 𝐋 that I could not copy paste. So now I can define the type for the argument in this way, and works as intended:

```julia
length = typeof(1.0u"m").parameters[2]

function test(a::Array{<:Quantity{<:AbstractFloat, length}})
    # something inside function
end

```

This would also work with `HasLengthUnits` from `UnitAliases.jl` (e.g. `a::Array{<:HasLengthUnits{<:AbstractFloat}`), but I don’t have enough experience to tell if one is better than the other.

---

<div class="post-metadata">

**Author:** ![snowgum](https://avatars.discourse-cdn.com/v4/letter/s/ecc23a/32.png) [@snowgum](https://discourse.julialang.org/u/snowgum)\
**Post date:** [February 25, 2020, 12:35pm UTC](https://discourse.julialang.org/t/creating-a-function-that-only-takes-specific-units/35108/5 "2020-02-25T12:35:16Z")

</div>

Yes. My goal was to force an error when the function is called, not an error that is called from inside the function. Maybe that is not a good thing. From the point of view of code clarity, I though it would be better if the function definition would be explicit on the type of units it expects for each argument. Perhaps it is also easier to hunt for bugs when the error happens just as the function is called, to avoid having to dig deeper inside the function (e.g. if the function passes the argument into another function, it will be one less hop to find the source of the problem).

It seems to me that a broadcast addition would impact performance, if the input is a large array.

I’m an astronomer and quite used to using `astropy.units`. Trying to learn how to use Unitful, it is possible that my way of looking into the problem is heavily biased by my experience with `astropy`.

---

<div class="post-metadata">

**Author:** ![kevinczimmerman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kevinczimmerman/32/13040_2.png) [@kevinczimmerman](https://discourse.julialang.org/u/kevinczimmerman)\
**Post date:** [February 25, 2020, 12:51pm UTC](https://discourse.julialang.org/t/creating-a-function-that-only-takes-specific-units/35108/6 "2020-02-25T12:51:44Z")

</div>

What about

```julia
using Unitful

function test(a::Array{<:Unitful.Length})
    # do something
end

```

---

<div class="post-metadata">

**Author:** ![snowgum](https://avatars.discourse-cdn.com/v4/letter/s/ecc23a/32.png) [@snowgum](https://discourse.julialang.org/u/snowgum)\
**Post date:** [February 25, 2020, 1:02pm UTC](https://discourse.julialang.org/t/creating-a-function-that-only-takes-specific-units/35108/7 "2020-02-25T13:02:10Z")

</div>

Thanks, that is really compact and what I was looking for! But how would that work for composite unit types, e.g. length / time? A naive approach of `Unitful.Length / Unitful.Time` does not work.

It works using `Quantity{<:AbstractFloat, unit_type}` where `unit_type` is one of e.g.:

- `typeof(1.0u"m").parameters[2] / typeof(1.0u"s").parameters[2]`
- `typeof(1.0u"m/s").parameters[2]`

So this is fine for my purposes, although not as clean.

---

<div class="post-metadata">

**Author:** ![kevinczimmerman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kevinczimmerman/32/13040_2.png) [@kevinczimmerman](https://discourse.julialang.org/u/kevinczimmerman)\
**Post date:** [February 25, 2020, 1:05pm UTC](https://discourse.julialang.org/t/creating-a-function-that-only-takes-specific-units/35108/8 "2020-02-25T13:05:36Z")

</div>

Well for that particular example you could use

```julia
<:Unitful.Velocity

```

Look [here](https://github.com/PainterQubits/Unitful.jl/blob/7526dc736e30118c171bd08e5b2b27b5e804f079/src/pkgdefaults.jl) for more dimensions.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [February 26, 2020, 12:08am UTC](https://discourse.julialang.org/t/creating-a-function-that-only-takes-specific-units/35108/9 "2020-02-26T00:08:48Z")

</div>

> [@snowgum](#):
>
> Yes. My goal was to force an error when the function is called, not an error that is called from inside the function. Maybe that is not a good thing.

That depends somewhat on your user. If you restrict the input types like you are doing, the user will get a `MethodError` if the units they are supplying are incorrect. If you instead check the units inside the function, you can provide a customized error message, like “this function requires the input arguments to have a length unit”. For experienced julia programmers, the former `MethodError` contains exactly this information, but for beginners it might be hard to parse.

Both errors will occur no runtime cost if implemented correctly.
