View mode: basic / threaded / horizontal-split · Log in · Help
September 24, 2012
Neat: UFCS for integer dot operator suffix
I tried this, and found it neat that it works:

----
import std.traits;

@property @safe pure nothrow
{
    T Mile(T)(T i)
        if (isNumeric!T)
    {
        return i*1609.44;
    }

    T Ki(T)(T i)
        if (isNumeric!T)
    {
        return i*1024;
    }

    T m(T)(T i)
        if (isNumeric!T)
    {
        return i/1000;
    }
}

void main()
{
    auto medication = 60.m;
    int[32.Ki] buffer;
    auto parisToBerlib = 544.93.Mile;
}

----

It is not homogenous (eg, Km vs Kg vs Kv), but it makes writing 
unit-less sizes pretty easy.

This has probably been discovered before, but it is new to me.

Of course, nothing that can't be done with a simple multiply, but 
I found there is something more... "special"... to doing it with 
dot.
September 24, 2012
Re: Neat: UFCS for integer dot operator suffix
monarch_dodra:

> I tried this, and found it neat that it works:

Lately I was thinking about this topic (because of a program that 
mixes many doubles that are instead different types).

// F#
let gravityOnEarth = 9.81<m/s^2>
let heightOfMyOfficeWindow = 3.5<m>
let speedOfImpact = sqrt(2.0 * gravityOnEarth * 
heightOfMyOfficeWindow)


So is this a good syntax for an hypothetical Phobos library?

Acceleration gravityOnEarth = Units!"m/s^2"(9.81);
alias Units U;
auto heightOfMyOfficeWindow = U!`m`(3.5);
alias U!"g" grams; // a @property
auto sugarAmount1 = Grams(10.5);
auto sugarAmount2 = 10.5.Grams;
Length dist1 = 3.U!"cm";
auto dist2 = 2.U!q{cm^1};
alias U!"cm^2" cm2;
assert(dist1 * dist2 == 6.cm2);
mixin NewUnit!"degrees";
auto myAngularSpeed = 90.U!"degrees/s";

Bye,
bearophile
September 24, 2012
Re: Neat: UFCS for integer dot operator suffix
On Mon, Sep 24, 2012 at 2:28 PM, bearophile <bearophileHUGS@lycos.com> wrote:
> monarch_dodra:
>
>
>> I tried this, and found it neat that it works:

I used this in a small unit library (partially accessible on github),
to obtain code like:

auto distance = 100.km;
auto speed = 130.km/h; // division works, too.

auto timeToDestination = (distance/speed).hour; // distance/speed
gives seconds => transformed in hours.

It was a nice exercise in using UFCS and mixins to create your own
unit library (not only IS, but ay kind of unit library).

And, you know what? I *never* used it after coding it. These examples
are cute, they make for nice blog posts for F#, but the real-world
usage is dubious to me (I know they were space-programs crashes)

I quite like the implicit message in units: use the type system to
help you catch errors are compile-time. Add to that a nice syntax and
a showcase for D's generational capabilities and it's quite nice.

But, to my eyes, it's but a toy.
September 24, 2012
Re: Neat: UFCS for integer dot operator suffix
Philippe Sigaud:

> But, to my eyes, it's but a toy.

There are features (like tuples) that I use all the time in other
languages (and in D too), so I know they are useful for me. I
have not used units in normal languages (only a little in Frink:
http://futureboy.us/frinkdocs/ ), so I don't know for sure they
are useful for me :-)

On the other hand both in D and other languages I feel the need
for strongly typing single values (like typedef in D1). For me
telling apart differently typed double values or array types is
handy for documentation and improve code readability (and for
this a D alias is enough), and the type system enforcement makes
me more relaxed while I write code, because I know the compiler
catches more mistakes.

Bye,
bearophile
September 24, 2012
Re: Neat: UFCS for integer dot operator suffix
On 9/24/12 9:36 AM, Philippe Sigaud wrote:
> On Mon, Sep 24, 2012 at 2:28 PM, bearophile<bearophileHUGS@lycos.com>  wrote:
>> monarch_dodra:
>>
>>
>>> I tried this, and found it neat that it works:
>
> I used this in a small unit library (partially accessible on github),
> to obtain code like:
>
> auto distance = 100.km;
> auto speed = 130.km/h; // division works, too.
>
> auto timeToDestination = (distance/speed).hour; // distance/speed
> gives seconds =>  transformed in hours.
>
> It was a nice exercise in using UFCS and mixins to create your own
> unit library (not only IS, but ay kind of unit library).
>
> And, you know what? I *never* used it after coding it. These examples
> are cute, they make for nice blog posts for F#, but the real-world
> usage is dubious to me (I know they were space-programs crashes)
>
> I quite like the implicit message in units: use the type system to
> help you catch errors are compile-time. Add to that a nice syntax and
> a showcase for D's generational capabilities and it's quite nice.
>
> But, to my eyes, it's but a toy.

I wouldn't read too much into it. You're a library author, not (I 
assume) a scientific computing guy. So beyond playing with a few 
examples, your work on this library is done - you wouldn't be a client 
of it for the simple reason you don't intensively work with kilometers, 
speeds, dollars, and such. It's possible that a good and usable library 
of units could add value to a category of users.


Andrei
September 24, 2012
Re: Neat: UFCS for integer dot operator suffix
>> I used this in a small unit library (partially accessible on 
>> github),
>> to obtain code like:
>>
>> auto distance = 100.km;
>> auto speed = 130.km/h; // division works, too.
>>
>> auto timeToDestination = (distance/speed).hour; // 
>> distance/speed
>> gives seconds =>  transformed in hours.
>>
>> It was a nice exercise in using UFCS and mixins to create your 
>> own
>> unit library (not only IS, but ay kind of unit library).
>>
>> And, you know what? I *never* used it after coding it. These 
>> examples
>> are cute, they make for nice blog posts for F#, but the 
>> real-world
>> usage is dubious to me (I know they were space-programs 
>> crashes)
>>
>> I quite like the implicit message in units: use the type 
>> system to
>> help you catch errors are compile-time. Add to that a nice 
>> syntax and
>> a showcase for D's generational capabilities and it's quite 
>> nice.
>>
>> But, to my eyes, it's but a toy.
>
> I wouldn't read too much into it. You're a library author, not 
> (I assume) a scientific computing guy. So beyond playing with a 
> few examples, your work on this library is done - you wouldn't 
> be a client of it for the simple reason you don't intensively 
> work with kilometers, speeds, dollars, and such. It's possible 
> that a good and usable library of units could add value to a 
> category of users.

IMO, you don't need to be a scientific computing guy to find unit 
checking useful, since almost any number conceptually has a unit 
on it. I would ask any programmer, how often do you accidentally 
use a measurement of 'bytes' where 'dwords' were expected, or use 
a variable as an array index when it was actually something 
totally different?

However, unit checking cannot be done satisfactorially in a 
library; it has two main problems when provided that way:
1. It's too bulky (too much syntax required, as units have to be 
spelled out constantly)
2. Values with traditionally-typed units don't interoperate with 
existing libraries, including very simple functions such as

int abs(int x) { return x > 0 ? x : -x; }
int square(int x) { return x*x; }

You can define an inplicit conversion from e.g. 'Unit!"pixels"' 
to 'int' but then you'll need to manually cast it back, and the 
compiler can't check your cast to make sure it's correct.

IMO, solving these two problems requires a parallel type system 
to infer unit relationships automatically, either with direct 
language support, or a separate analysis tool that uses the 
compiler as a service (currently not possible with D).
September 24, 2012
Re: Neat: UFCS for integer dot operator suffix
On Monday, 24 September 2012 at 17:47:33 UTC, David Piepgrass 
wrote:
> However, unit checking cannot be done satisfactorially in a 
> library; it has two main problems when provided that way:
> 1. It's too bulky (too much syntax required, as units have to 
> be spelled out constantly)
> 2. Values with traditionally-typed units don't interoperate 
> with existing libraries, including very simple functions such as
>
> int abs(int x) { return x > 0 ? x : -x; }
> int square(int x) { return x*x; }
>
> You can define an inplicit conversion from e.g. 'Unit!"pixels"' 
> to 'int' but then you'll need to manually cast it back, and the 
> compiler can't check your cast to make sure it's correct.
>
> IMO, solving these two problems requires a parallel type system 
> to infer unit relationships automatically, either with direct 
> language support, or a separate analysis tool that uses the 
> compiler as a service (currently not possible with D).

+1

You can partially solve the function arg/return value problem by 
making those functions templates but:

(a) This doesn't help you with existing functions (e.g. trig 
function in std.math)
(b) It stops those functions from being virtual.
(c) Generally makes the functions more difficult to work with (no 
common type, horrible compilation errors)
Top | Discussion index | About this forum | D home