[GSoC Proposal] Statically Checked Measurement Units

Cristi Cobzarenco cristi.cobzarenco at gmail.com
Mon Mar 28 08:43:32 PDT 2011


First, let me apologize for this very late entry, it's the end of university
and it's been a very busy period, I hope you will still consider it.

Note this email is best read using a fixed font.

PS: I'm really sorry if this is the wrong mailing list to post and I hope
you'll forgive me if that's the case.

======= Google Summer of Code Proposal: Statically Checked Units =======


Abstract
-------------

Measurement units allow to statically check the correctness of assignments
and expressions at virtually no performance cost and very little extra
effort. When it comes to physics the advantages are obvious – if you try to
assign a force a variable measuring distance, you've most certainly got a
formula wrong somewhere along the way. Also, showing a sensor measurement in
gallons on a litre display that keeps track of the remaining fuel of a plane
(a big no-no) is easily avoidable with this technique. What this translates
is that one more of the many hidden assumptions in source code is made
visible: units naturally complement other contract checking techniques, like
assertions, invariants and the like. After all the unit that a value is
measured in is part of the contract.

The scope of measurement units is not limited to physics calculations
however and if the feature is properly implemented and is very easy to use,
creating a very domain-specific units helps a great deal with checking
correct code at compile time. Static typing doesn't cut it sometimes:
imagine    two variables counting different things – Gadgets and Widgets.
While both values should be ints, one of them should probably not be
assignable to the other. Or imagine a website calculating the number of
downloads per second, but uses a timer that counts milliseconds. When one
thinks about it this way, there are a great many cases where units can help
prevent common errors.

Given D's focus on contract based design and language features supporting
it, I think statically checked measurement units fit very naturally into the
standard library, and the language's metaprogramming features would make it
very clean to implement (as opposed to a similar effort in C++). I think a
system that is closer to the one in F# would be a better idea than the one
provided by Boost.Units:
1. Defining unit systems, like Boost.Units requires is extra effort, so
units for counting Widgets or Gadgets would be awkward to use and we would
lose the safety checks there.
2. Defining dimensions is not strictly necessary, and F# does well without
them.
3. The sort of silent conversion that Boost.Units performs is undesirable in
many cases since it is a recipe for precision disasters, imagine sometimes
accidentally assigning a variable measured in billions of years to a one
measured in picoseconds. Boost.Units would silently convert one to another,
since they measure the same dimension. This probably results into the value
being set to +INF and even if it doesn't, very rarely one actually intends
to perform this conversion.
4. Setting numerical ids to units and dimensions is cumbersome. S

Thus, the requirements for the unit system would be:
1. One line definition of new units.
2. Simple, yet safe and explicit conversion between units.
3. Zero runtime overhead.
4. Minimal extra coding effort to use units.


Interface Overview
---------------------------
A Boost type approach to the library interface would be:

struct Metre     : SomeUnitBaseType!(...) {}
struct Second    : SomeUnitBaseType!(...) {}

typedef DerivedUnit!(MetreType,1,Second,-1) MetresPerSecond;
typedef DerivedUnit!(MetreType,2)           MetersSquared;

Meter           metre, metres;
Second          second, seconds;
MetersPerSecond metersPerSecond;
MetersSquared   meterSquared, metersSquared;

void f() {
Quantity!(metre)           dist1 = 3.0 * metres;
Quantity!(meterSquared)    area  = dist1 * dist1;
Quantity!(metresPerSecond) speed = distance / (2.0*seconds);
}


This is very cumbersome and fails on the one line requirement. I propose
using types for base units and mixins to define derived units. One can use
the typenames of the units in arithmetic operations this way:

struct metre  {}
struct second {}


void f() {
Quantity!("metre")        dist1 = quantity!(3.0, "metre");
Quantity!("metre^2")      area  = dist1 * dist1;
Quantity!("metre/second") speed = dist1 / quantity!(2.0, "second");
}


Conversion between units can be done specifying a single factor with a
proper unit:

template conversion( alias unit : "kilometer/meter" ) {
immutable Quantity!(unit) conversion = quantity!(123.0,unit);
}

void f() {
Quantity!("metre")     d1 = quantity!(123.0,"metre");
 // convert calls conversion! with the right argument
Quantity!("kilometre") d2 = convert!(d1,"kilometre");
}

Also, notice this approach imposes no restriction to the types that define
units, therefore our Widget/Gadget counters could be defined without any
extra work:

class Widget { /* complicated class definition */ }
class Gadget { /* complicated class definition */ }

Quantity!("Widget",int) nWidgets;
Quantity!("Gadget",int) nGadgets;


About Me
------------
I am an undergraduate student at the University of Edinburgh in Scotland
doing a degree in Computer Science and Artificial Intelligence, originally
from Romania where I finished a specialised Computer Science high school
(Colegiul National de Informatica "Tudor Vianu").
My first language is C++ which I started learning when I was 9 and as a
result I have a very good understanding of template metaprogramming. I also
know Haskell and Python well which helps me draw from multiple paradigms
when designing as system. I started learning D about a year ago and I
instantly fell in love with it. The fact that it does away with all the
annoying C backwards compatibility, improves on the features that make C++
unique (the template system, performance, low level memory access etc.) and
adds modern language features (garbage collection, lambda functions etc.)
makes me very optimistic about the project.
In terms of working experience, other than a myriad of personal projects, I
did work for my former high school for a summer, implementing an automated
testing system, and last year I was lead a team that won a software
development competition organised by our computing society. This year I took
part in the Scottish Game Jam where my team ended up in 8th place.


-- 
(Cristi Cobzarenco)
Pofile: http://www.google.com/profiles/cristi.cobzarenco
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20110328/95c5ba5c/attachment-0001.html>


More information about the Digitalmars-d mailing list