Thread overview
Possible 'pure' bug with int[] slice. Programming in D page 174
11 hours ago
Brother Bill
9 hours ago
Dmitry Olshansky
9 hours ago
Brother Bill
3 hours ago
Alex Bryan
3 hours ago
Dmitry Olshansky
11 hours ago

Did I discover a bug, or am I misunderstanding intentional behavior?
I would not expect a 'pure' function to modify a parameter.

void main()
{
	import std.stdio : writeln;

	int[] numbers = [5, 6, 7, 8, 9];
	writeln("numbers before: ", numbers);
	writeln("inner(numbers): ", inner(numbers));
	writeln("numbers after : ", numbers);
}

int[] inner(int[] slice) pure
{
	// This should not be pure.  I broke purity by mutating slice[0]
	// D compiler is not catching this!
	slice[0] = 500;

	if (slice.length)
	{
		--slice.length;
		if (slice.length)
		{
			slice = slice[1 .. $];
		}
	}
	return slice;
}

Output of console:

numbers before: [5, 6, 7, 8, 9]
inner(numbers): [6, 7, 8]
numbers after : [500, 6, 7, 8, 9]
9 hours ago

On Saturday, 4 October 2025 at 10:56:09 UTC, Brother Bill wrote:

>

Did I discover a bug, or am I misunderstanding intentional behavior?
I would not expect a 'pure' function to modify a parameter.

It’s weakly pure in that it could only mutate things that are passed in. Strongly pure would require no mutable pointers/slices/references.
It may be misleading that it’s single keyword for both of these. The good news is that strongly pure functions can call weakly pure function and stay strongly pure.

9 hours ago

On Saturday, 4 October 2025 at 12:14:06 UTC, Dmitry Olshansky wrote:

>

It’s weakly pure in that it could only mutate things that are passed in. Strongly pure would require no mutable pointers/slices/references.
It may be misleading that it’s single keyword for both of these. The good news is that strongly pure functions can call weakly pure function and stay strongly pure.

So if we don't want to allow mutating passing in parameters, add 'in' keyword to each parameter. Then it should be strongly cure. Is that correct?

int[] inner(in int[] slice) pure
3 hours ago

On Saturday, 4 October 2025 at 12:40:43 UTC, Brother Bill wrote:

>

On Saturday, 4 October 2025 at 12:14:06 UTC, Dmitry Olshansky wrote:

>

It’s weakly pure in that it could only mutate things that are passed in. Strongly pure would require no mutable pointers/slices/references.
It may be misleading that it’s single keyword for both of these. The good news is that strongly pure functions can call weakly pure function and stay strongly pure.

So if we don't want to allow mutating passing in parameters, add 'in' keyword to each parameter. Then it should be strongly cure. Is that correct?

int[] inner(in int[] slice) pure

If you want to enforce (and also document) that an parameter is never changed by the function, you should use const. If I'm reading the spec correctly (https://dlang.org/spec/function.html#in-params), in always implies const, and with the -preview=in compiler switch, it also implies scope

3 hours ago

On Saturday, 4 October 2025 at 12:40:43 UTC, Brother Bill wrote:

>

On Saturday, 4 October 2025 at 12:14:06 UTC, Dmitry Olshansky wrote:

>

It’s weakly pure in that it could only mutate things that are passed in. Strongly pure would require no mutable pointers/slices/references.
It may be misleading that it’s single keyword for both of these. The good news is that strongly pure functions can call weakly pure function and stay strongly pure.

So if we don't want to allow mutating passing in parameters, add 'in' keyword to each parameter. Then it should be strongly cure. Is that correct?

int[] inner(in int[] slice) pure

Yes that’s it.