Array as an argument, ambiguous behaviour.

Maxim Fomin maxim at maxim-fomin.ru
Thu Jan 30 09:24:53 PST 2014


On Thursday, 30 January 2014 at 16:48:51 UTC, Cooler wrote:
> On Thursday, 30 January 2014 at 16:18:33 UTC, Steven 
> Schveighoffer wrote:
>> void foo(int x)
>> {
>>   x = 5;
>> }
>>
>> "hey, why doesn't that work! Setting a parameter to another 
>> value should be illegal!"
>>
>> -Steve
>
> Please understand - I am not against void foo(int[] x){}
> I am for predictability of behavior.

Predictability of behavior is not a principle of D and even if it 
would be, it can't be applied blindly. D is not a formal 
mathematic system.

> You suggest to describe function's behavior in documentation - 
> quotation from your article "It is a good idea to note in the 
> documentation how the passed in slice might or might not be
> overwritten." My idea is that all potential errors must be 
> detected as soon as possible.

It is impossible to detect all errors in D per se, let alone 
taking into account separate compilation model. In some 
circumstances compiler can guess possible ways, but particular 
case we discussing is so common, that nothing can be done to 
'fix' it. By the way, this case is not strictly speaking an 
error. It is error in context when caller cares about changes but 
this can be hardly verified at compile time (compiler need to 
read brain to know it).

> The D principle - "The program compile and runs as expected, or 
> not compile at all".

It is all talk. Trying to apply this 'principle' in all cases is 
too naive.

> If you really need to call function that can change content of 
> an array, but cannot change size of an array the language 
> syntax should allow express it in function signature. I 
> consider "void fun(int[] const x){}" more error prone than 
> "void fun(int[] x){}" and for the caller and for implemeter.
>

Personally this syntax is awful.

By the way, there is another similar issue in D:

import std.stdio;

void foo(int[int] aa)
{
	aa[1] = 1;
}

void main()
{
	int[int] aa;
	foo(aa);
	writeln(aa); // []
	aa[0] = 0;
	foo(aa);
	writeln(aa); // [0:0, 1:1]
	aa = null;
	foo(aa);
	writeln(aa); // []
}

Here changes in AA array will be visible conditional that array 
is non null. If it is null, changes will be lost. This is another 
example of situation of "the caller MAY or MAY NOT see changes 
to" (citing your post above). In general, such 
semivalue-semireference semantic is produced when there is 
pointer wrapped into struct (doesn't matter whether it is opaque 
lang type or user defined). This happens in some language types, 
but may be also in user defined types. I don't think that 
verifying arbitrary semantic is compiler job.


More information about the Digitalmars-d-learn mailing list