Last active
August 29, 2015 14:17
-
-
Save glesica/ccb86f4d5ad3eb076d58 to your computer and use it in GitHub Desktop.
Rudimentary implementation of units of measure in Julia.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Base.show, Base.convert | |
abstract Unit | |
abstract ScalarUnit <: Unit | |
abstract CompoundUnit <: Unit | |
abstract LinearUnit <: ScalarUnit | |
macro defunit(name::Symbol, parent::Symbol) | |
quote | |
immutable $name <: $parent | |
value::Float64 | |
end | |
$(esc(name))(x::Unit) = convert($name, x) | |
end | |
end | |
macro defbase(name::Symbol, parent::Symbol) | |
quote | |
$(esc(:baseunit)){T <: $parent}(::Type{T}) = $name | |
end | |
end | |
macro defconv(left::Symbol, right::Symbol, ltor::Expr, rtol::Expr) | |
quote | |
function $(esc(:convert))(::Type{$right}, a::$left) | |
local x = a.value | |
$right($ltor) | |
end | |
function $(esc(:convert))(::Type{$left}, a::$right) | |
local x = a.value | |
$left($rtol) | |
end | |
end | |
end | |
@defunit Cm LinearUnit | |
@defbase Cm LinearUnit | |
@defunit In LinearUnit | |
@defconv In Cm (x * 2.54) (x / 2.54) | |
@defunit Ft LinearUnit | |
@defconv Ft Cm (x * 30.48) (x / 30.48) | |
convert{T <: Unit}(::Type{T}, x::T) = x | |
convert{T <: Unit, J <: Unit}(::Type{T}, x::J) = convert(T, convert(baseunit(J), x)) | |
baseunit{T <: Unit}(::Type{T}) = error("No base unit defined for $(T)") | |
show{T <: Unit}(io::IO, x::T) = print(io, "$(x.value)$(lowercase(string(typeof(x))))") | |
*{T <: Unit}(x::Real, ::Type{T}) = T(x) | |
+{T <: Unit}(a::T, b::T) = (a.value + b.value) * T | |
-{T <: Unit}(a::T, b::T) = (a.value - b.value) * T | |
*{T <: Unit}(a::T, b::Real) = (a.value * b) * T | |
*{T <: Unit}(a::Real, b::T) = b * a | |
/{T <: Unit}(a::T, b::Real) = (a.value / b) * T | |
/{T <: Unit}(a::Real, b::T) = b * a | |
# Testing... | |
a = 2.0Cm | |
b = 2.0In | |
c = 2.0Ft | |
println("a = ", a) | |
println("b = ", b) | |
println("\nArithmetic...") | |
println("a + a = ", a + a) | |
println("a * 2 = ", a * 2) | |
println("2 * a = ", 2 * a) | |
println("\nFancy conversions...") | |
println("a -> In: ", a |> In) | |
println("a -> Cm: ", a |> Cm) | |
println("b -> Cm: ", b |> Cm) | |
println("c -> In: ", c |> In) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment