Skip to content

Instantly share code, notes, and snippets.

@jasononeil
Last active November 10, 2016 11:16
Show Gist options
  • Save jasononeil/b6b1845824f45f5d19df to your computer and use it in GitHub Desktop.
Save jasononeil/b6b1845824f45f5d19df to your computer and use it in GitHub Desktop.
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();
})();
@larsiusprime
Copy link

Should this line: https://gist.github.com/jasononeil/b6b1845824f45f5d19df#file-metric-hx-L40

@: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
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment