On 08/09/2012 14:05, Chris Nicholson-Sauls wrote:
Given:

void func (ref int[], int)

If ref/out were required at the call site, this destroys UFCS.

int[] array;
array.func(0); // error, ref not specified by caller

For UFCS, ref should be implied. Also for 'const ref' parameters, callsite ref should not be necessary.

This suggestion has come up a couple times before, and each time failed
to gain traction.

But given that C, C#, (Go?) and Rust have the same philosophy that argument modification should be explicit for value types, it is arguably important. It might be nice to have for D3.

I wouldn't mind it as an option -- possibly even as a
recommendation in most library code -- but as a requirement it honestly
just gives me a headache.

As an option it would serve no practical purpose other than documentation.

Generally speaking, if a parameter being
ref/out is surprising, there is something wrong with the design.  (There
are times it is non-obvious in otherwise good code, this seems uncommon.)

Yes but unfortunately bad design is going to be a reality sometimes. Also there is a difference between 'surprising' and 'obvious'. Callsite ref makes it quicker to understand code for a negligible cost, occasionally a lot quicker if you're coming back to code you haven't seen for a while.

For example, calling one of the *InPlace functions from Phobos, I
immediately expect 'ref' -- otherwise, how to modify "in place" in a
reliable (ie, non-allocating) manner?  Likewise, 'out' -- used pretty
rarely in the first place -- sits in the same place pointers typically
do, as auxiliary returns.  The category of functions/methods which use
them is pretty self consistent. (What few corner cases remain would be
better served by cleaning up tuples to make them more sane as return
values.)

Given:

bool checkedEmitJ (Op, Params, ref const(Scope), Address, out Address)

I really don't want to have to call it as:

auto handled = checkedEmitJ(Op.CJmp, parms, ref _scope, suggest, out lval);

When the 'ref' and 'out' parameters listed are specified by the design
and consistent across all the "-emit-" functions.

The point is that the signature of checkedEmitJ is not always there when you are reading code that calls checkedEmitJ, so the ref and out parameters are useful in saving the reader time. Making code easier to read is much more important than making it easier to write.

When I first saw:
swap(ref a, ref b);

I thought that looked ugly with the refs, but now I don't mind it. IMO it's only functions whose arguments are all passed by ref that don't really need annotation, and these are infrequent. All others stand to benefit.


Reply via email to