# How To Properly Use Unitful

**URL:** https://discourse.julialang.org/t/how-to-properly-use-unitful/40295
**Category:** General Usage
**Tags:** question, unitful
**Created:** [May 27, 2020, 10:24pm UTC](https://discourse.julialang.org/t/how-to-properly-use-unitful/40295 "2020-05-27T22:24:24Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![acdupont](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/acdupont/32/15223_2.png) [@acdupont](https://discourse.julialang.org/u/acdupont)
#### Post date: [May 27, 2020, 10:24pm UTC](https://discourse.julialang.org/t/how-to-properly-use-unitful/40295/1 "2020-05-27T22:24:24Z")

</div>

I’m using Unitful for the first time and would like direction on the proper way to use it. For my use case, I am creating a struct that I would like to store a specific unit because the value is being passed to such things as xml file creation and cli programs as only a number. I’d like conversion of the to happen at construction, rather than having to do something like `uconvert(u"output-unit", someQuantity)` every place the raw number has to be passed to the external applications.

In my first implementation that works, I had a struct similar to the following:

```julia
struct MyStruct 
	value::typeof(1.0u"cm^-3")
end

```

I thought this was too restricting because I may want to allow `Int` or something for the quantity, so I changed my struct to the following:

```julia
struct MyStruct 
	value::Unitful.Quantity{<:Real, Unitful.𝐋^-3, u"cm^-3"}
end

```

But when I try to construct an instance, I get the following error:

```julia
ERROR: MethodError: no method matching Quantity{#s92495,𝐋^-3,cm^-3} where #s92495<:Real(::Quantity{Int64,𝐋^-3,Unitful.FreeUnits{(cm^-3,),𝐋^-3,nothing}})

```

To experiment with different types, I discovered the following

```julia
julia> typeof(1.0u"cm^-3")
Quantity{Float64,𝐋^-3,Unitful.FreeUnits{(cm^-3,),𝐋^-3,nothing}}

julia> typeof(1.0u"cm^-3") <: typeof(1.0u"cm^-3")
true

julia> typeof(1.0u"cm^-3") <: Unitful.Quantity{Float64, Unitful.𝐋^-3,Unitful.FreeUnits{( Unitful.cm^-3,), Unitful.𝐋^-3,nothing}}
false

```

That is a surprising result that I don’t understand.

Which leads me to why I asking a question. What is the proper way to force a specific `Unit` in the struct or a function signature? Also, what is best practice? I would normally expect to use something like `Quantity{<:Real, 𝐋^-3}`, but for my specific case it seems safer to force the Unit as well to avoid having to remember do `uconvert` with the correct type everywhere when I am interfacing with external applications.

---

<div class="post-metadata">

### Author: ![briochemc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/briochemc/32/4209_2.png) [@briochemc](https://discourse.julialang.org/u/briochemc)
#### Post date: [May 28, 2020, 3:13am UTC](https://discourse.julialang.org/t/how-to-properly-use-unitful/40295/2 "2020-05-28T03:13:36Z")

</div>

I’m not sure it’s helpful, but I think you should not worry about the unit in `struct`s, unless I’m missing something. So I would just go with

```julia
struct MyStruct{T}
	value::T
end

```

Also, I don’t see why using a struct removes the necessity to do `uconvert`. Maybe you can clarify that?

Side notes:  
Visually, I personally prefer to use the pipe for conversions, e.g., `3u"m" |> u"cm"` will give `300u"cm"`. I also like that you can strip the unit and convert at the same time, e.g., `ustrip(u"cm", 3u"m")` will give `300`.

---

<div class="post-metadata">

### Author: ![acdupont](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/acdupont/32/15223_2.png) [@acdupont](https://discourse.julialang.org/u/acdupont)
#### Post date: [May 28, 2020, 3:28pm UTC](https://discourse.julialang.org/t/how-to-properly-use-unitful/40295/3 "2020-05-28T15:28:37Z")

</div>

The idea of the struct is I can use the value stored in the struct directly and know it is the correct unit for use with external applications I am interfacing with (the struct is used for other stuff too, not just storing the Quantity). There are lines of code like the following that use the numeric value in the filename:

```julia
outputpath = joinpath(directory, "data$(mystruct.value.val).txt")

```

which probably would need a `unconvert` call if I don’t know the units in mystruct:

```julia
outputpath = joinpath(directory, "data$(uconvert(u"m", mystruct.value).val).txt")

```

The value is used as data inside xml files and as cli parameter to other applications too though. So I’m trying to avoid having to call `uconvert` to be sure of the unit.

The code needs to be refactored because I can put the logic in a function and do the conversion in the function, then the unit in MyStruct won’t matter. So there are better ways, but I am still curious how to force units with the function signature.

---

<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: [May 28, 2020, 5:17pm UTC](https://discourse.julialang.org/t/how-to-properly-use-unitful/40295/4 "2020-05-28T17:17:29Z")

</div>

```julia
julia> using Unitful

julia> struct MyStruct{L<:Unitful.Length}
           x::L
       end

julia> MyStruct(3.0u"mm")
MyStruct{Quantity{Float64,𝐋,Unitful.FreeUnits{(mm,),𝐋,nothing}}}(3.0 mm)

julia> MyStruct(3u"km")
MyStruct{Quantity{Int64,𝐋,Unitful.FreeUnits{(km,),𝐋,nothing}}}(3 km)

julia> MyStruct(3u"s")
ERROR: MethodError: no method matching MyStruct(::Quantity{Int64,𝐓,Unitful.FreeUnits{(s,),𝐓,nothing}})
Closest candidates are:
...

```

You can either use [Unitful’s defaults](https://github.com/PainterQubits/Unitful.jl/blob/3d494ad85248aaff160d7df3a4cf75c0803ed5f5/src/pkgdefaults.jl) or define your own:

```julia
@derived_dimension PerVol inv(Unitful.𝐋^3)

```

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [May 28, 2020, 5:43pm UTC](https://discourse.julialang.org/t/how-to-properly-use-unitful/40295/5 "2020-05-28T17:43:09Z")

</div>

The OP specifically said

> [@acdupont](#):
>
> I would normally expect to use something like `Quantity{<:Real, 𝐋^-3}` , but for my specific case it seems safer to force the Unit as well to avoid having to remember do `uconvert` with the correct type everywhere when I am interfacing with external applications.

so it seems they want to constrain the struct to only hold something with units of inverse centimeters cubed. They don’t want to allow inverse kilometers cubed or whatever.

What I find surprising is this part:

```julia
julia> using Unitful

julia> typeof(1.0u"cm^-3")
Quantity{Float64,𝐋^-3,Unitful.FreeUnits{(cm^-3,),𝐋^-3,nothing}}

julia> Unitful.Quantity{Float64, Unitful.𝐋^-3,Unitful.FreeUnits{( Unitful.cm^-3,), Unitful.𝐋^-3,nothing}}
Quantity{Float64,𝐋^-3,Unitful.FreeUnits{(cm^-3,),𝐋^-3,nothing}}

julia> typeof(1.0u"cm^-3") == Unitful.Quantity{Float64, Unitful.𝐋^-3,Unitful.FreeUnits{( Unitful.cm^-3,), Unitful.𝐋^-3,nothing}}
false

julia> typeof(1.0u"cm^-3") <: Unitful.Quantity{Float64, Unitful.𝐋^-3,Unitful.FreeUnits{( Unitful.cm^-3,), Unitful.𝐋^-3,nothing}}
false

```

I can’t spot a single difference between the second and third input yet they are apparently not the same type. Seems like a bug to me, but maybe I’m missing something.

---

<div class="post-metadata">

### Author: ![acdupont](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/acdupont/32/15223_2.png) [@acdupont](https://discourse.julialang.org/u/acdupont)
#### Post date: [May 28, 2020, 5:58pm UTC](https://discourse.julialang.org/t/how-to-properly-use-unitful/40295/6 "2020-05-28T17:58:29Z")

</div>

@Mason, yup, that is exactly correct. And your findings are what have me puzzled as well.

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [May 28, 2020, 6:17pm UTC](https://discourse.julialang.org/t/how-to-properly-use-unitful/40295/7 "2020-05-28T18:17:30Z")

</div>

I would suggest opening and issue in Unitful.jl regarding those types and asking why they’re not the same.

---

<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: [May 28, 2020, 6:29pm UTC](https://discourse.julialang.org/t/how-to-properly-use-unitful/40295/8 "2020-05-28T18:29:25Z")

</div>

Continuing @tim.holy 's example, you could still force the unit on creation with an [inner constructor](https://docs.julialang.org/en/v1/manual/constructors/#man-inner-constructor-methods-1) if I understand correctly

```julia
using Unitful

@derived_dimension PerVol inv(Unitful.𝐋^3)

struct MyStruct{T <: PerVol}
    x::T
    function MyStruct(x::T) where {T <: PerVol}
        y = uconvert(u"cm^-3", x)
        new{eltype(y)}(y)
    end
end

```

```julia
julia> MyStruct(1u"mm^-3")
MyStruct{Quantity{Int64,�^-3,Unitful.FreeUnits{(cm^-3,),�^-3,nothing}}}(1000 cm^-3)

```

---

<div class="post-metadata">

### Author: ![acdupont](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/acdupont/32/15223_2.png) [@acdupont](https://discourse.julialang.org/u/acdupont)
#### Post date: [May 28, 2020, 7:30pm UTC](https://discourse.julialang.org/t/how-to-properly-use-unitful/40295/9 "2020-05-28T19:30:21Z")

</div>

@Mason, I will open an issue. @kevinczimmerman, I didn’t think to use an inner constructor, I will try that as a work around. It would be nice to know why the function signature is not working though, or if that can’t be done at all for some reason.

---

<div class="post-metadata">

### Author: ![acdupont](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/acdupont/32/15223_2.png) [@acdupont](https://discourse.julialang.org/u/acdupont)
#### Post date: [May 28, 2020, 7:42pm UTC](https://discourse.julialang.org/t/how-to-properly-use-unitful/40295/10 "2020-05-28T19:42:19Z")

</div>

I opened an issue about the typeof weirdness:  
[https://github.com/PainterQubits/Unitful.jl/issues/339](https://github.com/PainterQubits/Unitful.jl/issues/339)

---

<div class="post-metadata">

### Author: ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)
#### Post date: [May 28, 2020, 8:07pm UTC](https://discourse.julialang.org/t/how-to-properly-use-unitful/40295/11 "2020-05-28T20:07:43Z")

</div>

I didn’t get to the bottom of this, but Unitful does have all sorts of `show` methods for these types, which might be hiding things:

```julia
julia> @which show(stdout, typeof(1.0u"cm^-3"))
show(io::IO, x::Type{T}) where T<:Quantity in Unitful at /Users/me/.julia/packages/Unitful/9XsxK/src/display.jl:81

```

---

<div class="post-metadata">

### Author: ![ajkeller34](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ajkeller34/32/4416_2.png) [@ajkeller34](https://discourse.julialang.org/u/ajkeller34)
#### Post date: [June 15, 2020, 4:57am UTC](https://discourse.julialang.org/t/how-to-properly-use-unitful/40295/12 "2020-06-15T04:57:04Z")

</div>

Late to the thread, but fyi, there’s something sneaky being done here to keep Unitful types from being exceedingly long when printed, which is something people have disliked in the past. The `cm^-3` inside the type signature is actually this:

```julia
julia> Unitful.Unit{:Meter, u"𝐋"}(-2,-3)
cm⁻³

```

The `Unitful.Unit` type is never manipulated by the user and is for internal use only. Having Unitful types show in a succinct way that still yields enough information to construct the type at the REPL has proven challenging. I think a step in the right direction would be to at least distinguish the two `cm` objects by having the internal one display differently, to avoid pulling a fast one on everyone. Sorry for that.

If you find yourself wanting to manipulate Unitful types directly, there’s almost always a better way. I would follow Tim’s advice here. You could consider restricting to `cm^-3` in the constructor if desired, though I’m not sure why you would need to do that.

---

<div class="post-metadata">

### Author: ![jlawrie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlawrie/32/26283_2.png) [@jlawrie](https://discourse.julialang.org/u/jlawrie)
#### Post date: [August 19, 2022, 10:37am UTC](https://discourse.julialang.org/t/how-to-properly-use-unitful/40295/13 "2022-08-19T10:37:41Z")

</div>

Hello;

just to say that this puzzles me greatly as well. I’m a novice, but if I happen to discover anything relevant I will post an update.

Cheers!

P.S. I don’t know if it is considered ‘good practice’ to bump old threads like this (when they are still open) - if it is not please let me know and I will refrain in the future.

---

<div class="post-metadata">

### Author: ![emmt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/emmt/32/5192_2.png) [@emmt](https://discourse.julialang.org/u/emmt)
#### Post date: [October 31, 2023, 2:58pm UTC](https://discourse.julialang.org/t/how-to-properly-use-unitful/40295/14 "2023-10-31T14:58:36Z")

</div>

I ran into the same issue. Below I describe how I inverstigated the problem and fixed the type definition (spoiler: solution is at the end).

```julia
julia> using Unitful

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

```

OK so let us define type `b` (a supposed alias for type `a`) as (note that you need the `Unitful.` prefix unless you import symbols `m` and `𝐋`, a bold L, from `Unitful`):

```julia
julia> b = Quantity{Float64, Unitful.𝐋, Unitful.FreeUnits{(Unitful.m,), Unitful.𝐋, nothing}}
Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}

```

`a` and `b` are printed exactly the same however they are different as shown by:

```julia
julia> a == b
false

```

Exactly what was observed by @acdupont at the start of this discussion.

Since `a` and `b` are parametric types, let us find out which of their parameters is/are different by introspection:

```julia
julia> a.parameters .== b.parameters
3-element BitVector:
 1
 1
 0

```

So the culprit is the 3rd one, a `Unitful.FreeUnits` structure, we use the same trick as above to compare its parameters:

```julia
julia> a.parameters[3].parameters .== b.parameters[3].parameters
3-element BitVector:
 0
 1
 1

```

So, the 1st parameter is now the one which is different. However:

```julia
julia> a.parameters[3].parameters[1]
(m,)

julia> b.parameters[3].parameters[1]
(m,)

```

which (wrongly) seems to indicate that both are 1-tuple with single element `m`. Let us check the type of the element:

```julia
julia> typeof(a.parameters[3].parameters[1][1])
Unitful.Unit{:Meter, 𝐋}

julia> typeof(b.parameters[3].parameters[1][1])
Unitful.FreeUnits{(m,), 𝐋, nothing}

```

Hooray, we finally found a difference!

Unrolling all this, the correct definition for `b` is:

```julia
julia> b = Quantity{Float64, Unitful.𝐋, Unitful.FreeUnits{(Unitful.Unit{:Meter,Unitful.𝐋}(0,1//1),), Unitful.𝐋, nothing}}
Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}

```

Let us check this:

```julia
julia> a == b
true

julia> a === b
true

```

To give a practical example that can be used to define precisely the type of a field in a structure (the original need), we can define the following type alias:

```julia
const Meters{T<:Real} = Quantity{T, Unitful.𝐋, Unitful.FreeUnits{(Unitful.Unit{:Meter,Unitful.𝐋}(0,1//1),), Unitful.𝐋, nothing}}

```

and check that:

```julia
julia> typeof(1.0u"m") === Meters{Float64}
true

julia> typeof(1u"m") === Meters{Int}
true

julia> convert(Meters{Float32}, 2.3u"mm")
0.0023f0 m

```
