Would like to see ref and out required for function calls

Nick Treleaven ntrel-public at yahoo.co.uk
Sat Sep 8 09:05:25 PDT 2012


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.




More information about the Digitalmars-d mailing list