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.