# Tangent: Measurement infrastructure

I had some time tonight to work on Tangent. On the menu? Infrastructure for unit of measurement types (as the clever folks might've guessed by the title). Under the hood, a

Type operators already exist for the usual suspects. They need to be extended to be aware of the new subtype (did I mention this was a little awkward?). The equality and subclassing operators actually didn't need to be modified; since measure types are goose types, that works itself out. Same with tupling, and intersection. Bind and select (to bind a generic param, and select a method from a group respectively) don't really apply. Union (inheritance) is a TODO [eventually, you'll be able to inherit from classes without data fields]. So umm, not much work needed here.

But measures need a few more operators. Type operators to construct new types from the existing types. The three here are multiplication, division, and exponentiation. They have 2 key jobs. First is to do the math on the exponents of the

So, for those who followed last post's link or know of the F# implementation, this is going to be a little different. Instead of

So, the night's test code:

Eventually I aim to get aliases into measure definitions, probably with certain names marked as singular/plural/abbreviation to generate better names, and to give the option of a terse 'abbreviation-style' name.

`Measure`inherits (awkwardly) from`Type`. It adds a list of`UnitOfMeasure`, a comparator, and a few util methods for now. A`UnitOfMeasure`contains a`Measure`and an exponent (in numerator/denominator form rather than float).Type operators already exist for the usual suspects. They need to be extended to be aware of the new subtype (did I mention this was a little awkward?). The equality and subclassing operators actually didn't need to be modified; since measure types are goose types, that works itself out. Same with tupling, and intersection. Bind and select (to bind a generic param, and select a method from a group respectively) don't really apply. Union (inheritance) is a TODO [eventually, you'll be able to inherit from classes without data fields]. So umm, not much work needed here.

But measures need a few more operators. Type operators to construct new types from the existing types. The three here are multiplication, division, and exponentiation. They have 2 key jobs. First is to do the math on the exponents of the

`Measure`s. The second is to do the type fiddling with the 'value' of the measure.`int of meters/int of seconds`should yield`float of (m/s)`for example. To do this, the operators will look at the implemented multiply and division methods for the numeric types and use that type for the determination. That might run into problems, but should be an okay way to keep the things generic enough for user numeric types.So, for those who followed last post's link or know of the F# implementation, this is going to be a little different. Instead of

`float`,`meters`will default to`float`(or more accurately be declared as`measure` meters{} ) so the*use*of the measure will be a little less verbose/more focused. Of course a different type might be generated... say meters with a`complex`unit type if its manipulated that way. In general though, I want the programmer to be able to use what numeric they need; not annoy them with conversions or accommodations just to get measure safety.So, the night's test code:

Measure Meters = Measure.Create("Meters");

Measure Seconds = Measure.Create("Seconds");

Listmps = new List ();

mps.Add(new UnitOfMeasure(Meters, 1));

mps.Add(new UnitOfMeasure(Seconds, -1));

Measure V = Measure.Create(mps);

Console.WriteLine("[m,s^-1] name: {0}",V.Name);

Measure v2 = Tangent.Lang.Type.PerOperator(Meters, Seconds) as Measure;

Console.WriteLine("m/s -> {0}", v2.Name);

Measure a = Tangent.Lang.Type.PerOperator(v2, Seconds) as Measure;

Console.WriteLine("mps/s -> {0}", a.Name);

Measure a2 = Tangent.Lang.Type.PerOperator(Meters, Tangent.Lang.Type.ExponentiationOperator(Seconds, 2,1)) as Measure;

Console.WriteLine("m/(s^2) -> {0}", a2.Name);

Measure m = Tangent.Lang.Type.MultiplyOperator(v2, Seconds) as Measure;

Console.WriteLine("mps * s -> {0}", m.Name);

[m,s^-1] name: Meters per Seconds

m/s -> Meters per Seconds

mps/s -> Meters per Seconds^2

m/(s^2) -> Meters per Seconds^2

mps * s -> Meters

Eventually I aim to get aliases into measure definitions, probably with certain names marked as singular/plural/abbreviation to generate better names, and to give the option of a terse 'abbreviation-style' name.

0

Sign in to follow this

Followers
0

## 6 Comments

## Recommended Comments

## Create an account or sign in to comment

You need to be a member in order to leave a comment

## Create an account

Sign up for a new account in our community. It's easy!

Register a new account## Sign in

Already have an account? Sign in here.

Sign In Now