Wednesday, July 23, 2008

D 2.0 Rocks!

Probably not as much as you think, but this just tickles me pink. I rewrote a simple factorial program I had written to use Design by Contract and Pure functions. So, what does this mean?

First, Design by Contract allows me to check the input and output values to ensure that they're correct. In the case of the factorial function below, I check to see if the input and output values are both greater than zero. It's kind-of pointless for the output, but it didn't hurt to put the check in.

Second, a Pure function is one that behaves in a functional manner. In other words, no side effects. You pass data in and you get a return value. You can't use global or static variables. I think this was originally done for threading, but I like it because you can make functions safer all around. Think about it, no worrying about the function changing a global variable somewhere accidentally. These are restricted to a degree in that pure functions can only call pure functions, but you can use "non-pure" code inside of a pure function, such as a for loop. This way you get the niceties, if not the best, of both worlds.

Below is the code. Enjoy.


import std.stdio; // Module for console IO.

pure long calcFac (invariant int value)
in
{
assert(value > 0, "Input value is not greater than 0.");
}
out (result)
{
assert(result > 0, "Return value is not greater than 0.");
}
body
{
long retval = 1;
int i;

for (i = 1; i <= value; i++)
{
retval *= i;
}
return retval;
}

int main(char[][] args)
{
try
{
writefln("Result: %d",calcFac(4));
writefln("Result: %d",calcFac(0));
}
catch (Exception e)
{
writefln("Caught: %s\n", e.msg);
}

return 0;
}


Yes, it is a bit wordy for a simple factorial, but this one the first idea I had to try this out with and I think it's a good one.

Labels: , ,

0 Comments:

Post a Comment

Links to this post:

Create a Link

<< Home