Thread overview | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
October 06, 2008 Units of Measure in F# | ||||
---|---|---|---|---|
| ||||
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 Re: Units of Measure in F# | ||||
---|---|---|---|---|
| ||||
Posted in reply to 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! |
October 06, 2008 Re: Units of Measure in F# | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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 Re: Units of Measure in F# | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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 Re: Units of Measure in F# | ||||
---|---|---|---|---|
| ||||
Posted in reply to Denis Koroskin | 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 Re: Units of Measure in F# | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | Hmm... do we want to add pressure to energy density? |
October 07, 2008 Re: Units of Measure in F# | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | 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 Re: Units of Measure in F# | ||||
---|---|---|---|---|
| ||||
Posted in reply to 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) |
October 07, 2008 Re: Units of Measure in F# | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | 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 Re: Units of Measure in F# | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | 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;
|
Copyright © 1999-2021 by the D Language Foundation