Design by Contract Hinges on Implication

Design by Contract Hinges on Implication Featured Image

For some time, I’ve been trying to come up with better ways to explain the concept of design by contract. Rather than shooting for the best explanation, I figured I’d share a variety of explanations to appeal to a variety of folks. Today, we’re going to talk about design by contract in the context of boolean algebra, specifically implication. Let’s get to it!

Table of Contents

The Golden Rule of Design By Contract

If you’ve ever taken the time to tackle the concept of design by contract, you may learn that the entire premise can be boiled down to a single golden rule: if the precondition is true, then the postcondition can be assumed to be true.

The trouble with a statement like this is that it’s unclear what is expected to happen if the precondition is false. Taken in context, my students often assume that a false precondition means the code is guaranteed to crash. However, the reality is that we cannot assume anything will happen if the precondition is false. The code could crash, freeze, run forever, or even return a reasonable value. As a result, the only information we get from our golden rule is what is assumed to occur if the precondition is true.

Because I find this idea of uncertainty so difficult to convey to students, I thought I’d try my hand at explaining it through logic. Keep in mind that it has been ages since I’ve done any formal logic work, so my conceptual understanding could be off. But, these ideas really help me make sense of the golden rule.

Introducing the Idea of Implication

Whenever I first teach programming to someone, I really like to teach ideas related to boolean algebra. After all, those ideas translate almost directly into conditionals in programming. If you can grasp the ideas of AND, OR, and NOT, you have almost all of the tools you need to construct reasonable conditionals.

However, for most programmers, the ideas around boolean algebra usually stop there. Very rarely do we need to make use of ideas like NAND, NOR, and XOR (even if some of these are implied), and even more rarely do we need to know the various rules for simplifying and rewriting boolean expressions (e.g., De Morgan’s Law).

As a result, it’s no surprise that the ideas around implication are often not taught in programming courses. Ironically, implication plays really nicely into those concepts around conditionals. In fact, one way of thinking of implication is through the idea of if/then statements. If some statement (often called an antecedent) is true, then we expect the result (often called the consequence) to be true.

In design by contract, we take this idea of implication and make it our golden rule: if the precondition is true, then the postcondition can be assumed to be true. As a result, if this statement is not satisfied, we have failed design by contract. And this is shown through the truth table for implication:

PreconditionPostconditionPre -> Post (DbC)
TTT
TFF
FTT
FFT

Based on this table, design by contract is only violated if the client satisfies the precondition but the postcondition is false. Otherwise, the client is free to violate the precondition all day, and we guarantee nothing (i.e., the postcondition could be true or false, and design by contract would still be upheld).

Example Contract

To help make sense of this, here’s a method with a proper contract:

/**
 * Multiplies two numbers together. 
 *
 * @param a the first term
 * @param b the second term
 * @requires Integer.MIN_VALUE <= a * b <= Integer.MAX_VALUE
 * @ensures product = a * b
 * @return the product of two integers
 */
public static int product(int a, int b) {
  return a * b;
}

Under this contract, the user can provide any pair of integers as long as their product doesn’t exceed the maximum and minimum integers. Therefore, if the precondition is upheld, the user will get what they want. If for whatever reason, the user provides integers that exceed the range of int when combined, then we promise nothing. They could get the right answer or the wrong one. In this case, the product will wraparound, but we don’t guarantee that to the user.

At any rate, I doubt this will be the last time I talk about design by contract. Last year, I obsessed over recursion explanations, and it seems design by contract is the new focus. So, expect more of these types of discussions in the future.

In the meantime, why not check out my other discussions on design by contract (and recursion). It’s not a practice I use in my day-to-day life, but it’s a wonderful principle for thinking about the design of code:

With that said, I’m going to wrap it up for today. Thanks again for your time, and I look forward to sharing more content with you soon!

Coding Tangents (43 Articles)—Series Navigation

As a lifelong learner and aspiring teacher, I find that not all subjects carry the same weight. As a result, some topics can fall through the cracks due to time constraints or other commitments. Personally, I find these lost artifacts to be quite fun to discuss. That’s why I’ve decided to launch a whole series to do just that. Welcome to Coding Tangents, a collection of articles that tackle the edge case topics of software development.

In this series, I’ll be tackling topics that I feel many of my own students have been curious about but never really got the chance to explore. In many cases, these are subjects that I think deserve more exposure in the classroom. For instance, did you ever receive a formal explanation of access modifiers? How about package management? Version control?

In some cases, students are forced to learn these subjects on their own. Naturally, this forms a breeding ground for misconceptions which are made popular in online forums like Stack Overflow and Reddit. With this series, I’m hoping to get back to the basics where these subjects can be tackled in their entirety.

Jeremy Grifski

Jeremy grew up in a small town where he enjoyed playing soccer and video games, practicing taekwondo, and trading Pokémon cards. Once out of the nest, he pursued a Bachelors in Computer Engineering with a minor in Game Design. After college, he spent about two years writing software for a major engineering company. Then, he earned a master's in Computer Science and Engineering. Today, he pursues a PhD in Engineering Education in order to ultimately land a teaching gig. In his spare time, Jeremy enjoys spending time with his wife and kid, playing Overwatch 2, Lethal Company, and Baldur's Gate 3, reading manga, watching Penguins hockey, and traveling the world.

Recent Posts