Passing array as const slows down code?

H. S. Teoh hsteoh at quickfur.ath.cx
Fri Apr 27 11:25:06 PDT 2012


On Fri, Apr 27, 2012 at 07:25:30PM +0200, Joseph Rushton Wakeling wrote:
> On 27/04/12 19:08, Steven Schveighoffer wrote:
> >weak purity, I think, is one of the most revolutionary ideas to come
> >from D.  Essentially, we get compiler-checked pure functions that can
> >be written imperatively instead of functionally.
> 
> I do agree with that; it's a very attractive aspect of D that a
> function or object can be internally imperative but pure as far as the
> outside world is concerned.  Seeing that documented in Andrei's
> writings was another "Wow!" moment for me about D. :-)
> 
> What concerned me here was that the way my reputation() function was
> set up actually did change the public state of the object, which to my
> mind isn't even weakly pure.  But I just wrote a fix which, contrary
> to my fears, didn't affect the speed of the program.

As mentioned by others, D internally recognizes two kinds of purity,
which is unofficially called "strong purity" and "weak purity". The idea
is that strong purity corresponds with what functional programming
languages call "pure", whereas weak purity allows mutation of state
outside the function, *but only through function parameters*.

The idea is that strongly pure functions are allowed to call weakly pure
functions, provided any reference parameters passed in never escape the
scope of the strongly pure function. For example, a strongly pure
function is allowed to pass in pointers to local variables which the
weakly pure function can modify through the pointer:

	pure real computationHelper(real arg1, ref real arg2) {
		// This mutates arg2, so this function is only weakly
		// pure
		arg2 = sin(arg1);

		return cos(arg1);
	}

	pure real complexComputation(real[] args) {
		real tempValue;
		...

		// Note: this changes tempValue
		real anotherTempValue = computationHelper(args[0],
					tempValue);

		// But since tempValue is only used inside this
		// function, it does not violate strong purity
		return tempValue + complicatedFunc(args[1]);
	}

As far as the outside world is concerned, complexComputation is a
strongly pure function, because even though computationHelper mutates
stuff through its arguments, those mutations are all local to
complexComputation, and does not actually touch global world state
outside. Weakly pure functions cannot mutate anything that they don't
receive through their arguments (the 'this' pointer is considered part
of their arguments, it's just implicit), so as long as the strongly pure
function never passes in a pointer to the outside world, everything is
OK.

The motivation for distinguishing between these types of purity is to
expand the scope of what the strongly-pure function can call. By
allowing weakly pure functions to be called from strongly-pure
functions, we open up many more implementation possibilities while still
retaining all the benefits of strong purity.


> >If the function is weakly pure, then it cannot be optimized based on
> >purity, so I don't think there is any way marking it pure *hurts*.
> 
> I was more concerned that the compiler wasn't identifying what to me
> was a violation of purity.  I'm fairly sure I can also find a way to
> make some of those "nothrow" functions throw an error ...

It's not a violation of purity, it's just "weak purity". If you try to
access a global variable, for example, it will trigger an error.

And nothrow functions *are* allowed to throw Error objects. That's also
a deliberate decision. :-)


T

-- 
"640K ought to be enough" -- Bill G., 1984.
"The Internet is not a primary goal for PC usage" -- Bill G., 1995.
"Linux has no impact on Microsoft's strategy" -- Bill G., 1999.


More information about the Digitalmars-d-learn mailing list