Contract programming or Design by contract (DbC) is a programming approach that focuses more on enforcing and documenting certain conditions and operations within a program. These conditions are often defined with the help of assertions or logical statements that must hold true for specific points of the code execution. It enhances reliability by validating function behavior, improves maintainability by serving as self-documentation, and facilitates collaboration.
In the context of the D programming language, contract programming is an inbuilt feature designed to provide a solid way of defining and enforcing a specific condition and invariant of the code. Contracts help us maintain our code. In D programming, three types of contracts can be used, which are defined as follows:
Precondition contract: These conditions should be true before a function is executed.
Postcondition contract: These conditions should be true after a function is executed.
Invariant contract: These conditions should be true regardless of the state of the code.
Let’s familiarize ourselves with the contract coding implementation in the upcoming section.
In this section, we’ll explore the syntax of the contract types and how to implement them in our code.
Here we go with the precondition contract syntax:
void funcName(arg) in {// Write the precondition code here} body {// Function body}
In the syntax section, in
represents the beginning of the precondition contract block, where we will define the conditions that must be satisfied before the function execution.
Now it is time to understand the syntax of postcondition contract syntax:
void funcName(arg) out {// Write the postcondition code here} body {// Function body}
In the syntax section, out
represents the beginning of the postcondition contract block, where we will define the conditions that must be satisfied after the function execution.
Lastly, Here we go with the invariant contract syntax:
class ExampleClass {// Class members and methods go hereinvariant {// Code for the invariant contract here}}
To define an invariant contract, we use the invariant keyword within our coding class or struct, which should be satisfied at all stages of the code execution.
Now that we understand the coding implementation, let’s enhance our knowledge with a coding example.
Let’s explore a coding example where we’ll implement all the contracts:
import std.stdio;class Calculator {int a;int b;invariant {assert(a >= 0, "a should not be less than 0");assert(b >= 0, "b should not be less than 0");}int add(int a, int b) in {assert(a >= 0, "a should not be less than 0");assert(b >= 0, "b should not be less than 0");} out {assert(__result >= 0, "Result should not be less than 0");assert(__result == a + b, "Result should match the sum of a and b");} body {this.a = a;this.b = b;return a + b;}int subtract(int a, int b) in {assert(a >= 0, "a should not be less than 0");assert(b >= 0, "b should not be less than 0");assert(a >= b, "a should not be less than b");} out {assert(__result >= 0, "Result should not be less than 0");assert(__result == a - b, "Result should match the subtraction of b from a");} body {this.a = a;this.b = b;return a - b;}}void main() {Calculator calculator = new Calculator();int sum = calculator.add(5, 3);writeln("5 + 3 = ", sum);int difference = calculator.subtract(10, 4);writeln("10 - 4 = ", difference);// Uncomment the line below to see a precondition violation// int invalidResponse = calculator.add(-3, 3);}
Note: To test whether contracts are working or not, please uncomment the code at line 48.
Line 3: We define a Calculator
class, which will have methods for addition and subtraction.
Lines 7–10: We define an invariant
contract block to ensure that these variables are always non-negative. The invariant block checks that a
and b
are not less than 0 every time an operation is performed.
Lines 12–22: We define a add
method in which we implemented the precondition contract at line 12 with the help of in
keyword, which will check whether a
and b
are greater than or equal to 0. We also define a postcondition at line 15 with the help of out
keyword, which will check whether sum
of a
and b
are greater than or equal to 0.
Lines 24–36: We define a subtract
, the method by which we implemented the same processes that we did in the add
method but for subtraction.
Free Resources