Kelvin: Typesafe Dimensional Analysis

I’ve managed to apply my learnings from throwing together ChronoFlare and generalize it further to enable a typesafe dimensional analysis library. It turns out you can (ab)use IntLiteral to very nicely encode dimensional information into the type system. Allowing you to not only bring type safety to your API, but also represent arbitrary dimensions. Couple that with Mojo’s powerful compile time programming, and users can easily add custom units to their codebase with a single alias

# Quantity.D is the `Dimensions` of the type
alias kg = Kilogram.D
alias m = Meter.D
alias s = Second.D
alias Newton = Quantity[kg * m * (s ** -2)]
print(Newton(100)) # 100.0 m^1 kg^1 s^-2
print(Newton(10) + Newton(30)) # 40.0 m^1 kg^1 s^-2

alias MetersPerSecond = Quantity[m / s]
# Length / Time produces MetersPerSecond
var mps: MetersPerSecond = Meter(20) / Second(10)

I am still very much in the process of polishing this to make it better and more useful, but I wanted to share it in case anyone who might have use for it has any feedback, or design input.

Also special thanks to @owenhilyard for pointing me towards the uom Rust library as it this is heavily inspired by that work, and @martinvuyk for already taking the time to contribute!

8 Likes

Quick teaser, with some new experimental changes that introduce the ability to encode the scale of your units into each dimension you can do things like this now.

    alias speed_of_light = MetersPerSecond(299792458.0)
    print(MilesPerHour(cast_from=speed_of_light)) # 670616629.3843951 mile^1 h^-1
1 Like