Pure functions and delegates

H. S. Teoh hsteoh at quickfur.ath.cx
Tue Jan 17 19:40:34 PST 2012

So, I was quite impressed with D's pureness system, and was
experimenting a bit with it. Then I discovered that delegates are
impure, which seems reasonable since there's no way to know what a
delegate might do. But *if* the compiler verifies that a particular
delegate is (weakly) pure in the context of the function that passed it,
then couldn't the function that it gets passed to be declared pure as

The context is this:

	class MyCollection {
		void opApply(int delegate(const ref int n) cb) const {
			if (cb(...)) { ... }
		int[] enumerate() {
			int[] list;
			foreach (n; this) {
				list ~= n;
			return list;

Is there a way to convince the compiler that enumerate() can be marked
'pure' even though opApply() can't, in general, be pure because it
doesn't know what the delegate does?

Technically, enumerate() is weakly pure, because its delegate does not
touch anything outside of its scope, and given this particular delegate,
opApply() also is weakly pure. In other words, opApply()'s pureness
depends on the delegate passed to it. So if there was a way for the
compiler to check that yes, opApply() is (weakly) pure except for the
part that calls the delegate (perhaps using some kind of "conditionally
pure" attribute?), then it should, in theory, be possible to verify that
yes, the delegate that enumerate() passes to opApply() does not violate
pureness, so enumerate() can be labelled 'pure'.

The trouble is, given the current state of things, there is no way to
implement enumerate() in a pure way, short of duplicating most of
opApply()'s code and substituting the line that calls the delegate.
Which is a rather ugly workaround. But otherwise, MyCollection cannot be
used inside a (strongly) pure function unless it avoids using opApply()
and enumerate() altogether, even if the container never escapes the pure
function's scope. This is quite a major limitation IMHO.


He who laughs last thinks slowest.

More information about the Digitalmars-d-learn mailing list