Jump to page: 1 2
Thread overview
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
October 06, 2008
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
October 06, 2008
"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!


October 06, 2008
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..)
{
  Unit!(stuff) opAdd(T)(T t) {...}
}

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)


October 06, 2008
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.
October 07, 2008
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


October 07, 2008
Hmm... do we want to add pressure to energy density?
October 07, 2008
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
October 07, 2008
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)


October 07, 2008
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
October 07, 2008
On Tue, 07 Oct 2008 22:39:10 +0400, BCS <ao@pathlink.com> wrote:

> 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)
>
>

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..$]);
    }
}

template AddPowers(Unit, Units...)
{
    // 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