View mode: basic / threaded / horizontal-split · Log in · Help
September 10, 2012
Re: Would like to see ref and out required for function calls
On Saturday, 8 September 2012 at 17:20:21 UTC, F i L wrote:
> On Friday, 7 September 2012 at 11:33:41 UTC, Kevin McTaggart 
> wrote:
>> I've been looking at migrating a reasonably large ship motion 
>> library (tens of thousands of lines) from C# to D.  I've 
>> become quite enthusiastic about D, and most of my problems 
>> have been relatively minor (e.g., inconsistent bugs with 
>> std.container.Array, would like orange serialization to give 
>> me an error telling me I didn't register a class before 
>> calling serialize).  I suggest that the language require ref 
>> and out when calling functions, as C# requires.  This would 
>> make code easier to understand, and would also eliminate the 
>> problem I had when the wrong function from the following 
>> choices was mistakenly called:
>>
>> parseLineInts(string text, int positionStart, out int j0, out 
>> int j1)
>>
>> parseLineInts(string text, out int j0, out int j1, out int j2)
>>
>> I note that the second function calls another function as 
>> follows:
>> int positionStart = 1;
>> parseLineInts(text, positionStart, j0, j1, j2);
>>
>> I look forward to seeing feedback from D experts.  This is the 
>> only significant change that I could think of recommending for 
>> the language.
>
> +1. The fact that a value type is modified should be 
> information the programmer can see at a glance.
>
>
>

+1 here too. Coming from C# this is exactly what i was missing
from D too.

It's not only that the information that a value type is modified
should be visible to the programmer at a glance who had
originally written the code but also to other team members who
just want to do a quick read over code someone else has written
or to the people who do code review.

 From my personal experience within commercial software
development code is much more often read than written. And most
of the time it will be read by a larger amount of people one can
initially think of.

But i have to admit, that it might be too late for changes in D2
regarding this just because it would break too much existing code
(and at the moment code still breaks too often).


>
> Andrei Alexandrescu wrote:
>> Actually the darndest thing is that C# has retired the syntax 
>> in 5.0 (it used to be required up until 4.0). Apparently users 
>> complained it was too unsightly.
>

I have never heard anyone complaining about this syntax nor have
i read of anyone complaining about this online in newsgroups or
such. From my colleagues and my circle of acquaintances only
former C++ programmers were initially complaining but they were
soon adopting this syntax and at the end they had to admit that
these additional syntax annotations at the call site make sense.

I think ref/out is like the now "forced" "override" keyword for
overridden methods - it just helps to avoid mistakes and makes
things a little bit safer.

> Citation? I'm using C# 5.0 with Visual Studios 2012 on Windows 
> 8 right now and ref/out are still required at the call sight of 
> functions.

I have Visual Studio 2012 RC and can confirm, that ref and out
are still required even with C# 5.0 (but maybe there is some
compiler switch to disable this ??)
September 11, 2012
Re: Would like to see ref and out required for function calls
> But i have to admit, that it might be too late for changes in D2
regarding this just because it would break too much existing code
Such feature can be implemented as optional in D2 with compiler 
switch to enforce explicit ref and out syntax.
September 11, 2012
Re: Would like to see ref and out required for function calls
On 11-09-2012 06:21, zerg wrote:
>> But i have to admit, that it might be too late for changes in D2
> regarding this just because it would break too much existing code
> Such feature can be implemented as optional in D2 with compiler switch
> to enforce explicit ref and out syntax.

It's already highly problematic that we have -property (and that it 
isn't the default).

D code shouldn't stop being valid just because of a missing compiler 
switch (or the presence of one).

-- 
Alex Rønne Petersen
alex@lycus.org
http://lycus.org
September 11, 2012
Re: Would like to see ref and out required for function calls
On 9/11/12 1:28 AM, Manuel wrote:
>> Citation? I'm using C# 5.0 with Visual Studios 2012 on Windows 8 right
>> now and ref/out are still required at the call sight of functions.
>
> I have Visual Studio 2012 RC and can confirm, that ref and out
> are still required even with C# 5.0 (but maybe there is some
> compiler switch to disable this ??)

Erik Meijer didn't get back to me yet about that with a link, but he did 
mention that the relaxation was only allowed for COM calls.

Andrei
September 11, 2012
Re: Would like to see ref and out required for function calls
Am 08.09.2012 20:17, schrieb Timon Gehr:
> Agh, sent a private mail again. I don't seem to be the only one though.
> Has there been a thunderbird UI change?
> 

They exchanged the order of the "Reply" and "Smart reply" buttons in TB
15. This also hit me several times, very annoying. You can switch them
back using "Customize" in the context menu though.
September 11, 2012
Re: Would like to see ref and out required for function calls
On 10/09/2012 21:36, Timon Gehr wrote:
> On 09/09/2012 02:54 PM, Nick Treleaven wrote:
>> 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()'.
>>
>
> Not more bizarre as in other positions.

The brackets make it more ugly though. The reason why it is not 
necessary is that in general, function arguments are not implicitly 
modified (and some languages enforce this). But when you see foo.bar() 
and you don't know what bar does, you don't assume that foo won't be 
modified, even across many languages.

>>> 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).
>>
>
> Yes, Go uses explicit pointer types.
> Regarding Rust, you are wrong.

OK, I misunderstood Rust & I apologize. Thanks for providing the example 
code.

>>> What is this claim based on? The use case above is probably one of the
>>> more common ones.
>>
>> How often do you use swap?
>>
>
> Whenever I want to swap the values of two variables. All other
> functions in my current project except one that use ref either pass by
> const/immutable ref, or all arguments are ref, or they are function
> pointer literals that are part of a polymorphic value type where it is
> obvious that the first parameter is passed by ref. The remaining
> function is private and declared right between the methods that use it.

Then callsite ref might not help you at all. I think Manuel's recent 
post is better than anything I could write to support the idea.
September 11, 2012
Re: Would like to see ref and out required for function calls
On Tuesday, 11 September 2012 at 08:10:21 UTC, Andrei 
Alexandrescu wrote:
> On 9/11/12 1:28 AM, Manuel wrote:
>>> Citation? I'm using C# 5.0 with Visual Studios 2012 on 
>>> Windows 8 right
>>> now and ref/out are still required at the call sight of 
>>> functions.
>>
>> I have Visual Studio 2012 RC and can confirm, that ref and out
>> are still required even with C# 5.0 (but maybe there is some
>> compiler switch to disable this ??)
>
> Erik Meijer didn't get back to me yet about that with a link, 
> but he did mention that the relaxation was only allowed for COM 
> calls.
>
> Andrei

OK, i see. For COM calls that might make sense, since binary COM 
modules are mostly written in C/C++ and must also not depend on 
any feature of any programming language so that the calling 
should be easily possible from any language. There these C# 
specific annotations are of no use since you don't get any 
additional safety and you just have to write more code which at 
the end gains you nothing.


In general, i can understand the objections against adding these 
syntax annotations at the call site. When i started programming 
in C#, coming from a C++ background, i found writing these 
additional annotations rendundant and annoying and a complete 
waste of time.

But when you are developing in a team where you often have to 
read the code written by other team members and they have to read 
your code, then you really begin to see the merits. But it is 
also a good reminder for yourself when you have to look or modify 
code you have written a long time ago.


A colleague of mine also mentioned, that you can see "a 
simulation" of the ref/out annotations using pointers / 
references as an idiom nowadays in a lot of C++ code too. If a 
function argument will be modified in some way you use a pointer 
and const references when it won't:


e.g. if you have a function / method:


void transmogrify(const MogrifyType& a, const MogrifyType& b, 
MogrifyType* out)


you would call it:


transmogrify(a, b, &c);


Using this convention throughout the code you can see at the call 
site that a and b are input parameters and c will be modified.

For example the render system "pbrt" ( http://pbrt.org/ ) uses 
this as an convention in their C++ code and it is explicitly 
mentioned in chapter 1.5.1 "pointer or reference" in the 
introduction.
September 11, 2012
Re: Would like to see ref and out required for function calls
> Actually the darndest thing is that C# has retired the syntax 
> in 5.0 (it used to be required up until 4.0). Apparently users 
> complained it was too unsightly.
>
> Andrei

Wh-huh?? Reference please. I have sought out info about C# 5 
multiple times and I never heard that.

Anyway I don't mind if ref is not required, but it ticks me off 
that it is not *allowed*. Even in C++ I can use "OUT" and "IN 
OUT" at both the definition and call sites (I may as well, since 
Windows header files #define them already). The compiler doesn't 
verify it but I find it useful to make the code self-documenting.

Some have said that "well if the the compiler doesn't enforce it 
then it's pointless, you won't be able to tell if a call site 
without 'ref' is passed by ref". But no, it's not pointless, 
because (1) if you see a call site WITH 'ref' then clearly it is 
passed by reference, (2) I would use 'ref' consistently in my own 
code so that when I look back at my code a year later, the 
absence of 'ref' is a clear indication that it is an input 
parameter, and (3) if the compiler offered the option to issue a 
warning when 'ref' is absent, statement (2) would be true 100% of 
the time, in my code, instead of just 98%.

Most of the code I look at is my own so that's my primary motive 
for wanting 'ref'. Yes, if 'ref' were allowed, some people would 
not use it; so when looking at a new code base I'd have no 
guarantee that a parameter NOT marked ref is passed by value. But 
at least (1) still applies.
September 11, 2012
Re: Would like to see ref and out required for function calls
>>> 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.
+1

> Why? UFCS means uniform function call syntax.
It is already understood that the thing left of '.' may be passed 
by reference:

struct Foo { int x = 0; void f() { x++; } }
void obvious()
{
   Foo foo; foo.f(); // x is passed to f() by reference
}

Perhaps your argument makes sense for classes, but not for 
structs. In any case the syntax (ref foo).f() would require extra 
work for Walter so I would not propose it. What I might propose 
instead is that, if the user requests (via command-line argument 
such as '-callSiteRef') that a warning be issued for arguments 
passed without 'ref' at the call site, then a situation like this 
should prompt a warning.

class Bar { int b; }
void changeBar(ref Bar b) { b = new Bar(); }
void warning()
{
    Bar bar = new Bar();
    bar.b = 10;
    bar.changeBar(); // Warning: 'bar' is implicitly passed by 
reference. To eliminate this warning, use 'changeBar(ref bar)' 
instead or do not compile with '-callSiteRef'
}

Again, this problem only applies to classes, since it is 
understood that structs are normally passed by reference.

>> 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.

If you're referring to the fact that it's easy to have a D 
pointer to a stack variable outlive the variable... I don't think 
that this 'flaw' (I think of it as a flaw, others may think of it 
as a feature) is a good enough reason to say 'call site ref 
should be required for const ref parameters'.

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

I think 'ref' is a popular idea because people have used it in C# 
and liked it. I didn't start putting 'IN OUT' and 'OUT' in my C++ 
code until C# taught me the value of documenting it at the call 
site.

>>> 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.)

I often want to 'scan' code to see what it does. Especially for 
debugging, I want to see where the side-effects are QUICKLY. 
Guessing which parameters are 'ref' requires me to analyze the 
code in my head. Even if I myself wrote the code, it can be time 
consuming. That's why I would prefer to explicitly mark possible 
side effects with 'ref' (of course, when passing a class to a 
function, the class members may be modified when the reference to 
the class was passed by value. But it is far easier to keep track 
of which classes are mutable than to keep track of which 
parameters of which functions are 'ref', because functions far 
outnumber classes.)

> IMHO it is better left to the future D editor.

That's probably a long way off.
September 11, 2012
Re: Would like to see ref and out required for function calls
On Tue, 11 Sep 2012 13:36:23 +0200
Sönke Ludwig <sludwig@outerproduct.org> wrote:

> Am 08.09.2012 20:17, schrieb Timon Gehr:
> > Agh, sent a private mail again. I don't seem to be the only one
> > though. Has there been a thunderbird UI change?
> > 
> 
> They exchanged the order of the "Reply" and "Smart reply" buttons in
> TB 15. This also hit me several times, very annoying. You can switch
> them back using "Customize" in the context menu though.
> 

Mozilla's constantly screwing around with their UIs. You're lucky in
this case: Usually you can't revert their UI shenanigans without just
simply downgrading or going through the bother of writing a whole
plug-in.
1 2 3 4 5 6 7
Top | Discussion index | About this forum | D home