Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ada-like types in Nimrod

Tags:

d

ada

nim-lang

today I did ask in D mailing list whether it's possible to define and use custom data types in a way similar to e.g. example from Ada's wiki page:

type Day_type   is range    1 ..   31;
type Month_type is range    1 ..   12;
type Year_type  is range 1800 .. 2100;
type Hours is mod 24;
type Weekday is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday); 


type Date is
   record
     Day   : Day_type;
     Month : Month_type;
     Year  : Year_type;
   end record;

subtype Working_Hours is Hours range 0 .. 12;
subtype Working_Day is Weekday range Monday .. Friday;
Work_Load: constant array(Working_Day) of Working_Hours 
   := (Friday => 6, Monday => 4, others => 10); 

and the reply demonstrated something like:

import std.typecons;
import std.exception;

struct Limited(T, T lower, T upper)
{
    T _t;
    mixin Proxy!_t; //Limited acts as T (almost)
    invariant()
    {
        enforce(_t >= lower && _t <= upper);
    }
    this(T t)
    {
        _t = t;
    }
}

auto limited(T, T lower, T upper)(T init = T.init)
{
    return Limited!(T, lower, upper)(init);
}

unittest
{
    enum l = [-4,9];
    auto a = limited!(int, l[0], l[1])();
    foreach(i; l[0] .. l[1]+1)
    {
        a = i;
    }

    assertThrown({a = -5;}());
    assertThrown({a = 10;}());
}

which shows it's possible, but probably misses Ada's elegance.

Now, after reading about Nimrod recently, I wonder how it can handle similar task with the provision to ensure same Ada's type-safety?

like image 972
gour Avatar asked Aug 29 '13 15:08

gour


1 Answers

Nimrod support these rather directly:

type
  Day = range[1..31]
  Month = range[1..12]

  WeekDay = enum
    Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday

  WorkingDays = range[Monday..Friday]
  WorkingHours = range[0..12]

  WorkSchedule = array[WorkingDays, WorkingHours]

Errors are enforced either at compile-time:

var x: Day
x = 40 # conversion from int literal(40) to Day is invalid

.. or at run-time

var x: Day
var y = unknownInt() # let's say it returns 100

x = y # unhandled exception: value 100 out of range [EOutOfRange]

Furthermore, distinct types can be used if even stronger type safety is required.

like image 98
zah Avatar answered Oct 01 '22 23:10

zah