On 01/15/2012 11:10 PM, Timon Gehr wrote:
On 01/15/2012 02:36 PM, Alex Rønne Petersen wrote:
Hi,

I don't know how many times I've made the mistake of passing a local
variable to a function which takes a 'ref' parameter. Suddenly, local
variables/fields are just mutating out of nowhere, because it's not at
all obvious that a function you're calling is taking a 'ref' parameter.
This is particularly true for std.utf.decode().


Odd. I always thought the fact that std.utf.decode modifies the second
parameter is very intuitive. (decoding cannot work nicely without it)

Yes, I realize I could look at the function declaration. Yes, I could
read the docs too. But that doesn't prevent me from forgetting that a
function takes a 'ref' parameter, and then doing the mistake again. The
damage is done, and the time is wasted.


This is true for every part of a function interface. How can a
programmer even understand what the function does if he forgets what the
calling conventions are? Conversely, does a reminder of the calling
conventions usually restore full knowledge of the semantics of the
called function?

I think D should allow 'ref' on call sites to prevent these mistakes.
For example:

string str = ...;
size_t pos;
auto chr = std.utf.decode(str, ref pos);

Now it's much more obvious that the parameter is passed by reference and
is going to be mutated.

Ideally, this would not be optional, but rather *required*, but I
realize that such a change would break a *lot* of code, so that's
probably not a good idea.

Thoughts?


I personally think 'ref' at call site is pure syntax noise but I see
that it might be useful to some in some cases. I'd prefer to leave it
as-is, but I don't feel very strongly for either way.
My preference would be
[not allowed > enforced > ... > optional > optional with switch]

However, it is very important not to do this to 'lazy'.

Another thing that would have to be discussed: what happens to const ref
parameters? It is very reasonable that someone will decide to change
calling conventions from by value to by const ref or the other way round
after profiling. It is very convenient that such a change is
syntactically transparent to the caller and this should stay.

It is even realistic that someone will decide to interchange by ref/by
value, because there is no way to express 'I will not change the head
level' in the current type system other than taking a parameter by
value. Therefore introducing call-site ref would perhaps necessitate
re-introducing 'final' for variables.


Oh, and furthermore it would give rise to abominations such as:

auto ref wrap(alias foo,T...)(auto ref T args){
    return foo(auto ref args);
}

*shudder*. What does 'auto ref' even mean if 'ref' is required for ref parameters at call site? I think the best answers would silently break existing code.

Reply via email to