Thread overview
Design by Contract - out old struct member value
August 06

Lets say we have the member function incrementBy(int increment)

struct Counter {
   int count;

   void incrementBy(int increment)
   in {
      assert(increment >= 0, "increment must be zero or greater");
   }
   out {
      // want to state  assert(count == old(count) + increment);
   }
   do {
      this.count += increment;
   }
}

old(count) is the value of count on entry to incrementBy()
old count is Eiffel syntax.

How is this done in D?

August 07
Doesn't look like it: https://dlang.org/spec/function.html#postconditions

Unfortunately Walter isn't very keen on contracts in general now days and may not be willing to accept any DIP's for this.

If you want it improved, you will likely have to implement it, on top of the DIP itself.
August 06

On Wednesday, 6 August 2025 at 15:43:01 UTC, Brother Bill wrote:

>

How is this done in D?

I thought the following would work, but the compiler doesn't like this.count as a default argument:

struct Counter {
   int count;

   void incrementBy(int increment, int preCount = this.count)
   in {
      assert(increment >= 0, "increment must be zero or greater");
   }
   out {
       assert(count == preCount + increment);
   }
   do {
      this.count += increment;
   }
}

And I expect you'd like to avoid adding a function parameter anyway.

August 06

On Wednesday, 6 August 2025 at 16:19:17 UTC, Nick Treleaven wrote:

>

On Wednesday, 6 August 2025 at 15:43:01 UTC, Brother Bill wrote:

>

How is this done in D?

I thought the following would work, but the compiler doesn't like this.count as a default argument:

struct Counter {
   int count;

   void incrementBy(int increment, int preCount = this.count)
   in {
      assert(increment >= 0, "increment must be zero or greater");
   }
   out {
       assert(count == preCount + increment);
   }
   do {
      this.count += increment;
   }
}

And I exp
ect you'd like to avoid adding a function parameter
anyway.

This hack gets the job done, at the cost of an extra struct member and an assignment.
If this code is conditionally compiled, then the extra struct member and the extra setting of oldCount can be removed from release (production) version.

The additional code is manually entered for now as a "proof of concept".

import std.stdio;

void main() {
	Counter counter = { count: 42 };
	writeln("counter(42): ", counter.count);
	
	counter.incrementBy(100);
	writeln("after incrementBy(100): ", counter.count);
}

struct Counter {
	int count;
	private int oldCount;

	void incrementBy(int increment)
	in {
		assert (increment >= 0, "increment must be non-negative");
	}
	out {
		assert(count == oldCount + increment, "count = old count + increment");
	}
	do {
		// Capture oldCount
		oldCount = count;

		// body
		count += increment;
	}

}

Can we do better than this?

IMHO, DbC (Design by Contract) is one of the great features in D "borrowed" from Eiffel.
It would be even better with old(count) or old count, where old would be a "keyword" specially treated in the postcondition "out" block only. It would capture the count member implicitly at the start of the do block.

	out {
		assert(count == old count + increment, "count = old count + increment");
	}