# Use unitful unit to a variable

**URL:** https://discourse.julialang.org/t/use-unitful-unit-to-a-variable/88002
**Category:** Specific Domains
**Tags:** unitful
**Created:** [September 29, 2022, 6:16pm UTC](https://discourse.julialang.org/t/use-unitful-unit-to-a-variable/88002 "2022-09-29T18:16:33Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![filchristou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filchristou/32/26760_2.png) [@filchristou](https://discourse.julialang.org/u/filchristou)
#### Post date: [September 29, 2022, 6:16pm UTC](https://discourse.julialang.org/t/use-unitful-unit-to-a-variable/88002/1 "2022-09-29T18:16:33Z")

</div>

How can I attach a unit to a variable ?

e.g.

```julia-repl
julia> using Unitful

julia> 25u"km" #works
25 km

julia> a = 25; # define a variable

julia> #would expect something like that or similar to work
julia> au = @u_str(a, "km")
ERROR: LoadError: MethodError: no method matching var"@u_str"(::LineNumberNode, ::Module, ::Symbol, ::String)
Closest candidates are:
  var"@u_str"(::LineNumberNode, ::Module, ::Any) at ~/.julia/packages/Unitful/ApCuY/src/user.jl:629
in expression starting at REPL[6]:1

```

For now I solve this with `eval`, but it doesn’t feel right:

```julia-repl
julia> au = eval(:a)u"km"
25 km

```

What’s the way to go here ?

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [September 29, 2022, 6:18pm UTC](https://discourse.julialang.org/t/use-unitful-unit-to-a-variable/88002/2 "2022-09-29T18:18:42Z")

</div>

```julia
julia> a = 25u"km"
25 km

julia> a
25 km

```

this?

Or this:

```julia
julia> b = 25 * oneunit(a)
25 km

```

In some sense, you cannot “attach” a unit to variable, because a variable with a unit is in some sense just a type of number. Is like if you could attach the property of being a `Complex{Float64}` to a `Float64`. You cannot, you have to create a new variable for that.

---

<div class="post-metadata">

### Author: ![filchristou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filchristou/32/26760_2.png) [@filchristou](https://discourse.julialang.org/u/filchristou)
#### Post date: [September 29, 2022, 6:36pm UTC](https://discourse.julialang.org/t/use-unitful-unit-to-a-variable/88002/3 "2022-09-29T18:36:48Z")

</div>

I want to take the value inside of a variable and attach it to a type.  
I don’t want to use a literal like `25` again.  
E.g., let’s say I derived programmatically a long `Int[]` array and I want to attach `u"km"` to it.  
Can I do it without `eval` ?

```julia-repl
julia> very_complex_func() = [1,2,3,4,5]
very_complex_func (generic function with 1 method)

julia> ar = very_complex_func();

julia> aru = eval(ar)u"km"
5-element Vector{Quantity{Int64, 𝐋, Unitful.FreeUnits{(km,), 𝐋, nothing}}}:
 1 km
 2 km
 3 km
 4 km
 5 km

```

> [@lmiq](#):
>
> In some sense, you cannot “attach” a unit to variable, because a variable with a unit is in some sense just a type of number. Is like if you could attach the property of being a `Complex{Float64}` to a `Float64`. You cannot, you have to create a new variable for that.

I don’t quite agree.  
I can initiate a `Complex` and a `Float64` with a variable and not always a literal is needed.  
Also I can “attach” a `Float64` value to a `Complex{Float64}` like the following:

```julia-repl
julia> num = 3;

julia> a = Float64(num);

julia> ac = Complex(a,a)
3.0 + 3.0im

```

Instead to initialize a `Unitful` type, it looks like I always need a literal.

---

<div class="post-metadata">

### Author: ![aramirezreyes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aramirezreyes/32/42573_2.png) [@aramirezreyes](https://discourse.julialang.org/u/aramirezreyes)
#### Post date: [September 29, 2022, 6:44pm UTC](https://discourse.julialang.org/t/use-unitful-unit-to-a-variable/88002/4 "2022-09-29T18:44:28Z")

</div>

You can multiply by the unit, for example. But I don’t know if this is what you don’t want to do.

```julia
julia> using Unitful
julia> a = [1, 2, 3]
julia> b = 1u"km".*a
3-element Vector{Quantity{Int64, 𝐋, Unitful.FreeUnits{(km,), 𝐋, nothing}}}:
 1 km
 2 km
 3 km

```

What you were trying to do with `@u_str` is also possible, but there is no need to introduce the `a` intro the macro call.

```julia
julia> a*@u_str("km")
3-element Vector{Quantity{Int64, 𝐋, Unitful.FreeUnits{(km,), 𝐋, nothing}}}:
 1 km
 2 km
 3 km

```

What happens is that the way of “attaching” a unit to a value, even in the example of a = 25u"km" is doing a product between `25` and the thing that comes back from `u"km"`

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [September 29, 2022, 6:44pm UTC](https://discourse.julialang.org/t/use-unitful-unit-to-a-variable/88002/5 "2022-09-29T18:44:32Z")

</div>

> [@filchristou](#):
>
> E.g., let’s say I derived programmatically a long `Int[]` array and I want to attach `u"km"` to it.  
> Can I do it without `eval` ?

I don´t know if `Unitful` has a specific function for that. But you cannot “attach” the units to such array, because the array is of immutable values, and the unitful values are a different type of animal.

Thus, you can do, for example:

```julia
julia> x = [1,2,3,4,5];

julia> x .* 1u"km"
5-element Vector{Quantity{Int64, 𝐋, Unitful.FreeUnits{(km,), 𝐋, nothing}}}:
 1 km
 2 km
 3 km
 4 km
 5 km

```

> [@filchristou](#):
>
> I can initiate a `Complex` and a `Float64` with a variable and not always a literal is needed.

I’m not sure if there is a `convert(...)` type of function in `Unitful` for doing that with another syntax. But anyway you need to define a new variable.

(I think that if the purpose is to propagate units that are attached to some input variable, the most useful pattern is something like:

```julia
julia> a = 1u"km"
1 km

julia> x = [1,2];

julia> y = x .* oneunit(a)
2-element Vector{Quantity{Int64, 𝐋, Unitful.FreeUnits{(km,), 𝐋, nothing}}}:
 1 km
 2 km

```

---

<div class="post-metadata">

### Author: ![filchristou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filchristou/32/26760_2.png) [@filchristou](https://discourse.julialang.org/u/filchristou)
#### Post date: [September 29, 2022, 6:53pm UTC](https://discourse.julialang.org/t/use-unitful-unit-to-a-variable/88002/6 "2022-09-29T18:53:08Z")

</div>

Yeah, the multiplication with `1u"km"` again works (probably better than the `eval`) but again it seems to me like a “hack”. Anyway, I better get used to it. 😃 Thanks!

---

<div class="post-metadata">

### Author: ![aramirezreyes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aramirezreyes/32/42573_2.png) [@aramirezreyes](https://discourse.julialang.org/u/aramirezreyes)
#### Post date: [September 29, 2022, 6:56pm UTC](https://discourse.julialang.org/t/use-unitful-unit-to-a-variable/88002/7 "2022-09-29T18:56:27Z")

</div>

It is not a hack, it is actually the usual way:

> [@aramirezreyes](#):
>
> What happens is that the way of “attaching” a unit to a value, even in the example of a = 25u"km" is doing a product between `25` and the thing that comes back from `u"km"`

You can see it with:

```julia
julia> @which 25u"km"
*(x::Number, y::Unitful.Units, z::Unitful.Units...) in Unitful at /Users/arreyes/.julia/packages/Unitful/ApCuY/src/quantities.jl:26

```

This actually calls the product of 25 and u"km". This product is defined at unitful. So it is not more esoteric than that.

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [September 29, 2022, 7:05pm UTC](https://discourse.julialang.org/t/use-unitful-unit-to-a-variable/88002/8 "2022-09-29T19:05:49Z")

</div>

> [@filchristou](#):
>
> but again it seems to me like a “hack”.

If you think in terms of actual units, it is not a hack, it is what actually make sense. A dimensionless quantity does not assume dimensions, but it may be multiplied by a quantity with dimensions, and the result has the dimensions of that quantity.

It is not that you can “fix” the fact that you forgot to write the units of a quantity, because the types are different. For instance, you cannot do this:

```julia
julia> x = [1, 2];

julia> x[1] = 1u"km"
ERROR: DimensionError: and km are not dimensionally compatible.

```

Because `x` is a container of unitless (`Int64`) numbers only.

You can, however, do this:

```julia
julia> x = [1.0, 2.0]u"km"
2-element Vector{Quantity{Float64, 𝐋, Unitful.FreeUnits{(km,), 𝐋, nothing}}}:
 1.0 km
 2.0 km

julia> x[1] = 1.0u"m"
1.0 m

julia> x
2-element Vector{Quantity{Float64, 𝐋, Unitful.FreeUnits{(km,), 𝐋, nothing}}}:
 0.001 km
   2.0 km

```

since how it makes sense to convert the meter to the km unit which the vector carries.

\*you could do this:

```julia
julia> x = Number[1.0, 2.0];

julia> x[1] = 1.0u"km"
1.0 km

julia> x
2-element Vector{Number}:
 1.0 km
      2.0

```

but that is only because that vector can contain anything that is a subtype of number, and there is no relation between the values before and after the mutation - and this is very bad for performance.
