How to have strongly typed numerical values?

Ali Çehreli acehreli at yahoo.com
Tue Sep 4 21:25:09 PDT 2012


On 09/04/2012 08:11 PM, ixid wrote:
 > Using this:
 >
 > struct Grams
 > {
 > size_t amount;
 > }
 >
 > @property Grams grams(size_t amount)
 > {
 > return Grams(amount);
 > }
 >
 > void main()
 > {
 > auto weight = 5.grams;
 > weight = weight + 10.grams;
 > }
 >
 > How would you use it? I thought the point of this sort of strong typing
 > was to be able to carry out arithmetic using your type that other units
 > cannot accidentally be mixed with.

I have not used such frameworks myself but have seen them mentioned a 
number of times. I think the type above should have been Weight, not Grams.

The idea is to build the relationships between types and allow only 
those operations. For example, the following program defines dividing 
Distance by Time to produce Speed:

import std.stdio;
import std.string;

struct Distance
{
     double amount;

     Speed opBinary(string op)(in Time time) const
         if (op == "/")
     {
         return Speed(this.amount / time.amount);
     }
}

@property Distance meters(double amount)
{
     return Distance(amount);
}

struct Time
{
     double amount;
}

@property Time seconds(double amount)
{
     return Time(amount);
}

struct Speed
{
     double amount;

     string toString() const
     {
         return format("%s m/s", amount);
     }
}

void main()
{
     auto distance = (10.5).meters;
     auto time = (2.5).seconds;
     auto speed = distance / time;

     writeln(speed);
}

The parentheses around the floating point literals are not necessary. I 
thought this reads better.

Ali



More information about the Digitalmars-d-learn mailing list