Why I chose D over Ada and Eiffel
Timon Gehr
timon.gehr at gmx.ch
Thu Aug 29 16:35:16 PDT 2013
On 08/29/2013 09:17 PM, bearophile wrote:
> Piotr Szturmaj:
>
>> These are refinement types (I call them 'views') and I have
>> half-written DIP for this. However, I doubt that it will be accepted.
>
> I'll be quite interested by such DIP. Even if your DIP will be refused,
> it could still produce several useful consequences.
Why not build something rather general?
struct Hour{
int hour;
IsTrue[0 <= hour && hour <= 23] proof;
}
@terminating @correct pure nothrow @safe{ // additional attributes
// allow the compiler to erase proofs at run time in a modular fashion
// to maintain efficiency.
alias IsTrue[bool a] = Prop[a === true];
// (selection of intrinsic facts about built-in operators)
IsTrue[a && b] conj[bool a,bool b](IsTrue[a] x, IsTrue[b] y);
IsTrue[a] projA[bool a,bool b](IsTrue[a && b] ab);
IsTrue[b] projB[bool a,bool b](IsTrue[a && b] ab);
IsTrue[a <= c] letrans[int a,int b,int c]
(IsTrue[a <= b] aleb, IsTrue[b <= c] blec);
}
struct WorkingHour{
int hour;
IsTrue[0 <= hour && hour <= 12] proof;
@correct // meaning does not throw an error or segfault
Hour toHour()out(r){assert(r.hour==hour);}body{// compile-time check
return Hour(hour,
// an explicit proof that the hour is actually in range
conj(projA(proof),
letrans(projB(proof), IsTrue[12 <= 23].init))
);
}
alias toHour this;
}
(Maybe there is a better choice for the syntax.)
The basic idea is to extend the type system slightly such that the
compiler becomes able to type check proofs talking about program
behaviour. A flow analysis ensures that proofs are properly updated.
It would then become possible to build arbitrary refinement types:
bool isPrime(int x){ return iota(3,x).all!(a=>!!(x%a)); }
struct Prime{
int prime;
IsTrue[isPrime(prime)] proof;
}
Prime seven = Prime(7,IsTrue[isPrime(7)].init); // proof by CTFE
assert(isPrime(x));
auto foo = Prime(x,IsTrue[isPrime(x)].init); // proof by runtime check
and flow analysis
auto bar = Prime(y,IsTrue[isPrime(y)].init); // error, disabled @this
This could also be used without runtime overhead eg. inside a
correctness proof for a prime sieve, though this necessitates a slightly
larger apparatus than presented here.
More information about the Digitalmars-d
mailing list