Programming Languages – Defining New Limits for Simple Types

annotationsattributescjava

Many languages like C++, C#, and Java allow you to create objects that represent simple types like integer or float. Using a class interface you can override operators and perform logic like checking if a value exceeds a business rule of 100.

I'm wondering if it's possible in some languages to define these rules as annotations or attributes of a variable/property.

For example, in C# you might write:

[Range(0,100)]
public int Price { get; set; }

Or maybe in C++ you could write:

int(0,100) x = 0;

I've never seen something like this done, but given how dependent we have become on data validation before storage. It's strange that this feature hasn't been added to languages.

Can you give example of languages where this is possible?

Best Answer

Pascal had subrange types, i.e. decreasing the number of numbers that fit into a variable.

  TYPE name = val_min .. val_max;

Ada also has a notion of ranges: http://en.wikibooks.org/wiki/Ada_Programming/Types/range

From Wikipedia....

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

can also do

subtype Weekend is  Weekday (Saturday..Sunday);
subtype WorkDay is  Weekday (Monday..Friday);

And here's where it gets cool

year : Year_type := Year_type`First -- 1800 in this case...... 

C does not have a strict subrange type, but there are ways to mimic one (at least limited) by using bitfields to minimize the number of bits used. struct {int a : 10;} my_subrange_var;}. This can work as an upper bound for variable content (in general I would say: don't use bitfields for this, this is just to proof a point).

A lot of solutions for arbitrary-length integer types in other languages rather happen on the library-level, I.e. C++ allows for template based solutions.

There are languages that allow for monitoring of variable states and connecting assertions to it. For example in Clojurescript

(defn mytest 
   [new-val] 
   (and (< new-val 10)
        (<= 0 new-val)))

(def A (atom 0 :validator mytest))

The function mytest is called when a has changed (via reset! or swap!) checks whether conditions are met. This could be an example for implementing subrange behaviour in late-binding languages (see http://blog.fogus.me/2011/09/23/clojurescript-watchers-and-validators/ ).

Related Topic