View mode: basic / threaded / horizontal-split · Log in · Help
September 11, 2012
Re: Would like to see ref and out required for function calls
On Tuesday, 11 September 2012 at 17:57:17 UTC, David Piepgrass 
wrote:
>>>> 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.


Like i have written above, when switching from C++ to C# i found 
it at first annoying but now i wished i would have it in C++ too. 
One possibility to simulate this in C++ is like the pbrt people 
have done it with const references and pointers (look at my post 
above for further details).


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

+1

It's not only that you yourself want to 'scan' through your code 
and QUICKLY see where parameters in function calls are modified 
but others might have to read your code aswell for code reviewing 
without browsing in the hopefully existing documentation for 
every single function / method. People in companies normally are 
not programming in isolation but are working in a team and teams 
often change.



>> IMHO it is better left to the future D editor.
>
> That's probably a long way off.

Yes. Looking at the current overall state of the d toolchain that 
might be a very long way off.

And even then, inmho, it would be a not so good solution because 
it would be a feature which would tie users who want this feature 
to a specific editor / ide.
September 12, 2012
Re: Would like to see ref and out required for function calls
On Tuesday, 11 September 2012 at 16:49:45 UTC, Manuel wrote:
> 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.
>

Having used Turbo Pascal before I was doing C, I never understood
why so many developers cry for this at the call site.

I never had any problem with "var" parameters on Turbo Pascal (or
other languages from Wirth), nor with references in C++.

As I am not language religious, I just use them the way the
language provides them.

--
Paulo
September 12, 2012
Re: Would like to see ref and out required for function calls
On 11/09/2012 18:57, David Piepgrass wrote:
>>>> 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.

I had only thought about UFCS and ref parameters for value types. You 
are right that requiring callsite ref for class ref parameters would be 
a useful idea, as modifying the ref itself is unusual behavior. And 
because of that, disallowing UFCS for functions that have a class ref 
parameter as the first parameter might be an elegant solution.
September 12, 2012
Re: Would like to see ref and out required for function calls
On 12/09/2012 13:39, Nick Treleaven wrote:
>> 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.
>
> I had only thought about UFCS and ref parameters for value types. You
> are right that requiring callsite ref for class ref parameters would be
> a useful idea, as modifying the ref itself is unusual behavior. And
> because of that, disallowing UFCS for functions that have a class ref
> parameter as the first parameter might be an elegant solution.

Also the same applies to ref parameters with any reference types:

On 08/09/2012 14:05, Chris Nicholson-Sauls wrote:
> 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

So the above poster was right, I completely missed this :-/

(But disallowing UFCS here still might be a good solution).
September 12, 2012
Re: Would like to see ref and out required for function calls
I disagree that it would be useful.
In C# it is useful because pointers that used a lot less than in 
D.

Consider this:

void f(ref int x)
{
...
}

...
int x = 5;
f(ref x); // good, passed by reference
...


But:
void g(int* p)
{
...
}

...
int x = 5;
g(&x); // passed by reference as well, but it is not explicit 
like before. You don't even know if it's a const pointer if you 
don't read the function's signature.
...

So someone has this cool idea which is also present in some other 
programming language and thinks it would be nice to add it to D. 
That's not how it works. Then come the problem with things not 
properly designed etc etc.

Anyway, who needs to see f(ref x) when you can put your mouse 
above the function call and see its declaration? All modern IDEs 
support that - and I don't think C# guys use plain text editors.
September 12, 2012
Re: Would like to see ref and out required for function calls
Minas:

> g(&x); // passed by reference as well, but it is not explicit 
> like before. You don't even know if it's a const pointer if you 
> don't read the function's signature.

The presence of "&" at call site acts exactly like the "ref" at
the call site. In both cases you don't know if it's
const/immutable.

Bye,
bearophile
September 12, 2012
Re: Would like to see ref and out required for function calls
Minas wrote:
> Anyway, who needs to see f(ref x) when you can put your mouse 
> above the function call and see its declaration? All modern 
> IDEs support that - and I don't think C# guys use plain text 
> editors.

People debugging large bodies of code should not be required to 
hover the mouse over each and every function parameter for a 
second to properly understand structure. People using non-tooltip 
text editors have an even harder time.

I think you're missing the point. This code:

    int* x;
    foo(&x);

at least tells you there's a _potential_ x is being manipulated 
rather than just used. We don't need full insight into what's 
going on, just a helpful hint which narrows the potential 
culprits when debugging.

If fact, it would nice if even reference types where required to 
follow similar "is modified in function" semantics, and I have 
ideas about that, but I'm not going there right now...
September 12, 2012
Re: Would like to see ref and out required for function calls
On Wednesday, 12 September 2012 at 07:36:24 UTC, Paulo Pinto 
wrote:
> On Tuesday, 11 September 2012 at 16:49:45 UTC, Manuel wrote:
>> 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.
>>
>
> Having used Turbo Pascal before I was doing C, I never 
> understood
> why so many developers cry for this at the call site.
>
> I never had any problem with "var" parameters on Turbo Pascal 
> (or
> other languages from Wirth), nor with references in C++.
>
> As I am not language religious, I just use them the way the
> language provides them.
>
> --
> Paulo


You just have cut away the last part of the history of my life 
and completely changed my statement to the reverse ;-)

That last part was were i was getting my enlightenment and 
started to embrace additional annotations at the call site. From 
there i never looked back and lived a happier and more glorious 
life with a lot of profit and lot less errors ;-)


Kevin just put this up for discussion because he realized while 
porting code from C# to D that he got wrong function calls on 
overloaded functions because of missing call site parameter 
annotations and just asked about the general opinion in the D 
community to add these to the language.

I and a lot of the other participants in this thread just 
asserted that it would be a nice addition to D. That does not 
mean, we were "crying" for these or that we are "language 
religious" or that without them we would have unsolvable problems 
and would forever quit programming in D and switch over to 
QuickBasic again.

It was more just a survey about the general opinion in the 
community. And as an intermediate result (which is not even close 
to be representive), the majority of the participants of this 
thread would like to have these added to the language, some just 
don't care and some don't like the idea at all.

From those who didn't like the idea the most heared 
counter-argument was more like: "I know my code, i have written 
it, so i know which method modifies which parameters. I don't 
need this it makes me do more work."

Which in my opinion is a bit shortsighted since in commercial 
development or in general when you work in a team you don't 
program in isolation and you have to  often use 
third-party-frameworks were you don't have written every method 
by yourself. That's why the Microsoft language designer added 
this to C# and you even find this in a simulated way in C++ 
realised with references and pointers.

The only valid counter-arguments brought up so far, were possible 
breakage of code (when it would be enforced) and maybe UCFS.


> As I am not language religious, I just use them the way the
> language provides them.


The good thing here in the open source world is that we are not 
bound to the decision of a big committee. It's not "you'll eat 
what's put in front of you".

If a bigger part of the D community would like to have these 
annotations added to the language, at least as an optional 
feature, then that might persuade our "benevolent dictators" 
(just joking - you are great!) Walther and Andrei to add them or 
we could just make a fork of the language and add them ourselves 
(more joking - no, just skip this last part - it's late) :-)

There might be other problems, maybe with the compiler internals 
or breakage of parts of the language. These were severe. But i 
think only Walther and Andrei might tell. If these wouldn't exist 
it would at least be possible, how David proposed it in his post, 
to make them optional.

At the end that won't stop me or any other poster from 
programming in D. It would just really be nice to see this little 
extra of parameter checking at least optionally in D since with 
all the other safeness-features like safeD, contracts, etc. it 
would be a good addition to the language.
September 13, 2012
Re: Would like to see ref and out required for function calls
On 9/13/12 1:02 AM, Manuel wrote:
> If a bigger part of the D community would like to have these annotations
> added to the language, at least as an optional feature, then that might
> persuade our "benevolent dictators" (just joking - you are great!)
> Walther and Andrei to add them or we could just make a fork of the
> language and add them ourselves (more joking - no, just skip this last
> part - it's late) :-)
>
> There might be other problems, maybe with the compiler internals or
> breakage of parts of the language. These were severe. But i think only
> Walther and Andrei might tell. If these wouldn't exist it would at least
> be possible, how David proposed it in his post, to make them optional.

I don't think there would be problems with allowing ref/out optionally 
at the call site. The thing is, however, that in this matter reasonable 
people may disagree. In C++, the equivalent argument (should we pass 
everything modifiable by pointer or not?) erupts every six months on 
internal fora at Facebook. No winning argument is made by either part. 
For example, it is often brought up that it's good to see "&" at the 
call site when debugging some urgent matter at 3am. Yet there are other 
people who are just as apt at debugging urgent matters at 3am, and the 
absence of "&" doesn't seem to be a handicap for them at all. I'd be 
unable to identify any pattern in engineers choosing one preference over 
the other. As a consequence, our code has a mix of pass-by-pointer and 
pass-by-reference-to-nonconst, all engineers manage either style just as 
well, and we've never been able to find any evidence pointing one way or 
another.

Now that the subject has been broken, we do have good evidence of a 
pattern that generates significant and difficult bugs: escaping the 
address of a reference. In C++:

struct A {
    A(int& host) : host_(host) {}
private:
    int& host_;
};

In D:

class A { // or struct
    A(ref int host) : _host(&host) {}
private:
    int* _host;
}

A solution we use for C++ is to require escaped addresses to be always 
passed as pointers or smart pointers.

Walter and I have discussed this for quite a while. We have recently 
decided to disallow, at least in SafeD, escaping the address of a ref 
parameter. In the beginning we'll be overly conservative by disallowing 
taking the address of a ref altogether. I'll write a DIP on that soon.


Andrei
September 13, 2012
Re: Would like to see ref and out required for function calls
In D:

class A { // or struct
    A(ref int host) : _host(&host) { }
private:
    int* _host;
}

Since when do we have initialization lists in D? ;)

at topic: +1
1 2 3 4 5 6 7
Top | Discussion index | About this forum | D home