Search
Units of Measure in F#
Oct 06, 2008
bearophile
Oct 06, 2008
Nick Sabalausky
Oct 06, 2008
BCS
Oct 06, 2008
Denis Koroskin
Oct 07, 2008
BCS
Oct 07, 2008
bearophile
Oct 07, 2008
BCS
Oct 07, 2008
bearophile
Oct 07, 2008
BCS
Oct 07, 2008
Denis Koroskin
Oct 07, 2008
ore-sama
Oct 09, 2008
Walter Bright
Oct 09, 2008
BCS
Oct 09, 2008
Denis Koroskin
Oct 09, 2008
BCS
```I have found this interesting old thread, I don't know how much those things are true today too: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=36939

Beside allowing algebraic data types, that are quite useful, a functional-like type system allows to implement Units of Measure in a nice way:
http://blogs.msdn.com/andrewkennedy/archive/2008/08/20/units-of-measure-in-f-part-one-introducing-units.aspx

For people that don't remember what algebraic data types are: http://en.wikipedia.org/wiki/Algebraic_data_type

This power also allows to use pattern matching, absent in Python, present in Haskell, Ocaml, Scala, etc.

Bye,
bearophile
```
```"bearophile" <bearophileHUGS@lycos.com> wrote in message news:gcdt5p\$10t0\$1@digitalmars.com...
>I have found this interesting old thread, I don't know how much those things are true today too:
> http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=36939
>
> Beside allowing algebraic data types, that are quite useful, a
> functional-like type system allows to implement Units of Measure in a nice
> way:
> http://blogs.msdn.com/andrewkennedy/archive/2008/08/20/units-of-measure-in-f-part-one-introducing-units.aspx
>
> For people that don't remember what algebraic data types are: http://en.wikipedia.org/wiki/Algebraic_data_type
>
> This power also allows to use pattern matching, absent in Python, present in Haskell, Ocaml, Scala, etc.
>
> Bye,
> bearophile

That's awesome. I want it!

```
```Reply to bearophile,

> I have found this interesting old thread, I don't know how much those
> things are true today too:
> http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmar
> s.D&article_id=36939
>
> Beside allowing algebraic data types, that are quite useful, a
> functional-like type system allows to implement Units of Measure in a
> nice way:
>
> http://blogs.msdn.com/andrewkennedy/archive/2008/08/20/units-of-measur
> e-in-f-part-one-introducing-units.aspx
>
> For people that don't remember what algebraic data types are:
> http://en.wikipedia.org/wiki/Algebraic_data_type
>
> This power also allows to use pattern matching, absent in Python,
> present in Haskell, Ocaml, Scala, etc.
>
> Bye,
> bearophile

I think it is fully doable right now. I've considered doing it off and on for some time. I even figured out how to make it do rational powers for the dimensions.

The only thing I would want is to be able to avoid needing to wrap everything by way of operator overloads on typedefs

typedef real Unit(..stuff..)
{
}

and some way to re-type functions

alias sqrt Unit!(stuff/2) sqrt(Unit!(stuff));  // if sqrt called with Unit!(stuff), return type is Unit!(stuff/2)

```
```On Tue, 07 Oct 2008 00:41:29 +0400, bearophile <bearophileHUGS@lycos.com> wrote:

> I have found this interesting old thread, I don't know how much those things are true today too:
> http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=36939
>
> Beside allowing algebraic data types, that are quite useful, a functional-like type system allows to implement Units of Measure in a nice way:
> http://blogs.msdn.com/andrewkennedy/archive/2008/08/20/units-of-measure-in-f-part-one-introducing-units.aspx
>
> For people that don't remember what algebraic data types are:
> http://en.wikipedia.org/wiki/Algebraic_data_type
>
> This power also allows to use pattern matching, absent in Python, present in Haskell, Ocaml, Scala, etc.
>
> Bye,
> bearophile

Arghh! I've almost done the trick with D templates and then I got this:
Assertion failure: 'i < parameters->dim' on line 784 in file 'template.c'

DMD is not ready for my funky templates yet! :)

I'll post my results (and a bug report) soon.
```
```Reply to Denis,

> On Tue, 07 Oct 2008 00:41:29 +0400, bearophile
> <bearophileHUGS@lycos.com>  wrote:
>
>> I have found this interesting old thread, I don't know how much those
>> things are true today too:
>> http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalma
>> rs.D&article_id=36939
>>
>> Beside allowing algebraic data types, that are quite useful, a
>>
>> functional-like type system allows to implement Units of Measure in a
>>
>> nice way:
>>
>> http://blogs.msdn.com/andrewkennedy/archive/2008/08/20/units-of-measu
>> re-in-f-part-one-introducing-units.aspx
>>
>> For people that don't remember what algebraic data types are:
>> http://en.wikipedia.org/wiki/Algebraic_data_type
>>
>> This power also allows to use pattern matching, absent in Python,
>> present in Haskell, Ocaml, Scala, etc.
>>
>> Bye,
>> bearophile
> Arghh! I've almost done the trick with D templates and then I got
> this: Assertion failure: 'i < parameters->dim' on line 784 in file
> 'template.c'
>
> DMD is not ready for my funky templates yet! :)
>
> I'll post my results (and a bug report) soon.
>

svn.dsource.org  seems to be having problmes or I'd post a system I just put together.

total code, WS comments: ~ 400 LOC
supports 44 different units,
support +,-,* and / as well as pow and root

```
```Hmm... do we want to add pressure to energy density?
```
```BCS:
> svn.dsource.org  seems to be having problmes or I'd post a system I just
> put together.
> total code, WS comments: ~ 400 LOC
> supports 44 different units,
> support +,-,* and / as well as pow and root

A lot of work. Does is use a (syntax) strategy similar to this? http://www.boost.org/doc/libs/1_36_0/doc/html/boost_units.html

Now D just needs a pow infix operator (** ?) and that's done :-)

Bye,
bearophile
```
```Reply to bearophile,

> BCS:
>
>> svn.dsource.org  seems to be having problmes or I'd post a system I
>> just
>> put together.
>> total code, WS comments: ~ 400 LOC
>> supports 44 different units,
>> support +,-,* and / as well as pow and root
> A lot of work. Does is use a (syntax) strategy similar to this?
> http://www.boost.org/doc/libs/1_36_0/doc/html/boost_units.html
>
> Now D just needs a pow infix operator (** ?) and that's done :-)
>
> Bye,
> bearophile

SVN is working again (or I'm somewhere it works from)

http://www.dsource.org/projects/scrapple/browser/trunk/units/

take a look at si.d first as it's the most useful intro (look way down at the bottom)

```
```BCS:
> take a look at si.d first as it's the most useful intro (look way down at the bottom)

I think there's a need of some syntactic sugar :-)

Bye,
bearophile
```
```On Tue, 07 Oct 2008 22:39:10 +0400, BCS <ao@pathlink.com> wrote:

>
>> BCS:
>>
>>> svn.dsource.org  seems to be having problmes or I'd post a system I
>>> just
>>> put together.
>>> total code, WS comments: ~ 400 LOC
>>> supports 44 different units,
>>> support +,-,* and / as well as pow and root
>> A lot of work. Does is use a (syntax) strategy similar to this?
>> http://www.boost.org/doc/libs/1_36_0/doc/html/boost_units.html
>>  Now D just needs a pow infix operator (** ?) and that's done :-)
>>  Bye,
>> bearophile
>
> SVN is working again (or I'm somewhere it works from)
>
> http://www.dsource.org/projects/scrapple/browser/trunk/units/
>
> take a look at si.d first as it's the most useful intro (look way down at the bottom)
>
>

Well, I have done it completely different. Here is my (simplified) class hierarchy from memory:

// Unit is 's', 'kg', 'n' etc, i.e. they are basic orthogonal units
class Unit(string name)
{
enum AsString = name;
}

// A Powered Unit :) PUnit is s^2, kg^(-3.14) etc.
// It is
class PUnit(Unit, float power)
{
alias UnitType Unit;
enum Power = power;
}

// Quantity consists of a unique set of PUnits and a value. It also
// defines a set of operations like opMul, opDiv, opAdd and opSub
// Example: 5 m/s^2
class Quantity(U...)
{
alias Units U;

private float value;

// here is how my opMul looks like:
Multiply!(Units, OtherUnits) opMul(OtherUnits)(OtherUnits other)
{
Multiply!(Units, OtherUnits) result = void;
result.value = value * other.value;
return result;
}
}

here is how I merge Units for multiplication:

template GetUnitPower(Unit, Units...)
{
static if (Units.length == 0) {
enum GetUnitPower = 0;
} else static if (is (Units[0].UnitType == Unit)) {
enum GetUnitPower = Units[0].Power;
} else {
enum GetUnitPower = GetUnitPower!(Unit, Units[1..\$]);
}
}

{
// GetUnitPower returns 0 if there is no such Unit in Units
// put '-' for Divide! here
enum Power = Unit.Power + GetUnitPower!(Unit.UnitType, Units);

// get all the Units without Unit
alias Without!(Unit.UnitType, Units) Rest;

// Add the Unit with a new Power to the list of rest units
alias Tuple!(PUnit!(Unit.UnitType, Power), Rest) Result;
}

As a result you can have any arbitrary amount of orthogonal Units. Add them with a single line:

mixin(defineUnit("Time", "s"));
mixin(defineUnit("Mass", "kg"));
mixin(defineUnit("Distance", "m"));
mixin(defineUnit("Speed", "m/s"));

Distance d = 6 * m;
Time t = 3 * s;
Speed s = d / t;
```
« First   ‹ Prev
1 2