digitalmars.D - Explicitly saying ref or out when invoking a function
- Ary Borenszweig <ary esperanto.org.ar> Aug 11 2009
- Lutger <lutger.blijdestijn gmail.com> Aug 11 2009
- bearophile <bearophileHUGS lycos.com> Aug 11 2009
- BCS <ao pathlink.com> Aug 11 2009
- bearophile <bearophileHUGS lycos.com> Aug 11 2009
- Edward Diener <eddielee_no_spam_here tropicsoft.com> Aug 11 2009
- Denis Koroskin <2korden gmail.com> Aug 11 2009
- Jarrett Billingsley <jarrett.billingsley gmail.com> Aug 11 2009
- Michiel Helvensteijn <m.helvensteijn.remove gmail.com> Aug 11 2009
- Bill Baxter <wbaxter gmail.com> Aug 11 2009
- "Steven Schveighoffer" <schveiguy yahoo.com> Aug 11 2009
- Bill Baxter <wbaxter gmail.com> Aug 11 2009
- "Adam D. Ruppe" <destructionator gmail.com> Aug 11 2009
- Jeremie Pelletier <jeremiep gmail.com> Aug 11 2009
- "Lionello Lunesu" <lionello lunesu.remove.com> Aug 12 2009
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Aug 12 2009
- Ary Borenszweig <ary esperanto.org.ar> Aug 12 2009
- "Lionello Lunesu" <lionello lunesu.remove.com> Aug 12 2009
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Aug 12 2009
- "Lionello Lunesu" <lionello lunesu.remove.com> Aug 13 2009
- Ary Borenszweig <ary esperanto.org.ar> Aug 12 2009
- Jarrett Billingsley <jarrett.billingsley gmail.com> Aug 11 2009
- soso <vcd9900123 hotmail.com> Aug 11 2009
In C# when you define a function that takes an out or ref parameter, when invoking that function you must also specify ref or out. For example: void fun(ref uint x, double y); uint a = 1; double b = 2; fun(ref a, b); When I first started using C# it really annoyed me that I had to put that keyword there just to get my program compiled. "I know what I'm doing", I thought. But later, when reading the code, I found it very helpful to know that my "a" could be changed when invoking "fun". As always, code is read much more times than written, and I think this little tips help better understand the code. What do you think?
Aug 11 2009
Ary Borenszweig wrote:In C# when you define a function that takes an out or ref parameter, when invoking that function you must also specify ref or out. For example: void fun(ref uint x, double y); uint a = 1; double b = 2; fun(ref a, b); When I first started using C# it really annoyed me that I had to put that keyword there just to get my program compiled. "I know what I'm doing", I thought. But later, when reading the code, I found it very helpful to know that my "a" could be changed when invoking "fun". As always, code is read much more times than written, and I think this little tips help better understand the code. What do you think?
I'm not sure. However, you could implement something like this in descent without having to type all that or change D ;) Change the color of the parameter or something like that...
Aug 11 2009
Ary Borenszweig:What do you think?
I don't know. It's a different design choice. Generally explicit is better and safer, but I don't know much safer this is. Overall I think the C# choice here is a bit better, but you have to write lot of code before being able to tell C# has chosen for the better. Another similar design choice is that in C# a method that overrides another one must have the attribute "override", while in D it's optional. Now in C#4 you can omit the "ref" in the call point if it's a COM type, this leads to tricks: http://msmvps.com/blogs/jon_skeet/archive/2009/07/07/faking-com-to-fool-the-c-compiler.aspx Bye, bearophile
Aug 11 2009
Reply to Ary,In C# when you define a function that takes an out or ref parameter, when invoking that function you must also specify ref or out. For example: void fun(ref uint x, double y); uint a = 1; double b = 2; fun(ref a, b); When I first started using C# it really annoyed me that I had to put that keyword there just to get my program compiled. "I know what I'm doing", I thought. But later, when reading the code, I found it very helpful to know that my "a" could be changed when invoking "fun". As always, code is read much more times than written, and I think this little tips help better understand the code. What do you think?
It would make template programming harder. template TplFn(alias fn) { void TplFn(T...)(T t) { fn(t); // what if fn has normal, ref and out args? } }
Aug 11 2009
BCS Wrote:It would make template programming harder. template TplFn(alias fn) { void TplFn(T...)(T t) { fn(t); // what if fn has normal, ref and out args? } }
There's an intermediate solution, to make "ref" optional at the calling site (as in the "override" case). I don't know how much this can improve the situation. Bye, bearophile
Aug 11 2009
Ary Borenszweig wrote:In C# when you define a function that takes an out or ref parameter, when invoking that function you must also specify ref or out. For example: void fun(ref uint x, double y); uint a = 1; double b = 2; fun(ref a, b); When I first started using C# it really annoyed me that I had to put that keyword there just to get my program compiled. "I know what I'm doing", I thought. But later, when reading the code, I found it very helpful to know that my "a" could be changed when invoking "fun". As always, code is read much more times than written, and I think this little tips help better understand the code. What do you think?
C#'s requirement is just stupid.
Aug 11 2009
Ary Borenszweig Wrote:In C# when you define a function that takes an out or ref parameter, when invoking that function you must also specify ref or out. For example: void fun(ref uint x, double y); uint a = 1; double b = 2; fun(ref a, b); When I first started using C# it really annoyed me that I had to put that keyword there just to get my program compiled. "I know what I'm doing", I thought. But later, when reading the code, I found it very helpful to know that my "a" could be changed when invoking "fun". As always, code is read much more times than written, and I think this little tips help better understand the code. What do you think?
IIRC, this is no more a case as of C# 3.0
Aug 11 2009
On Tue, Aug 11, 2009 at 11:40 AM, Ary Borenszweig<ary esperanto.org.ar> wrote:In C# when you define a function that takes an out or ref parameter, when invoking that function you must also specify ref or out. For example: void fun(ref uint x, double y); uint a = 1; double b = 2; fun(ref a, b); When I first started using C# it really annoyed me that I had to put that keyword there just to get my program compiled. "I know what I'm doing", I thought. But later, when reading the code, I found it very helpful to know that my "a" could be changed when invoking "fun". As always, code is read much more times than written, and I think this little tips help better understand the code. What do you think?
I suggested it ages ago and still think it would be a nice requirement.
Aug 11 2009
Ary Borenszweig wrote:In C# when you define a function that takes an out or ref parameter, when invoking that function you must also specify ref or out. For example: void fun(ref uint x, double y); uint a = 1; double b = 2; fun(ref a, b); What do you think?
I see what you mean, however: ----- swap(ref a, ref b); I think that's overly verbose for a call with very descriptive function name to begin with. ----- Perhaps an IDE can use formatting to show you the ref parameters. ----- The designer of the function can always request pointers, so the caller has to explicitly pass addresses. -- Michiel Helvensteijn
Aug 11 2009
On Tue, Aug 11, 2009 at 12:47 PM, Michiel Helvensteijn<m.helvensteijn.remove gmail.com> wrote:Ary Borenszweig wrote:In C# when you define a function that takes an out or ref parameter, when invoking that function you must also specify ref or out. For example: void fun(ref uint x, double y); uint a = 1; double b = 2; fun(ref a, b); What do you think?
I see what you mean, however: ----- swap(ref a, ref b); I think that's overly verbose for a call with very descriptive function name to begin with.
I don't think that looks so bad. It's not like swap is used in even 1 out of 100 lines of code generally. And it's not an expression either, so it generally is written on a line all by itself.----- The designer of the function can always request pointers, so the caller has to explicitly pass addresses.
But pointers can be null. Refs cannot. That's one big advantage of ref args. Of course if D gets non-nullable pointers... Anyway, I generally like the idea of requiring 'ref' on the call side. But I doubt Walter will go for it. He didn't the last time it was suggested. --bb
Aug 11 2009
On Tue, 11 Aug 2009 15:47:15 -0400, Michiel Helvensteijn <m.helvensteijn.remove gmail.com> wrote:Ary Borenszweig wrote:In C# when you define a function that takes an out or ref parameter, when invoking that function you must also specify ref or out. For example: void fun(ref uint x, double y); uint a = 1; double b = 2; fun(ref a, b); What do you think?
I see what you mean, however: ----- swap(ref a, ref b);
I tend to agree with this, most of the time, your function name hints at what is a reference and what is not. If this is implemented, then a ref const argument should not require a ref keyword to call (since there is no way to change it in the function). One thing about C# is that most everything is pass-by-reference anyways, so the ref and out, keywords are not common. However, in D I think the tendency to lean towards value types, and indicate pass by ref for performance means that code will get a lot uglier if this were to be implemented. This is just a gut feeling, I haven't done a true study. -Steve
Aug 11 2009
On Tue, Aug 11, 2009 at 1:05 PM, Nick Sabalausky<a a.a> wrote:"Ary Borenszweig" <ary esperanto.org.ar> wrote in message news:h5s3e9$2kml$1 digitalmars.com...In C# when you define a function that takes an out or ref parameter, when invoking that function you must also specify ref or out. For example: void fun(ref uint x, double y); uint a = 1; double b = 2; fun(ref a, b); When I first started using C# it really annoyed me that I had to put that keyword there just to get my program compiled. "I know what I'm doing", I thought. But later, when reading the code, I found it very helpful to know that my "a" could be changed when invoking "fun". As always, code is read much more times than written, and I think this little tips help better understand the code. What do you think?
That's something I've always liked about C# and always wanted in D. Although, what some people have said about just coloring it in an editor is not a bad point (althogh it seems like we may be starting to run out of colors...).
No problem, we can resurrect <BLINK>! --bb
Aug 11 2009
On Tue, Aug 11, 2009 at 04:28:06PM -0400, bearophile wrote:There's an intermediate solution, to make "ref" optional at the calling site (as in the "override" case). I don't know how much this can improve the situation.
That seems to me to defeat the point, since you can't rely on it anymore.Bye, bearophile
-- Adam D. Ruppe http://arsdnet.net
Aug 11 2009
Ary Borenszweig Wrote:In C# when you define a function that takes an out or ref parameter, when invoking that function you must also specify ref or out. For example: void fun(ref uint x, double y); uint a = 1; double b = 2; fun(ref a, b); When I first started using C# it really annoyed me that I had to put that keyword there just to get my program compiled. "I know what I'm doing", I thought. But later, when reading the code, I found it very helpful to know that my "a" could be changed when invoking "fun". As always, code is read much more times than written, and I think this little tips help better understand the code. What do you think?
I think it's overkill, and it still doesn't say if the ref is const or mutable. Much like in C/C++ when you pass a pointer you dont know if its a const or mutable parameter unless you look at the function declaration. It's especially bad since if you modify the function prototype and change ref, you have all your calls to update too.
Aug 11 2009
"Jeremie Pelletier" <jeremiep gmail.com> wrote in message news:h5sl4c$1733$1 digitalmars.com...It's especially bad since if you modify the function prototype and change ref, you have all your calls to update too.
That must be the best argument to introduce repeating ref and out! L.
Aug 12 2009
Lionello Lunesu wrote:"Jeremie Pelletier" <jeremiep gmail.com> wrote in message news:h5sl4c$1733$1 digitalmars.com...It's especially bad since if you modify the function prototype and change ref, you have all your calls to update too.
That must be the best argument to introduce repeating ref and out! L.
// untested struct Ref(T) { private T* _data; this(ref T data) { _data = &data; } ref T get() { assert(_data); return *_data; } alias get this; } Ref!(T) byRef(ref T data) { return Ref!(T)(data); } ... void fun(Ref!int rint) { ... } ... int x; fun(byRef(x)); Andrei
Aug 12 2009
Andrei Alexandrescu escribió:Lionello Lunesu wrote:"Jeremie Pelletier" <jeremiep gmail.com> wrote in message news:h5sl4c$1733$1 digitalmars.com...It's especially bad since if you modify the function prototype and change ref, you have all your calls to update too.
That must be the best argument to introduce repeating ref and out! L.
// untested struct Ref(T) { private T* _data; this(ref T data) { _data = &data; } ref T get() { assert(_data); return *_data; } alias get this; } Ref!(T) byRef(ref T data) { return Ref!(T)(data); } ... void fun(Ref!int rint) { ... } ... int x; fun(byRef(x)); Andrei
Have you heard about standardization? ;-) But yeah, there's the problem with functions in templated code... I don't know what to do with that...
Aug 12 2009
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:h5ttfi$cf3$1 digitalmars.com...Lionello Lunesu wrote:"Jeremie Pelletier" <jeremiep gmail.com> wrote in message news:h5sl4c$1733$1 digitalmars.com...It's especially bad since if you modify the function prototype and change ref, you have all your calls to update too.
That must be the best argument to introduce repeating ref and out! L.
// untested struct Ref(T) { private T* _data; this(ref T data) { _data = &data; } ref T get() { assert(_data); return *_data; } alias get this; } Ref!(T) byRef(ref T data) { return Ref!(T)(data); } ... void fun(Ref!int rint) { ... } ... int x; fun(byRef(x));
Andrei, you bring the compiler vs library discussion to a whole new level :) We can add "ref" to the list of keywords that can be freed up. L.
Aug 12 2009
Lionello Lunesu wrote:"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:h5ttfi$cf3$1 digitalmars.com...Lionello Lunesu wrote:"Jeremie Pelletier" <jeremiep gmail.com> wrote in message news:h5sl4c$1733$1 digitalmars.com...It's especially bad since if you modify the function prototype and change ref, you have all your calls to update too.
That must be the best argument to introduce repeating ref and out! L.
// untested struct Ref(T) { private T* _data; this(ref T data) { _data = &data; } ref T get() { assert(_data); return *_data; } alias get this; } Ref!(T) byRef(ref T data) { return Ref!(T)(data); } ... void fun(Ref!int rint) { ... } ... int x; fun(byRef(x));
Andrei, you bring the compiler vs library discussion to a whole new level :) We can add "ref" to the list of keywords that can be freed up.
Good point, but actually ref can't be freed, because it would fall prey to infinite regression: if there was no ref keyword, how would you pass by reference the argument to the byRef function? Andrei
Aug 12 2009
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:h5vtj8$1l7b$1 digitalmars.com...Lionello Lunesu wrote:"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:h5ttfi$cf3$1 digitalmars.com...Lionello Lunesu wrote:"Jeremie Pelletier" <jeremiep gmail.com> wrote in message news:h5sl4c$1733$1 digitalmars.com...It's especially bad since if you modify the function prototype and change ref, you have all your calls to update too.
That must be the best argument to introduce repeating ref and out! L.
// untested struct Ref(T) { private T* _data; this(ref T data) { _data = &data; } ref T get() { assert(_data); return *_data; } alias get this; } Ref!(T) byRef(ref T data) { return Ref!(T)(data); } ... void fun(Ref!int rint) { ... } ... int x; fun(byRef(x));
Andrei, you bring the compiler vs library discussion to a whole new level :) We can add "ref" to the list of keywords that can be freed up.
Good point, but actually ref can't be freed, because it would fall prey to infinite regression: if there was no ref keyword, how would you pass by reference the argument to the byRef function?
Uh...... make it an alias parameter and take the address of it? or something... Needs IFTI to work nicely with aliases, not sure if it can be done.. L.
Aug 13 2009
Lionello Lunesu escribió:"Jeremie Pelletier" <jeremiep gmail.com> wrote in message news:h5sl4c$1733$1 digitalmars.com...It's especially bad since if you modify the function prototype and change ref, you have all your calls to update too.
That must be the best argument to introduce repeating ref and out!
No, that's one of the best argument to introduce it. See Nick's reply.
Aug 12 2009
On Tue, Aug 11, 2009 at 4:05 PM, Nick Sabalausky<a a.a> wrote:Although, what some people have said about just coloring it in an editor is not a bad point (althogh it seems like we may be starting to run out of colors...).
If your syntax highlighting is using so many colors that you're worried about running out, then your syntax highlighting is using too many colors ;) I never understood why some syntax highlighters make your code look like a goddamned rainbow threw up on it. There are so many colors that they stop meaning anything. Kate's default D highlighting scheme comes to mind as a particularly heinous offender. Do we really need different colors for 1, 0x1, 0b1, 01, and 1.0? They're all numbers. How about different highlighting for *every kind of string literal*?
Aug 11 2009
Ary Borenszweig Wrote:In C# when you define a function that takes an out or ref parameter, when invoking that function you must also specify ref or out. For example: void fun(ref uint x, double y); uint a = 1; double b = 2; fun(ref a, b); What do you think?
I agree
Aug 11 2009









Lutger <lutger.blijdestijn gmail.com> 