Instantly share code, notes, and snippets.

# jasononeil/Metric.hx Last active Nov 10, 2016

Demonstration of using Haxe abstracts to take care of explicit conversions between different units of measurement, with no performance overhead.
 class Metric { static function main() { var coinRadius:Millimeters = 12; var myHeight:Centimeters = 180; var raceLength:Meters = 200; var commuteDistance:Kilometers = 23; diff( coinRadius, myHeight ); // 1.788 meters diff( raceLength, commuteDistance ); // 22800 meters sum( commuteDistance, coinRadius ); // 23000.012 meters } static function diff( a:Meters, b:Meters ) { var d = Math.abs( a-b ); trace( '\$d meters' ); } static function sum( a:Meters, b:Meters ) { var s = Math.abs( a+b ); trace( '\$s meters' ); } } abstract Millimeters( Float ) from Float to Float { @:to function toCentimeters():Centimeters return this/10; @:to function toMeters():Meters return this/1000; @:to function toKilometers():Kilometers return this/1000000; @:op(A+B) function add(rhs:Float):Float return this+rhs; @:op(A-B) function sub(rhs:Float):Float return this-rhs; @:op(A-B) function multiply(rhs:Float):Float return this*rhs; @:op(A-B) function divide(rhs:Float):Float return this/rhs; } abstract Centimeters(Float) from Float to Float { @:to function toMillimeters():Millimeters return this*10; @:to function toMeters():Meters return this/100; @:to function toKilometers():Kilometers return this/100000; @:op(A+B) function add(rhs:Float):Float return this+rhs; @:op(A-B) function sub(rhs:Float):Float return this-rhs; @:op(A-B) function multiply(rhs:Float):Float return this*rhs; @:op(A-B) function divide(rhs:Float):Float return this/rhs; } abstract Meters( Float ) from Float to Float { @:to function toMillimeters():Millimeters return this*1000; @:to function toCentimeters():Centimeters return this*100; @:to function toKilometers():Kilometers return this/1000; @:op(A+B) function add(rhs:Float):Float return this+rhs; @:op(A-B) function sub(rhs:Float):Float return this-rhs; @:op(A-B) function multiply(rhs:Float):Float return this*rhs; @:op(A-B) function divide(rhs:Float):Float return this/rhs; } abstract Kilometers( Float ) from Float to Float { @:to function toMillimeters():Millimeters return this*1000000; @:to function toCentimeters():Centimeters return this*100000; @:to function toMeters():Meters return this*1000; @:op(A+B) function add(rhs:Float):Float return this+rhs; @:op(A-B) function sub(rhs:Float):Float return this-rhs; @:op(A-B) function multiply(rhs:Float):Float return this*rhs; @:op(A-B) function divide(rhs:Float):Float return this/rhs; }
 (function () { "use strict"; var Metric = function() { }; Metric.main = function() { var coinRadius = 12; var myHeight = 180; var raceLength = 200; var commuteDistance = 23; Metric.diff(coinRadius / 1000,myHeight / 100); Metric.diff(raceLength,commuteDistance * 1000); Metric.sum(commuteDistance * 1000,coinRadius / 1000); }; Metric.diff = function(a,b) { var d = Math.abs(a - b); console.log("" + d + " meters"); }; Metric.sum = function(a,b) { var s = Math.abs(a + b); console.log("" + s + " meters"); }; Metric.main(); })();
Owner Author

### jasononeil commented Aug 25, 2014

 I wrote this as an example for a Hacker News comment - it shows how "Abstract Types" in Haxe can be used to deal with units of measurement, providing inline, implicit conversion and keeping you from getting your units mixed up. The best part is, it wraps an ordinary Float, and when you compile, that's all it is. Take a look at how clean the Javascript output is. It would be great to see a more comprehensive library that deals with many units of measurement (distance, volume, time, speed and more) and provides clean conversion between them.

### larsiusprime commented Aug 25, 2014

 ``````@:op(A-B) function multiply(rhs:Float):Float return this*rhs; `````` instead be: ``````@:op(A*B) function multiply(rhs:Float):Float return this*rhs; `````` Or am I missing something?

### ibilon commented Aug 26, 2014

 @larsiusprime I think so too, same for `@:op(A/B) function divide(rhs:Float):Float return this/rhs;` @jasononeil I've started working on one: https://github.com/ibilon/units