Would like to see ref and out required for function calls

Nick Treleaven ntrel-public at yahoo.co.uk
Sun Sep 9 05:54:08 PDT 2012


On 08/09/2012 19:17, Timon Gehr wrote:
> On 09/08/2012 06:05 PM, Nick Treleaven wrote:
>> 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.
>
> Why? UFCS means uniform function call syntax.

I meant if callsite ref was required for parameters, it should not be 
required for array in 'array.func()'. It would be bizarre to require 
'(ref array).func()'.

>> Also for 'const ref' parameters, callsite ref should not be necessary.
>>
>
> The callee might escape a pointer to the argument. Which is
> 'non-obvious' as well when there is no callsite ref.

Knowing modification is more important to the local scope than knowing 
escapes, after all (in theory) the compiler should enforce that only 
data safe to be escaped is allowed to be escaped, at least in safe mode.

In any case, escaping is orthogonal to modification, so shouldn't use 'ref'.

>>> 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
>
> It is already explicit. The information is just not repeated at the
> call site.

It is not explicit at the call site. That is the crux of the argument 
for the feature.

>> for value types, it is arguably important.
>
> This is not necessarily a valid conclusion. Popularity does not imply
> importance.

I only said it was *arguably* important, given that the parent post said 
the idea failed to gain traction. Go and Rust are relatively new and 
decided for the explicit callsite approach (AFAIU).

>> It might be nice to have for D3.

BTW if this was desired (and it seems a long shot ATM) I was thinking 
there should be an automatic tool to upgrade code from D2 to 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.
>
> Requiring it makes lack of call site annotations carry some information.
> The only practical purpose would still be documentation.

Yes, albeit compiler enforced 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.
>
> Bad design never should be a motivation for adding language features.
> In fact, it seems to be a motivation for creating languages that have
> few features.

OK, but ref/out parameters aren't always a bad design.

>> 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.
>>
>
> IMHO it is better left to the future D editor. It can highlight ref/out
> arguments in a distinct style. Why clutter the language core even more
> with somewhat complex rules specifying in what cases call site ref is
> required?

1. Unix tools will never highlight ref/out parameters - e.g. grep.
2. Github probably won't ever.
3. Not everyone will use an editor that does so. Some people prefer a 
simple editor.

>> ...
>> 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.
>
> I'd still have to look up its declaration to understand exactly what it
> does.

Sometimes you're not concerned with the precise effect of a function, 
you just want to work out how it impacts the surrounding code.

>> Making code easier to read is much more important than making it
>> easier to write.
>>
>
> I don't know why this quote is repeated all the time. It is not like
> ease of writing and ease of reading are decoupled or something.
> What is most important is designing the language such that code
> that is easy to write is easy to read.
>
> What is easy to read is to some extent subjective. eg. I'd prefer to
> just look at the called function's documentation rather than having
> every call I later inspect redundantly repeat information present in
> the function declaration. IMHO it's just noise.

It would likely become a motor-skill to ignore the keywords when you're 
not interested in them.

>> 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,
>
> We are talking about call site annotations. Functions will always
> require annotation to change the parameter passing style.

Can't disagree there ;-)

>> and these are infrequent.
>
> What is this claim based on? The use case above is probably one of the
> more common ones.

How often do you use swap?



More information about the Digitalmars-d mailing list