www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Call site 'ref'

reply =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <xtzgzorex gmail.com> writes:
Hi,

I don't know how many times I've made the mistake of passing a local 
variable to a function which takes a 'ref' parameter. Suddenly, local 
variables/fields are just mutating out of nowhere, because it's not at 
all obvious that a function you're calling is taking a 'ref' parameter. 
This is particularly true for std.utf.decode().

Yes, I realize I could look at the function declaration. Yes, I could 
read the docs too. But that doesn't prevent me from forgetting that a 
function takes a 'ref' parameter, and then doing the mistake again. The 
damage is done, and the time is wasted.

I think D should allow 'ref' on call sites to prevent these mistakes. 
For example:

string str = ...;
size_t pos;
auto chr = std.utf.decode(str, ref pos);

Now it's much more obvious that the parameter is passed by reference and 
is going to be mutated.

Ideally, this would not be optional, but rather *required*, but I 
realize that such a change would break a *lot* of code, so that's 
probably not a good idea.

Thoughts?

-- 
- Alex
Jan 15 2012
next sibling parent reply Johnatan Frakes <123 COM.COM> writes:
You are, lazy, sir, and your programming license should be revoked.

By that logic we should dull all knives because somebody might get hurt.

My 2c.
Jan 15 2012
next sibling parent reply Peter Alexander <peter.alexander.au gmail.com> writes:
On 15/01/12 1:56 PM, Johnatan Frakes wrote:
 You are, lazy, sir, and your programming license should be revoked.

 By that logic we should dull all knives because somebody might get hurt.

 My 2c.

This has nothing to do with laziness. It's an error-detection mechanism, just like many other language features (e.g. override, const, immutable, shared, ...). I agree with requiring ref at the call site in principle, although it would be too much of a breaking change to introduce now. Perhaps allow it, and issue a warning if not used?
Jan 15 2012
next sibling parent =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <xtzgzorex gmail.com> writes:
On 15-01-2012 15:12, Peter Alexander wrote:
 On 15/01/12 1:56 PM, Johnatan Frakes wrote:
 You are, lazy, sir, and your programming license should be revoked.

 By that logic we should dull all knives because somebody might get hurt.

 My 2c.

This has nothing to do with laziness. It's an error-detection mechanism, just like many other language features (e.g. override, const, immutable, shared, ...). I agree with requiring ref at the call site in principle, although it would be too much of a breaking change to introduce now. Perhaps allow it, and issue a warning if not used?

That sounds reasonable to me. Maybe make it a compiler option like -property though? -callsiteref? Something like that. -- - Alex
Jan 15 2012
prev sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
On 15/01/2012 14:12, Peter Alexander wrote:
<snip>
 I agree with requiring ref at the call site in principle, although it would be
too much of
 a breaking change to introduce now. Perhaps allow it, and issue a warning if
not used?

Maybe phase it in in this sequence: 1. Allow ref/out at call site. 2. Add a warning for if ref/out at call site is omitted. 3. Deprecate omitting ref/out at call site. 4. Require ref/out at call site. 5. Allow overloading of functions based on parameter storage class, as much as makes sense. Stewart.
Jan 17 2012
prev sibling parent =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <xtzgzorex gmail.com> writes:
On 15-01-2012 14:56, Johnatan Frakes wrote:
 You are, lazy, sir, and your programming license should be revoked.

 By that logic we should dull all knives because somebody might get hurt.

 My 2c.

By your logic, we should remove all compiler checks that help avoid typical mistakes. This is not about one extreme or another; it's about striking the right balance. This is not the first time this issue has been brought up, and there's a reason for that. -- - Alex
Jan 15 2012
prev sibling next sibling parent reply "F i L" <witte2008 gmail.com> writes:
Alex Rønne Petersen wrote:
 Ideally, this would not be optional, but rather *required*, but 
 I realize that such a change would break a *lot* of code, so 
 that's probably not a good idea.

 Thoughts?

Good idea, but it should be optional. On by default maybe, but optional.
Jan 15 2012
parent =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= <xtzgzorex gmail.com> writes:
On 15-01-2012 15:05, F i L wrote:
 Alex Rønne Petersen wrote:
 Ideally, this would not be optional, but rather *required*, but I
 realize that such a change would break a *lot* of code, so that's
 probably not a good idea.

 Thoughts?

Good idea, but it should be optional. On by default maybe, but optional.

Absolutely. It would break way too much code if it was made an error. I think Peter Alexander's suggestion would work nicely. -- - Alex
Jan 15 2012
prev sibling next sibling parent reply dsimcha <dsimcha yahoo.com> writes:
On 1/15/2012 8:36 AM, Alex Rnne Petersen wrote:
 Hi,

 I don't know how many times I've made the mistake of passing a local
 variable to a function which takes a 'ref' parameter. Suddenly, local
 variables/fields are just mutating out of nowhere, because it's not at
 all obvious that a function you're calling is taking a 'ref' parameter.
 This is particularly true for std.utf.decode().

 Yes, I realize I could look at the function declaration. Yes, I could
 read the docs too. But that doesn't prevent me from forgetting that a
 function takes a 'ref' parameter, and then doing the mistake again. The
 damage is done, and the time is wasted.

 I think D should allow 'ref' on call sites to prevent these mistakes.
 For example:

 string str = ...;
 size_t pos;
 auto chr = std.utf.decode(str, ref pos);

 Now it's much more obvious that the parameter is passed by reference and
 is going to be mutated.

 Ideally, this would not be optional, but rather *required*, but I
 realize that such a change would break a *lot* of code, so that's
 probably not a good idea.

 Thoughts?

This would break UFCS severely. The following would no longer work: auto arr = [1, 2, 3, 4, 5]; arr.popFront(); // popFront takes arr by ref
Jan 15 2012
parent reply Peter Alexander <peter.alexander.au gmail.com> writes:
On 15/01/12 3:19 PM, dsimcha wrote:
 On 1/15/2012 8:36 AM, Alex Rnne Petersen wrote:
 Hi,

 I don't know how many times I've made the mistake of passing a local
 variable to a function which takes a 'ref' parameter. Suddenly, local
 variables/fields are just mutating out of nowhere, because it's not at
 all obvious that a function you're calling is taking a 'ref' parameter.
 This is particularly true for std.utf.decode().

 Yes, I realize I could look at the function declaration. Yes, I could
 read the docs too. But that doesn't prevent me from forgetting that a
 function takes a 'ref' parameter, and then doing the mistake again. The
 damage is done, and the time is wasted.

 I think D should allow 'ref' on call sites to prevent these mistakes.
 For example:

 string str = ...;
 size_t pos;
 auto chr = std.utf.decode(str, ref pos);

 Now it's much more obvious that the parameter is passed by reference and
 is going to be mutated.

 Ideally, this would not be optional, but rather *required*, but I
 realize that such a change would break a *lot* of code, so that's
 probably not a good idea.

 Thoughts?

This would break UFCS severely. The following would no longer work: auto arr = [1, 2, 3, 4, 5]; arr.popFront(); // popFront takes arr by ref

Unless it was ignored for UFCS, which is reasonable, since foo.bar() looks like it could modify foo whereas bar(foo) doesn't in general.
Jan 15 2012
parent =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <xtzgzorex gmail.com> writes:
On 15-01-2012 16:47, Peter Alexander wrote:
 On 15/01/12 3:19 PM, dsimcha wrote:
 On 1/15/2012 8:36 AM, Alex Rnne Petersen wrote:
 Hi,

 I don't know how many times I've made the mistake of passing a local
 variable to a function which takes a 'ref' parameter. Suddenly, local
 variables/fields are just mutating out of nowhere, because it's not at
 all obvious that a function you're calling is taking a 'ref' parameter.
 This is particularly true for std.utf.decode().

 Yes, I realize I could look at the function declaration. Yes, I could
 read the docs too. But that doesn't prevent me from forgetting that a
 function takes a 'ref' parameter, and then doing the mistake again. The
 damage is done, and the time is wasted.

 I think D should allow 'ref' on call sites to prevent these mistakes.
 For example:

 string str = ...;
 size_t pos;
 auto chr = std.utf.decode(str, ref pos);

 Now it's much more obvious that the parameter is passed by reference and
 is going to be mutated.

 Ideally, this would not be optional, but rather *required*, but I
 realize that such a change would break a *lot* of code, so that's
 probably not a good idea.

 Thoughts?

This would break UFCS severely. The following would no longer work: auto arr = [1, 2, 3, 4, 5]; arr.popFront(); // popFront takes arr by ref

Unless it was ignored for UFCS, which is reasonable, since foo.bar() looks like it could modify foo whereas bar(foo) doesn't in general.

Agreed. -- - Alex
Jan 15 2012
prev sibling next sibling parent reply "Robert Jacques" <sandford jhu.edu> writes:
On Sun, 15 Jan 2012 07:36:53 -0600, Alex Rnne Petersen <xtzgzorex gmail.com>
wrote:
 Hi,

 I don't know how many times I've made the mistake of passing a local
 variable to a function which takes a 'ref' parameter. Suddenly, local
 variables/fields are just mutating out of nowhere, because it's not at
 all obvious that a function you're calling is taking a 'ref' parameter.
 This is particularly true for std.utf.decode().

 Yes, I realize I could look at the function declaration. Yes, I could
 read the docs too. But that doesn't prevent me from forgetting that a
 function takes a 'ref' parameter, and then doing the mistake again. The
 damage is done, and the time is wasted.

 I think D should allow 'ref' on call sites to prevent these mistakes.
 For example:

 string str = ...;
 size_t pos;
 auto chr = std.utf.decode(str, ref pos);

 Now it's much more obvious that the parameter is passed by reference and
 is going to be mutated.

 Ideally, this would not be optional, but rather *required*, but I
 realize that such a change would break a *lot* of code, so that's
 probably not a good idea.

 Thoughts?

In no particular order: 1) Adding ref to the call site is lexically similar to Hungarian notation and has all the drawbacks and advantages thereof. I know invoking Hungarian notation is almost an invocation of Godwin's law when it comes to programming syntax discussions, but Hungarian notation was introduced for a reason; there was a time when for large software projects it dramatically increases code comprehension (and thus quality) for the code reviewer and/or code maintainer. And that argument still stand today for anyone _not_ using a modern IDE. The primary reason Hungarian notation is disparaged today is that IDEs evolved beyond emacs, vim and notepad. Once they could tell the programmer with a tooltip what every variable's type was, the need to encode the type in the variable name vanished. Or more to the original point, modern IDEs already list function parameter's type and type modifiers (i.e. aka) as you type the function in so it's _always_ obvious what is ref/const/etc and what is not. And for the code reviewer, ref parameters could be auto highlighted/underlined/etc to easy their job. Yes, this issue does need to be addressed, but I don't think that this is fundamentally a language problem; it more a lack of modern tools for D. That reminds me, I need to check out the latest revision of Visual D. :) 2) It is perfectly possible to write functions in D that require explicit demarcation at the call site: int foo( int* v ) { return *x; } int y; int z = foo( y); 3) Mandating ref at the call is currently how C# handles reference parameters. Anytime someone suggests a feature from another language, particularly C# or Java, two questions are immediately raised in my mind. 3a) Does the asker simply want D to be more like language X? 3b) What do programmers experienced in X and in D/C++/C/etc think about that particular feature (good/bad/ugly)? 4) When presenting problematic language use case and an associated proposed solution, being light on details/analysis and missing the second most obvious drawbacks of your proposed solution will cause your argument to be dismissed by many people. In short, if you're not willing to fully think through your idea, why should we take the time to too? That aside, if you are serious about this topic, you might want to have a look at/submit a D improvement proposal (http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs).
Jan 15 2012
next sibling parent reply Peter Alexander <peter.alexander.au gmail.com> writes:
On 15/01/12 5:57 PM, Robert Jacques wrote:
 On Sun, 15 Jan 2012 07:36:53 -0600, Alex Rnne Petersen
 Thoughts?

In no particular order: 1) Adding ref to the call site is lexically similar to Hungarian notation and has all the drawbacks and advantages thereof. I know invoking Hungarian notation is almost an invocation of Godwin's law when it comes to programming syntax discussions, but Hungarian notation was introduced for a reason; there was a time when for large software projects it dramatically increases code comprehension (and thus quality) for the code reviewer and/or code maintainer. And that argument still stand today for anyone _not_ using a modern IDE. The primary reason Hungarian notation is disparaged today is that IDEs evolved beyond emacs, vim and notepad. Once they could tell the programmer with a tooltip what every variable's type was, the need to encode the type in the variable name vanished. Or more to the original point, modern IDEs already list function parameter's type and type modifiers (i.e. aka) as you type the function in so it's _always_ obvious what is ref/const/etc and what is not. And for the code reviewer, ref parameters could be auto highlighted/underlined/etc to easy their job. Yes, this issue does need to be addressed, but I don't think that this is fundamentally a language problem; it more a lack of modern tools for D. That reminds me, I need to check out the latest revision of Visual D. :)

A fair point, but: a) D doesn't have much in terms of *free* highly-featured IDEs. b) Even if it did, lots of people still use emacs/vim. c) That does not help when glancing at code to find where a variable is modified.
 2) It is perfectly possible to write functions in D that require
 explicit demarcation at the call site:

 int foo( int* v ) { return *x; }

 int y;
 int z = foo( y);

True, but these aren't the same. Pointers can be reseated, ref parameters cannot. Pointers may also be null, encouraging needless null pointer checks.
 3) Mandating ref at the call is currently how C# handles reference
 parameters. Anytime someone suggests a feature from another language,
 particularly C# or Java, two questions are immediately raised in my mind.
 3a) Does the asker simply want D to be more like language X?

Perhaps, perhaps not. I think it is better to evaluate a suggestion on its merit and not on the suggester's motivation.
 3b) What do programmers experienced in X and in D/C++/C/etc think about
 that particular feature (good/bad/ugly)?

Mandated ref is well-received in C# as far as I'm aware. I also know that people dislike using reference parameters in C++ due to the lack of visibility at the call site (causing them to use pointers).
Jan 15 2012
parent reply Tobias Pankrath <tobias pankrath.net> writes:
 I also know that people dislike using reference parameters in C++ due to
 the lack of visibility at the call site (causing them to use pointers).

Which is true for me. Every single one of my reference parameters is const ref or pointer.
Jan 15 2012
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Tobias Pankrath:

 I also know that people dislike using reference parameters in C++ due to
 the lack of visibility at the call site (causing them to use pointers).

Which is true for me. Every single one of my reference parameters is const ref or pointer.

(What you do is also required by the Google C++ style guide.) So your experience favors the use of callsite "ref" for nonconst ref arguments :-) Bye, bearophile
Jan 15 2012
prev sibling parent Alvaro <alvaroDotSegura gmail.com> writes:
El 15/01/2012 20:04, Tobias Pankrath escribi:
 I also know that people dislike using reference parameters in C++ due to
 the lack of visibility at the call site (causing them to use pointers).

Which is true for me. Every single one of my reference parameters is const ref or pointer.

swap(ref a, ref b); // ?? No, thanks. swap(a, b); // obvious that the arguments will be mutated, and cleaner
Jan 15 2012
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Robert Jacques:

 1) Adding ref to the call site is lexically similar to Hungarian notation and
has all the drawbacks and advantages thereof.

The presence of "ref" at the call site is meant to be enforced by the type system of the compiler.
 Or more to the original point, modern IDEs already list function parameter's
type and type modifiers (i.e. aka) as you type the function in so it's _always_
obvious what is ref/const/etc and what is not.

C# is meant to be used with a modern IDE, yet it requires "ref" and "out" at the call site (but in some cases, where the use of ref is pervasive). Bye, bearophile
Jan 15 2012
prev sibling next sibling parent Mehrdad <wfunction hotmail.com> writes:
On 1/15/2012 5:36 AM, Alex Rnne Petersen wrote:
 Hi,

 I don't know how many times I've made the mistake of passing a local 
 variable to a function which takes a 'ref' parameter. Suddenly, local 
 variables/fields are just mutating out of nowhere, because it's not at 
 all obvious that a function you're calling is taking a 'ref' 
 parameter. This is particularly true for std.utf.decode().

 Yes, I realize I could look at the function declaration. Yes, I could 
 read the docs too. But that doesn't prevent me from forgetting that a 
 function takes a 'ref' parameter, and then doing the mistake again. 
 The damage is done, and the time is wasted.

 I think D should allow 'ref' on call sites to prevent these mistakes. 
 For example:

 string str = ...;
 size_t pos;
 auto chr = std.utf.decode(str, ref pos);

 Now it's much more obvious that the parameter is passed by reference 
 and is going to be mutated.

 Ideally, this would not be optional, but rather *required*, but I 
 realize that such a change would break a *lot* of code, so that's 
 probably not a good idea.

 Thoughts?

about aliens...
Jan 15 2012
prev sibling next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Alex Rnne Petersen" <xtzgzorex gmail.com> wrote in message 
news:jeukpm$168v$1 digitalmars.com...
 Hi,

 I don't know how many times I've made the mistake of passing a local 
 variable to a function which takes a 'ref' parameter. Suddenly, local 
 variables/fields are just mutating out of nowhere, because it's not at all 
 obvious that a function you're calling is taking a 'ref' parameter. This 
 is particularly true for std.utf.decode().

 Yes, I realize I could look at the function declaration. Yes, I could read 
 the docs too. But that doesn't prevent me from forgetting that a function 
 takes a 'ref' parameter, and then doing the mistake again. The damage is 
 done, and the time is wasted.

 I think D should allow 'ref' on call sites to prevent these mistakes. For 
 example:

 string str = ...;
 size_t pos;
 auto chr = std.utf.decode(str, ref pos);

 Now it's much more obvious that the parameter is passed by reference and 
 is going to be mutated.

 Ideally, this would not be optional, but rather *required*, but I realize 
 that such a change would break a *lot* of code, so that's probably not a 
 good idea.

 Thoughts?

Yes, this is one of the few things I always thought C# got right and D got wrong. That said though, I haven't personally run into this problem, and I've gotten used to not having "ref" or "out" on the caller's side. I wouldn't be opposed to the change though, even just as an optional warning.
Jan 15 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/15/2012 10:39 PM, Nick Sabalausky wrote:
 "Alex Rnne Petersen"<xtzgzorex gmail.com>  wrote in message
 news:jeukpm$168v$1 digitalmars.com...
 Hi,

 I don't know how many times I've made the mistake of passing a local
 variable to a function which takes a 'ref' parameter. Suddenly, local
 variables/fields are just mutating out of nowhere, because it's not at all
 obvious that a function you're calling is taking a 'ref' parameter. This
 is particularly true for std.utf.decode().

 Yes, I realize I could look at the function declaration. Yes, I could read
 the docs too. But that doesn't prevent me from forgetting that a function
 takes a 'ref' parameter, and then doing the mistake again. The damage is
 done, and the time is wasted.

 I think D should allow 'ref' on call sites to prevent these mistakes. For
 example:

 string str = ...;
 size_t pos;
 auto chr = std.utf.decode(str, ref pos);

 Now it's much more obvious that the parameter is passed by reference and
 is going to be mutated.

 Ideally, this would not be optional, but rather *required*, but I realize
 that such a change would break a *lot* of code, so that's probably not a
 good idea.

 Thoughts?

Yes, this is one of the few things I always thought C# got right and D got wrong.

I think both C# and D got it right.
 That said though, I haven't personally run into this problem, and I've
 gotten used to not having "ref" or "out" on the caller's side. I wouldn't be
 opposed to the change though, even just as an optional warning.

Jan 15 2012
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/15/2012 02:36 PM, Alex Rnne Petersen wrote:
 Hi,

 I don't know how many times I've made the mistake of passing a local
 variable to a function which takes a 'ref' parameter. Suddenly, local
 variables/fields are just mutating out of nowhere, because it's not at
 all obvious that a function you're calling is taking a 'ref' parameter.
 This is particularly true for std.utf.decode().

Odd. I always thought the fact that std.utf.decode modifies the second parameter is very intuitive. (decoding cannot work nicely without it)
 Yes, I realize I could look at the function declaration. Yes, I could
 read the docs too. But that doesn't prevent me from forgetting that a
 function takes a 'ref' parameter, and then doing the mistake again. The
 damage is done, and the time is wasted.

This is true for every part of a function interface. How can a programmer even understand what the function does if he forgets what the calling conventions are? Conversely, does a reminder of the calling conventions usually restore full knowledge of the semantics of the called function?
 I think D should allow 'ref' on call sites to prevent these mistakes.
 For example:

 string str = ...;
 size_t pos;
 auto chr = std.utf.decode(str, ref pos);

 Now it's much more obvious that the parameter is passed by reference and
 is going to be mutated.

 Ideally, this would not be optional, but rather *required*, but I
 realize that such a change would break a *lot* of code, so that's
 probably not a good idea.

 Thoughts?

I personally think 'ref' at call site is pure syntax noise but I see that it might be useful to some in some cases. I'd prefer to leave it as-is, but I don't feel very strongly for either way. My preference would be [not allowed > enforced > ... > optional > optional with switch] However, it is very important not to do this to 'lazy'. Another thing that would have to be discussed: what happens to const ref parameters? It is very reasonable that someone will decide to change calling conventions from by value to by const ref or the other way round after profiling. It is very convenient that such a change is syntactically transparent to the caller and this should stay. It is even realistic that someone will decide to interchange by ref/by value, because there is no way to express 'I will not change the head level' in the current type system other than taking a parameter by value. Therefore introducing call-site ref would perhaps necessitate re-introducing 'final' for variables.
Jan 15 2012
next sibling parent reply Peter Alexander <peter.alexander.au gmail.com> writes:
On 15/01/12 10:10 PM, Timon Gehr wrote:
 Another thing that would have to be discussed: what happens to const ref
 parameters? It is very reasonable that someone will decide to change
 calling conventions from by value to by const ref or the other way round
 after profiling. It is very convenient that such a change is
 syntactically transparent to the caller and this should stay.

Actually, that would be very dangerous. const ref does not have the privilege of being able to bind to rvalues in D like it does in C++. void foo(const ref int x) {...} foo(1); // this is legal in C++, but illegal in D In case, const ref would not require the ref at call site because there's no danger of it being modified.
Jan 15 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/15/2012 11:41 PM, Peter Alexander wrote:
 On 15/01/12 10:10 PM, Timon Gehr wrote:
 Another thing that would have to be discussed: what happens to const ref
 parameters? It is very reasonable that someone will decide to change
 calling conventions from by value to by const ref or the other way round
 after profiling. It is very convenient that such a change is
 syntactically transparent to the caller and this should stay.

Actually, that would be very dangerous. const ref does not have the privilege of being able to bind to rvalues in D like it does in C++. void foo(const ref int x) {...} foo(1); // this is legal in C++, but illegal in D

Who on earth wants to change an int parameter from by value to by const ref? struct literals can bind to const ref parameters so there is absolutely no issue.
 In case, const ref would not require the ref at call site because
 there's no danger of it being modified.

The semantics are still not the same.
Jan 15 2012
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/15/2012 11:36 PM, Timon Gehr wrote:
 On 01/15/2012 11:41 PM, Peter Alexander wrote:
 On 15/01/12 10:10 PM, Timon Gehr wrote:
 Another thing that would have to be discussed: what happens to const ref
 parameters? It is very reasonable that someone will decide to change
 calling conventions from by value to by const ref or the other way round
 after profiling. It is very convenient that such a change is
 syntactically transparent to the caller and this should stay.

Actually, that would be very dangerous. const ref does not have the privilege of being able to bind to rvalues in D like it does in C++. void foo(const ref int x) {...} foo(1); // this is legal in C++, but illegal in D

Who on earth wants to change an int parameter from by value to by const ref? struct literals can bind to const ref parameters so there is absolutely no issue.
 In case, const ref would not require the ref at call site because
 there's no danger of it being modified.

The semantics are still not the same.

(Even the claim that there is no danger of it being modified is plain wrong)
Jan 15 2012
prev sibling parent reply Peter Alexander <peter.alexander.au gmail.com> writes:
On 15/01/12 10:36 PM, Timon Gehr wrote:
 On 01/15/2012 11:41 PM, Peter Alexander wrote:
 On 15/01/12 10:10 PM, Timon Gehr wrote:
 Another thing that would have to be discussed: what happens to const ref
 parameters? It is very reasonable that someone will decide to change
 calling conventions from by value to by const ref or the other way round
 after profiling. It is very convenient that such a change is
 syntactically transparent to the caller and this should stay.

Actually, that would be very dangerous. const ref does not have the privilege of being able to bind to rvalues in D like it does in C++. void foo(const ref int x) {...} foo(1); // this is legal in C++, but illegal in D

Who on earth wants to change an int parameter from by value to by const ref? struct literals can bind to const ref parameters so there is absolutely no issue.

Are you sure about struct literals binding to const ref? I can't find anything in the language spec or TDPL that supports that claim. In fact, TDPL says: "If a function expects a ref, it accepts only "real" data, not temporaries; anything that's not an lvalue is rejected during compilation" Unfortunately it doesn't say anything explicitly about struct literals or const ref, but that would lead me to believe that they fall under the same rule. DMD allows struct literals to bind to const ref, but then again it also allows them to bind to ref, so I'm not sure how reliable that is. This should probably be clarified. It's kind of important.
Jan 15 2012
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/16/2012 12:39 AM, Peter Alexander wrote:
 On 15/01/12 10:36 PM, Timon Gehr wrote:
 On 01/15/2012 11:41 PM, Peter Alexander wrote:
 On 15/01/12 10:10 PM, Timon Gehr wrote:
 Another thing that would have to be discussed: what happens to const
 ref
 parameters? It is very reasonable that someone will decide to change
 calling conventions from by value to by const ref or the other way
 round
 after profiling. It is very convenient that such a change is
 syntactically transparent to the caller and this should stay.

Actually, that would be very dangerous. const ref does not have the privilege of being able to bind to rvalues in D like it does in C++. void foo(const ref int x) {...} foo(1); // this is legal in C++, but illegal in D

Who on earth wants to change an int parameter from by value to by const ref? struct literals can bind to const ref parameters so there is absolutely no issue.

Are you sure about struct literals binding to const ref? I can't find anything in the language spec or TDPL that supports that claim. In fact, TDPL says: "If a function expects a ref, it accepts only "real" data, not temporaries; anything that's not an lvalue is rejected during compilation"

Well, struct literals are lvalues, at least in DMD.
 Unfortunately it doesn't say anything explicitly about struct literals
 or const ref, but that would lead me to believe that they fall under the
 same rule.

 DMD allows struct literals to bind to const ref, but then again it also
 allows them to bind to ref, so I'm not sure how reliable that is.

 This should probably be clarified. It's kind of important.

I agree, but banning it would be an arbitrary and pointless restriction.
Jan 15 2012
parent reply Peter Alexander <peter.alexander.au gmail.com> writes:
On 15/01/12 11:56 PM, Jonathan M Davis wrote:
 On Monday, January 16, 2012 00:41:14 Timon Gehr wrote:
 Well, struct literals are lvalues, at least in DMD.

Yeah. I don't understand that. I've argued about it with Walter before. Apparently they are in C++ as well. I don't understand it. It makes it so that

In C++, struct literals are rvalues. C++ just has a special rule that const references can bind to rvalues (but non-const references cannot), and another special rule that when a const reference binds to a temporary it extends the life of the temporary. The benefit in C++ is so that you can write one function that takes a const reference and it works with rvalues as well as lvalues. Taking by value would be too expensive a lot of the time.
Jan 15 2012
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/16/2012 01:30 AM, Peter Alexander wrote:
 On 15/01/12 11:56 PM, Jonathan M Davis wrote:
 On Monday, January 16, 2012 00:41:14 Timon Gehr wrote:
 Well, struct literals are lvalues, at least in DMD.

Yeah. I don't understand that. I've argued about it with Walter before. Apparently they are in C++ as well. I don't understand it. It makes it so that

In C++, struct literals are rvalues. C++ just has a special rule that const references can bind to rvalues (but non-const references cannot), and another special rule that when a const reference binds to a temporary it extends the life of the temporary.

In C++, a struct literal can be on the lhs of an expression (because of the implicit copy assignment operator) but you cannot take it's address unless you pass it by const& ;D
 The benefit in C++ is so that you can write one function that takes a
 const reference and it works with rvalues as well as lvalues. Taking by
 value would be too expensive a lot of the time.

In D there is no such thing as a C++ const reference, therefore I think it is reasonable that struct literals are lvalues.
Jan 15 2012
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/15/12 6:30 PM, Peter Alexander wrote:
 On 15/01/12 11:56 PM, Jonathan M Davis wrote:
 On Monday, January 16, 2012 00:41:14 Timon Gehr wrote:
 Well, struct literals are lvalues, at least in DMD.

Yeah. I don't understand that. I've argued about it with Walter before. Apparently they are in C++ as well. I don't understand it. It makes it so that

In C++, struct literals are rvalues. C++ just has a special rule that const references can bind to rvalues (but non-const references cannot),

That's a bad rule that we shouldn't copy. Andrei
Jan 15 2012
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/16/2012 01:35 AM, Andrei Alexandrescu wrote:
 On 1/15/12 6:30 PM, Peter Alexander wrote:
 On 15/01/12 11:56 PM, Jonathan M Davis wrote:
 On Monday, January 16, 2012 00:41:14 Timon Gehr wrote:
 Well, struct literals are lvalues, at least in DMD.

Yeah. I don't understand that. I've argued about it with Walter before. Apparently they are in C++ as well. I don't understand it. It makes it so that

In C++, struct literals are rvalues. C++ just has a special rule that const references can bind to rvalues (but non-const references cannot),

That's a bad rule that we shouldn't copy. Andrei

What do you think is an optimal rule regarding struct literals/lvalues/rvalues and ref parameters?
Jan 15 2012
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/15/12 6:38 PM, Timon Gehr wrote:
 On 01/16/2012 01:35 AM, Andrei Alexandrescu wrote:
 On 1/15/12 6:30 PM, Peter Alexander wrote:
 On 15/01/12 11:56 PM, Jonathan M Davis wrote:
 On Monday, January 16, 2012 00:41:14 Timon Gehr wrote:
 Well, struct literals are lvalues, at least in DMD.

Yeah. I don't understand that. I've argued about it with Walter before. Apparently they are in C++ as well. I don't understand it. It makes it so that

In C++, struct literals are rvalues. C++ just has a special rule that const references can bind to rvalues (but non-const references cannot),

That's a bad rule that we shouldn't copy. Andrei

What do you think is an optimal rule regarding struct literals/lvalues/rvalues and ref parameters?

auto ref Andrei
Jan 15 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/16/2012 02:00 AM, Andrei Alexandrescu wrote:
 On 1/15/12 6:38 PM, Timon Gehr wrote:
 On 01/16/2012 01:35 AM, Andrei Alexandrescu wrote:
 On 1/15/12 6:30 PM, Peter Alexander wrote:
 On 15/01/12 11:56 PM, Jonathan M Davis wrote:
 On Monday, January 16, 2012 00:41:14 Timon Gehr wrote:
 Well, struct literals are lvalues, at least in DMD.

Yeah. I don't understand that. I've argued about it with Walter before. Apparently they are in C++ as well. I don't understand it. It makes it so that

In C++, struct literals are rvalues. C++ just has a special rule that const references can bind to rvalues (but non-const references cannot),

That's a bad rule that we shouldn't copy. Andrei

What do you think is an optimal rule regarding struct literals/lvalues/rvalues and ref parameters?

auto ref Andrei

But that only works for templates?
Jan 15 2012
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/15/12 7:21 PM, Timon Gehr wrote:
 On 01/16/2012 02:00 AM, Andrei Alexandrescu wrote:
 On 1/15/12 6:38 PM, Timon Gehr wrote:
 On 01/16/2012 01:35 AM, Andrei Alexandrescu wrote:
 On 1/15/12 6:30 PM, Peter Alexander wrote:
 On 15/01/12 11:56 PM, Jonathan M Davis wrote:
 On Monday, January 16, 2012 00:41:14 Timon Gehr wrote:
 Well, struct literals are lvalues, at least in DMD.

Yeah. I don't understand that. I've argued about it with Walter before. Apparently they are in C++ as well. I don't understand it. It makes it so that

In C++, struct literals are rvalues. C++ just has a special rule that const references can bind to rvalues (but non-const references cannot),

That's a bad rule that we shouldn't copy. Andrei

What do you think is an optimal rule regarding struct literals/lvalues/rvalues and ref parameters?

auto ref Andrei

But that only works for templates?

For non-templates, if it's important to distinguish between lvalues and rvalues, use two overloads. Andrei
Jan 18 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/18/2012 06:13 PM, Andrei Alexandrescu wrote:
 On 1/15/12 7:21 PM, Timon Gehr wrote:
 On 01/16/2012 02:00 AM, Andrei Alexandrescu wrote:
 On 1/15/12 6:38 PM, Timon Gehr wrote:
 On 01/16/2012 01:35 AM, Andrei Alexandrescu wrote:
 On 1/15/12 6:30 PM, Peter Alexander wrote:
 On 15/01/12 11:56 PM, Jonathan M Davis wrote:
 On Monday, January 16, 2012 00:41:14 Timon Gehr wrote:
 Well, struct literals are lvalues, at least in DMD.

Yeah. I don't understand that. I've argued about it with Walter before. Apparently they are in C++ as well. I don't understand it. It makes it so that

In C++, struct literals are rvalues. C++ just has a special rule that const references can bind to rvalues (but non-const references cannot),

That's a bad rule that we shouldn't copy. Andrei

What do you think is an optimal rule regarding struct literals/lvalues/rvalues and ref parameters?

auto ref Andrei

But that only works for templates?

For non-templates, if it's important to distinguish between lvalues and rvalues, use two overloads. Andrei

Currently 'auto ref' gives a compile error if used in a non-templated function parameter list. What are the semantics of 'auto ref' you have in mind? Are they specified somewhere?
Jan 18 2012
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/18/12 11:27 AM, Timon Gehr wrote:
 On 01/18/2012 06:13 PM, Andrei Alexandrescu wrote:
 For non-templates, if it's important to distinguish between lvalues and
 rvalues, use two overloads.

 Andrei

Currently 'auto ref' gives a compile error if used in a non-templated function parameter list. What are the semantics of 'auto ref' you have in mind? Are they specified somewhere?

I meant two overloads that don't use auto ref: void fun(S); void fun(ref S); Andrei
Jan 18 2012
prev sibling parent Peter Alexander <peter.alexander.au gmail.com> writes:
On 16/01/12 12:35 AM, Andrei Alexandrescu wrote:
 On 1/15/12 6:30 PM, Peter Alexander wrote:
 On 15/01/12 11:56 PM, Jonathan M Davis wrote:
 On Monday, January 16, 2012 00:41:14 Timon Gehr wrote:
 Well, struct literals are lvalues, at least in DMD.

Yeah. I don't understand that. I've argued about it with Walter before. Apparently they are in C++ as well. I don't understand it. It makes it so that

In C++, struct literals are rvalues. C++ just has a special rule that const references can bind to rvalues (but non-const references cannot),

That's a bad rule that we shouldn't copy.

I agree.
Jan 15 2012
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, January 16, 2012 00:41:14 Timon Gehr wrote:
 Well, struct literals are lvalues, at least in DMD.

Yeah. I don't understand that. I've argued about it with Walter before. Apparently they are in C++ as well. I don't understand it. It makes it so that void func(ref S val) S bar(); works with func(S(42)); but not func(bar()); It seems completely arbitrary to me that it works this way and has IMHO _zero_ benefits. And I know that newbies have run into the problem and been completely confused by it (e.g. http://stackoverflow.com/questions/6986175/const-ref-and- rvalue-in-d ). _I_'ve been confused by it. I was stunned to find out that there was _any_ difference in the language between a struct literal and an identical struct returned from a function. It's not as big an issue in C++, because using & is fairly rare in C++ unless its const, and const & will take temporaries. But in D, it's _definitely_ an issue IMHO. I really think that struct literals should be considered rvalues. I do _not_ understand why they aren't or why anyone ever thought that it was a good idea for them to be lvalues. - Jonathan M Davis
Jan 15 2012
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/15/2012 11:10 PM, Timon Gehr wrote:
 On 01/15/2012 02:36 PM, Alex Rnne Petersen wrote:
 Hi,

 I don't know how many times I've made the mistake of passing a local
 variable to a function which takes a 'ref' parameter. Suddenly, local
 variables/fields are just mutating out of nowhere, because it's not at
 all obvious that a function you're calling is taking a 'ref' parameter.
 This is particularly true for std.utf.decode().

Odd. I always thought the fact that std.utf.decode modifies the second parameter is very intuitive. (decoding cannot work nicely without it)
 Yes, I realize I could look at the function declaration. Yes, I could
 read the docs too. But that doesn't prevent me from forgetting that a
 function takes a 'ref' parameter, and then doing the mistake again. The
 damage is done, and the time is wasted.

This is true for every part of a function interface. How can a programmer even understand what the function does if he forgets what the calling conventions are? Conversely, does a reminder of the calling conventions usually restore full knowledge of the semantics of the called function?
 I think D should allow 'ref' on call sites to prevent these mistakes.
 For example:

 string str = ...;
 size_t pos;
 auto chr = std.utf.decode(str, ref pos);

 Now it's much more obvious that the parameter is passed by reference and
 is going to be mutated.

 Ideally, this would not be optional, but rather *required*, but I
 realize that such a change would break a *lot* of code, so that's
 probably not a good idea.

 Thoughts?

I personally think 'ref' at call site is pure syntax noise but I see that it might be useful to some in some cases. I'd prefer to leave it as-is, but I don't feel very strongly for either way. My preference would be [not allowed > enforced > ... > optional > optional with switch] However, it is very important not to do this to 'lazy'. Another thing that would have to be discussed: what happens to const ref parameters? It is very reasonable that someone will decide to change calling conventions from by value to by const ref or the other way round after profiling. It is very convenient that such a change is syntactically transparent to the caller and this should stay. It is even realistic that someone will decide to interchange by ref/by value, because there is no way to express 'I will not change the head level' in the current type system other than taking a parameter by value. Therefore introducing call-site ref would perhaps necessitate re-introducing 'final' for variables.

Oh, and furthermore it would give rise to abominations such as: auto ref wrap(alias foo,T...)(auto ref T args){ return foo(auto ref args); } *shudder*. What does 'auto ref' even mean if 'ref' is required for ref parameters at call site? I think the best answers would silently break existing code.
Jan 15 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, January 15, 2012 14:36:53 Alex R=C3=B8nne Petersen wrote:
 Thoughts?

This was discussed before, and I'm still completely against it. It _onl= y_ has=20 value IMHO if it's required, and even then, I don't like the idea. If it's _not_ required, then you don't know _still_ don't know whether = a=20 function takes a ref or not. The lack of ref at the call site means _no= thing_.=20 Does func(var); alter var? You can't know. If it's func(ref var); then yes, you _do_ know that it's being altered. But this just gives yo= u a=20 false sense of security. You _still_ need to check _every_ function cal= l which=20 isn't marked with ref whether it takes its arguments by ref or not. If = it were=20 required, then you would know that func(var); doesn't take var by ref and that func(ref var); _does_ take var by ref. So, in that case, it's _not_ a false sense of=20= security. It _actually_ guarantees something. So, it _does_ have some v= alue in=20 that case. But as long as it's optional, it's worse than not having it = IMHO. Now, personally, I don't like it regardless. It's makes function calls = that=20 much noisier at minimal benefit. Yes, upon occasion, I screw up and don= 't=20 realize that a function takes an argument by ref, but that's something = that I=20 _should_ know. It has a definite effect on what the function does, and = I should=20 be aware of it. So, I'm completely against this feature. - Jonathan M Davis
Jan 15 2012
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Sun, 15 Jan 2012 12:27:46 -0600, Peter Alexander
<peter.alexander.au gmail.com> wrote:
 On 15/01/12 5:57 PM, Robert Jacques wrote:
 On Sun, 15 Jan 2012 07:36:53 -0600, Alex Rnne Petersen
 Thoughts?

In no particular order: 1) Adding ref to the call site is lexically similar to Hungarian notation and has all the drawbacks and advantages thereof. I know invoking Hungarian notation is almost an invocation of Godwin's law when it comes to programming syntax discussions, but Hungarian notation was introduced for a reason; there was a time when for large software projects it dramatically increases code comprehension (and thus quality) for the code reviewer and/or code maintainer. And that argument still stand today for anyone _not_ using a modern IDE. The primary reason Hungarian notation is disparaged today is that IDEs evolved beyond emacs, vim and notepad. Once they could tell the programmer with a tooltip what every variable's type was, the need to encode the type in the variable name vanished. Or more to the original point, modern IDEs already list function parameter's type and type modifiers (i.e. aka) as you type the function in so it's _always_ obvious what is ref/const/etc and what is not. And for the code reviewer, ref parameters could be auto highlighted/underlined/etc to easy their job. Yes, this issue does need to be addressed, but I don't think that this is fundamentally a language problem; it more a lack of modern tools for D. That reminds me, I need to check out the latest revision of Visual D. :)

A fair point, but: a) D doesn't have much in terms of *free* highly-featured IDEs.

 b) Even if it did, lots of people still use emacs/vim.

 c) That does not help when glancing at code to find where a variable is
 modified.

 2) It is perfectly possible to write functions in D that require
 explicit demarcation at the call site:

 int foo( int* v ) { return *x; }

 int y;
 int z = foo( y);

True, but these aren't the same. Pointers can be reseated, ref parameters cannot.

Well, if the final storage class was brought back into the language...
 Pointers may also be null, encouraging needless null
 pointer checks.

Needless null pointer checks are only a possible problem in release code; assert solves that problem nicely.
 3) Mandating ref at the call is currently how C# handles reference
 parameters. Anytime someone suggests a feature from another language,
 particularly C# or Java, two questions are immediately raised in my mind.
 3a) Does the asker simply want D to be more like language X?

Perhaps, perhaps not. I think it is better to evaluate a suggestion on its merit and not on the suggester's motivation.

Before I can evaluate your use case, let alone your suggestion I need to understand and filter your biases. It's really important to understand how much of a poster's frustration simply come from the cognitive disconnect between two different programming languages and the actual features and capabilities of D.
 3b) What do programmers experienced in X and in D/C++/C/etc think about
 that particular feature (good/bad/ugly)?

Mandated ref is well-received in C# as far as I'm aware.

And C# has never had non mandated ref; this is both a good and bad thing. It's a bad thing as a positive response to ref gets mixed with mandated ref. It's good thing because there's probably a developer blog or two you could link too providing good support by industry experts for your argument.
 I also know that people dislike using reference parameters in C++ due to
 the lack of visibility at the call site (causing them to use pointers).

From the C++ FQA on references: "Note: Old line C programmers sometimes don't like references since they provide reference semantics that isn't explicit in the caller's code. After some C++ experience, however, one quickly realizes this is a form of information hiding, which is an asset rather than a liability. E.g., programmers should write code in the language of the problem rather than the language of the machine." From Google's Style Guidelines: Within function parameter lists all references must be const: void Foo(const string &in, string *out); In fact it is a very strong convention in Google code that input arguments are values or const references while output arguments are pointers. Input parameters may be const pointers, but we never allow non-const reference parameters.
Jan 15 2012
prev sibling next sibling parent reply Mail Mantis <mail.mantis.88 gmail.com> writes:
2012/1/15 Alex R=F8nne Petersen <xtzgzorex gmail.com>:
 Hi,

 I don't know how many times I've made the mistake of passing a local
 variable to a function which takes a 'ref' parameter. Suddenly, local
 variables/fields are just mutating out of nowhere, because it's not at al=

 obvious that a function you're calling is taking a 'ref' parameter. This =

 particularly true for std.utf.decode().

 Yes, I realize I could look at the function declaration. Yes, I could rea=

 the docs too. But that doesn't prevent me from forgetting that a function
 takes a 'ref' parameter, and then doing the mistake again. The damage is
 done, and the time is wasted.

 I think D should allow 'ref' on call sites to prevent these mistakes. For
 example:

 string str =3D ...;
 size_t pos;
 auto chr =3D std.utf.decode(str, ref pos);

 Now it's much more obvious that the parameter is passed by reference and =

 going to be mutated.

 Ideally, this would not be optional, but rather *required*, but I realize
 that such a change would break a *lot* of code, so that's probably not a
 good idea.

 Thoughts?

 --
 - Alex

I don't see how call cite ref will help the issue. If you don't read ddoc, how will you know what exactly function does with it's ref parameter - statistically? Knowing that function takes parameter by ref doesn't help understanding it's logic. Also, knowing that function doesn't take any ref parameters doesn't mean you don't need to read it's documentation.
Jan 15 2012
next sibling parent reply =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <xtzgzorex gmail.com> writes:
On 16-01-2012 02:37, Mail Mantis wrote:
 2012/1/15 Alex Rnne Petersen<xtzgzorex gmail.com>:
 Hi,

 I don't know how many times I've made the mistake of passing a local
 variable to a function which takes a 'ref' parameter. Suddenly, local
 variables/fields are just mutating out of nowhere, because it's not at all
 obvious that a function you're calling is taking a 'ref' parameter. This is
 particularly true for std.utf.decode().

 Yes, I realize I could look at the function declaration. Yes, I could read
 the docs too. But that doesn't prevent me from forgetting that a function
 takes a 'ref' parameter, and then doing the mistake again. The damage is
 done, and the time is wasted.

 I think D should allow 'ref' on call sites to prevent these mistakes. For
 example:

 string str = ...;
 size_t pos;
 auto chr = std.utf.decode(str, ref pos);

 Now it's much more obvious that the parameter is passed by reference and is
 going to be mutated.

 Ideally, this would not be optional, but rather *required*, but I realize
 that such a change would break a *lot* of code, so that's probably not a
 good idea.

 Thoughts?

 --
 - Alex

I don't see how call cite ref will help the issue. If you don't read ddoc, how will you know what exactly function does with it's ref parameter - statistically? Knowing that function takes parameter by ref doesn't help understanding it's logic. Also, knowing that function doesn't take any ref parameters doesn't mean you don't need to read it's documentation.

You may remember what the function does, but forget that it mutates an input parameter. -- - Alex
Jan 15 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/16/2012 08:31 AM, Alex Rnne Petersen wrote:
 On 16-01-2012 02:37, Mail Mantis wrote:
 2012/1/15 Alex Rnne Petersen<xtzgzorex gmail.com>:
 Hi,

 I don't know how many times I've made the mistake of passing a local
 variable to a function which takes a 'ref' parameter. Suddenly, local
 variables/fields are just mutating out of nowhere, because it's not
 at all
 obvious that a function you're calling is taking a 'ref' parameter.
 This is
 particularly true for std.utf.decode().

 Yes, I realize I could look at the function declaration. Yes, I could
 read
 the docs too. But that doesn't prevent me from forgetting that a
 function
 takes a 'ref' parameter, and then doing the mistake again. The damage is
 done, and the time is wasted.

 I think D should allow 'ref' on call sites to prevent these mistakes.
 For
 example:

 string str = ...;
 size_t pos;
 auto chr = std.utf.decode(str, ref pos);

 Now it's much more obvious that the parameter is passed by reference
 and is
 going to be mutated.

 Ideally, this would not be optional, but rather *required*, but I
 realize
 that such a change would break a *lot* of code, so that's probably not a
 good idea.

 Thoughts?

 --
 - Alex

I don't see how call cite ref will help the issue. If you don't read ddoc, how will you know what exactly function does with it's ref parameter - statistically? Knowing that function takes parameter by ref doesn't help understanding it's logic. Also, knowing that function doesn't take any ref parameters doesn't mean you don't need to read it's documentation.

You may remember what the function does, but forget that it mutates an input parameter. -- - Alex

This statement is self-contradictory.
Jan 16 2012
prev sibling parent Mehrdad <wfunction hotmail.com> writes:
On 1/15/2012 5:37 PM, Mail Mantis wrote:
 I don't see how call cite ref will help the issue. If you don't read 
 ddoc, how will you know what exactly function does with it's ref 
 parameter - statistically? Knowing that function takes parameter by 
 ref doesn't help understanding it's logic. Also, knowing that function 
 doesn't take any ref parameters doesn't mean you don't need to read 
 it's documentation. 

?!?!? Documentation is frequently out of date, but code isn't. And ideally, the code wouldn't NEED documentation, BECAUSE it SAYS what it's doing.
Jan 16 2012
prev sibling parent Mail Mantis <mail.mantis.88 gmail.com> writes:
2012/1/17 Mehrdad <wfunction hotmail.com>:
 ?!?!?

 Documentation is frequently out of date, but code isn't.
 And ideally, the code wouldn't NEED documentation, BECAUSE it SAYS what it's
 doing.

Maybe - if you have access to function's source text. But we were talking about a specific feature on callers side. "ref" stated at call site doesn't say what function is doing, it only tells that function returns one of it's results in specific parameter. That might be occasionally useful, but it is not worth extra syntax it introduces.
Jan 16 2012