digitalmars.D - Tagging of arguments ref/out, or just out
- bearophile (39/39) Aug 07 2011 This is a recently opened (not by me) enhancement request thread:
- Max Klyga (8/86) Aug 07 2011 One the main reasons c# has mandatory out and ref at call site is code
- bearophile (7/10) Aug 07 2011 On this, what I have suggested it not the same thing that the original p...
- Don (3/9) Aug 08 2011 Please bury forever the idea that "mandatory when compiled with -w" has
- Michel Fortin (35/64) Aug 08 2011 I don't find your arguments very enticing, sorry. But I do see *one*
- Timon Gehr (10/74) Aug 08 2011 void getopt(T...)(ref string[] args, ref T opts);
- Kagamin (4/16) Aug 08 2011 const opts = getopt(args);
- Kagamin (3/3) Aug 08 2011 Though I think, `main` arguments should eliminated altogether and be acc...
- Michel Fortin (11/29) Aug 08 2011 Thanks for the tip.
- kenji hara (2/66) Aug 08 2011
- Kagamin (2/4) Aug 08 2011 D is the language to save keystrokes. This proposal is plain invalid.
- KennyTM~ (11/15) Aug 08 2011 I disagree. If you want to save keystrokes, use Perl.
- Kagamin (2/3) Aug 08 2011 Perl is dynamically typed, right? D is statically typed, so it can stati...
- Ziad Hatahet (8/13) Aug 08 2011 FWIW, Google's C++ style guide explicitly requires passing pointers to
- bearophile (5/8) Aug 08 2011 It's here:
- Jonathan M Davis (8/13) Aug 08 2011 We're not going to reject a feature proposal simply because it involves ...
This is a recently opened (not by me) enhancement request thread: http://d.puremagic.com/issues/show_bug.cgi?id=6442 It proposes something that I remember was discussed and refused two times in past: to require (but only optionally!) "ref" and "out" at the calling point, void foo(ref int bar) { ... } int i = 0; foo(ref i); // <------- here void foo(out int bar) { ... } int i = 0; foo(out i); // <------- here Jonathan M Davis has then argued that they clutter the code, and that making them optional makes them kind of useless. See the thread for more details. ----------------- After thinking some about it, I have suggested a related but alternative proposal: to ask only for the "out" at the calling point, make it obligatory if you compile with -warning and optional otherwise (for a long time "override" was like this). I think having "out" at the calling point is more useful than "ref". Currently D 2.054 gives no warnings/errors on a program like this (I think the void foo(out int x) { x = 5; } void main() { int y = 10; foo(y); } The problem here is the initialization of y to 10 always gets ignored. Assigning something to y, *not using y in any way*, and then using it in a "out" function argument call, is in my opinion a code smell. It's wasted code at best, and sometimes it's related to possible semantic bugs. Using "out" at the calling point doesn't fix that code, but helps the programmer to see that the assign of 10 to y is useless, and it's better to remove it: void foo(out int x) { x = 5; } void main() { int y = 10; foo(out y); } In my opinion "ref" arguments don't have the same need of being tagged at the calling point because a function that uses "ref" often reads and writes the argument (otherwise you use "in" or "out"), so in a ref argument assigning something to y before the call is more often meaningful: void foo(ref int x) { x++; } int main() { int y = 10; return foo(y); } Bye, bearophile
Aug 07 2011
versioning. If some function took an argument by value but was changed to take if by reference, without annotations compiler would treat this as an error, preventing a potential bug. So this feature has to be either mandatory or not. Making it optional leads to confusion as Jonathan mentioned. But it's kinda late to change the language now, with all the code outthere. On 2011-08-07 23:42:30 +0300, bearophile said:This is a recently opened (not by me) enhancement request thread: http://d.puremagic.com/issues/show_bug.cgi?id=6442 It proposes something that I remember was discussed and refused two times in past: to require (but only optionally!) "ref" and "out" at the void foo(ref int bar) { ... } int i = 0; foo(ref i); // <------- here void foo(out int bar) { ... } int i = 0; foo(out i); // <------- here Jonathan M Davis has then argued that they clutter the code, and that making them optional makes them kind of useless. See the thread for more details. ----------------- After thinking some about it, I have suggested a related but alternative proposal: to ask only for the "out" at the calling point, make it obligatory if you compile with -warning and optional otherwise (for a long time "override" was like this). I think having "out" at the calling point is more useful than "ref". Currently D 2.054 gives no warnings/errors on a program like this (I void foo(out int x) { x = 5; } void main() { int y = 10; foo(y); } The problem here is the initialization of y to 10 always gets ignored. Assigning something to y, *not using y in any way*, and then using it in a "out" function argument call, is in my opinion a code smell. It's wasted code at best, and sometimes it's related to possible semantic bugs. Using "out" at the calling point doesn't fix that code, but helps the programmer to see that the assign of 10 to y is useless, and it's better to remove it: void foo(out int x) { x = 5; } void main() { int y = 10; foo(out y); } In my opinion "ref" arguments don't have the same need of being tagged at the calling point because a function that uses "ref" often reads and writes the argument (otherwise you use "in" or "out"), so in a ref argument assigning something to y before the call is more often meaningful: void foo(ref int x) { x++; } int main() { int y = 10; return foo(y); } Bye, bearophile
Aug 07 2011
Max Klyga:So this feature has to be either mandatory or not. Making it optional leads to confusion as Jonathan mentioned.On this, what I have suggested it not the same thing that the original proposal says. In the original proposal the "ref" and "out" are optional. In my alternative proposal if you compile with "-w" you are sure that the compiler will ask you "out" at the calling point too.But it's kinda late to change the language now, with all the code outthere.It will take some more years to have enough D2 code out there to make a breaking but incremental change like this too much costly for people. (In Bugzilla I have few more little breaking changes that are more important than this "out" thing. And other things will need to be fixed, in "const" etc. Several of them will break D code in ways more costly than requiring to add a "out" in code here and there). Bye, bearophile
Aug 07 2011
bearophile wrote:Max Klyga:Please bury forever the idea that "mandatory when compiled with -w" has any practical difference from "mandatory".So this feature has to be either mandatory or not. Making it optional leads to confusion as Jonathan mentioned.On this, what I have suggested it not the same thing that the original proposal says. In the original proposal the "ref" and "out" are optional. In my alternative proposal if you compile with "-w" you are sure that the compiler will ask you "out" at the calling point too.
Aug 08 2011
On 2011-08-07 20:42:30 +0000, bearophile <bearophileHUGS lycos.com> said:This is a recently opened (not by me) enhancement request thread: http://d.puremagic.com/issues/show_bug.cgi?id=6442 It proposes something that I remember was discussed and refused two times in past: to require (but only optionally!) "ref" and "out" at the void foo(ref int bar) { ... } int i = 0; foo(ref i); // <------- here void foo(out int bar) { ... } int i = 0; foo(out i); // <------- here Jonathan M Davis has then argued that they clutter the code, and that making them optional makes them kind of useless. See the thread for more details. ----------------- After thinking some about it, I have suggested a related but alternative proposal: to ask only for the "out" at the calling point, make it obligatory if you compile with -warning and optional otherwise (for a long time "override" was like this). I think having "out" at the calling point is more useful than "ref". […]I don't find your arguments very enticing, sorry. But I do see *one* solid reason we might want to add 'ref' and 'out', optional or not, at the call site: variadic templates. I recently had to use getopt. You use it like that: bool option; int counter; getopt(args, "option|o", &option, "counter|c", &counter); The problem is that taking addresses of a stack variable is disabled in SafeD, which means getopt doesn't work in SafeD, which puts SafeD in a strange position. It'd work if we used 'ref' parameters. The problem is that getopt is defined like this: void getopt(T...)(ref string[] args, T opts); Using a type tuple makes it impossible to have 'ref's where they need to be, hence the use of pointers. Type tuples could be made support propagating the type including the 'ref' or 'out' storage class applied on them, which would allow you to write this: getopt!(string, ref bool, string, ref int)(args, "option|o", option, "counter|c", counter); But that doesn't work with type deduction. It could work however if you allowed specifying the 'ref' as part of the argument list: getopt(args, "option|o", ref option, "counter|c", ref counter); I'd prefer if we had a solution that doesn't require you to write 'ref' at the call site, but I haven't found any. Ideas? -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Aug 08 2011
Michel Fortin wrote:On 2011-08-07 20:42:30 +0000, bearophile <bearophileHUGS lycos.com> said:void getopt(T...)(ref string[] args, ref T opts); Would work afaik (but all the flag names would be passed by ref too). std.stdio.readf has the same issue. The general problem is that type deduction does not currently work too well with implicit conversions (that is also the reason why most string algorithms in Phobos don't work with immutable strings) I can see a possible solution to the problem: At definition side, it should be possible to manually influence type and storage class deduction. But I cannot think of syntax for this that wouldn't look awkward. Any ideas?This is a recently opened (not by me) enhancement request thread: http://d.puremagic.com/issues/show_bug.cgi?id=6442 It proposes something that I remember was discussed and refused two times in past: to require (but only optionally!) "ref" and "out" at the void foo(ref int bar) { ... } int i = 0; foo(ref i); // <------- here void foo(out int bar) { ... } int i = 0; foo(out i); // <------- here Jonathan M Davis has then argued that they clutter the code, and that making them optional makes them kind of useless. See the thread for more details. ----------------- After thinking some about it, I have suggested a related but alternative proposal: to ask only for the "out" at the calling point, make it obligatory if you compile with -warning and optional otherwise (for a long time "override" was like this). I think having "out" at the calling point is more useful than "ref". […]I don't find your arguments very enticing, sorry. But I do see *one* solid reason we might want to add 'ref' and 'out', optional or not, at the call site: variadic templates. I recently had to use getopt. You use it like that: bool option; int counter; getopt(args, "option|o", &option, "counter|c", &counter); The problem is that taking addresses of a stack variable is disabled in SafeD, which means getopt doesn't work in SafeD, which puts SafeD in a strange position. It'd work if we used 'ref' parameters. The problem is that getopt is defined like this: void getopt(T...)(ref string[] args, T opts); Using a type tuple makes it impossible to have 'ref's where they need to be, hence the use of pointers. Type tuples could be made support propagating the type including the 'ref' or 'out' storage class applied on them, which would allow you to write this: getopt!(string, ref bool, string, ref int)(args, "option|o", option, "counter|c", counter); But that doesn't work with type deduction. It could work however if you allowed specifying the 'ref' as part of the argument list: getopt(args, "option|o", ref option, "counter|c", ref counter); I'd prefer if we had a solution that doesn't require you to write 'ref' at the call site, but I haven't found any. Ideas? -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Aug 08 2011
Michel Fortin Wrote:I recently had to use getopt. You use it like that: bool option; int counter; getopt(args, "option|o", &option, "counter|c", &counter); The problem is that taking addresses of a stack variable is disabled in SafeD, which means getopt doesn't work in SafeD, which puts SafeD in a strange position.const opts = getopt(args); const option = opts.get!bool("option|o"); const counter = opts.get!int("counter|c"); // also reusable
Aug 08 2011
Though I think, `main` arguments should eliminated altogether and be accessed statically. const ReusableOpts opts = getopts(); const string[] args = mainArgs; // property: parse args on demand, remove the code from startup.
Aug 08 2011
On 2011-08-08 18:30:10 +0000, Kagamin <spam here.lot> said:Michel Fortin Wrote:Thanks for the tip. That said it doesn't invalidate my complain about 'ref' and 'out' being unusable in conjunction with type tuple arguments. If you're going to write a function that forwards its parameters to another function, using a type tuple to make it generic will fail in the presence of 'ref' and 'out' parameters in the wrapped function. -- Michel Fortin michel.fortin michelf.com http://michelf.com/I recently had to use getopt. You use it like that: bool option; int counter; getopt(args, "option|o", &option, "counter|c", &counter); The problem is that taking addresses of a stack variable is disabled in SafeD, which means getopt doesn't work in SafeD, which puts SafeD in a strange position.const opts = getopt(args); const option = opts.get!bool("option|o"); const counter = opts.get!int("counter|c"); // also reusable
Aug 08 2011
I think we can use "auto ref". 2011/08/08 21:45 "Michel Fortin" <michel.fortin michelf.com>:On 2011-08-07 20:42:30 +0000, bearophile <bearophileHUGS lycos.com> said:This is a recently opened (not by me) enhancement request thread: http://d.puremagic.com/issues/show_bug.cgi?id=3D6442 It proposes something that I remember was discussed and refused two times in past: to require (but only optionally!) "ref" and "out" at the void foo(ref int bar) { ... } int i =3D 0; foo(ref i); // <------- here void foo(out int bar) { ... } int i =3D 0; foo(out i); // <------- here Jonathan M Davis has then argued that they clutter the code, and that making them optional makes them kind of useless. See the thread for more details. ----------------- After thinking some about it, I have suggested a related but alternative proposal: to ask only for the "out" at the calling point, make it obligatory if you compile with -warning and optional otherwise (for a long time "override" was like this). I think having "out" at the calling point is more useful than "ref". [=85]I don't find your arguments very enticing, sorry. But I do see *one* solid reason we might want to add 'ref' and 'out', optional or not, at the call site: variadic templates. I recently had to use getopt. You use it like that: bool option; int counter; getopt(args, "option|o", &option, "counter|c", &counter); The problem is that taking addresses of a stack variable is disabled in SafeD, which means getopt doesn't work in SafeD, which puts SafeD in a strange position. It'd work if we used 'ref' parameters. The problem is that getopt is defined like this: void getopt(T...)(ref string[] args, T opts); Using a type tuple makes it impossible to have 'ref's where they need to be, hence the use of pointers. Type tuples could be made support propagating the type including the 'ref' or 'out' storage class applied on them, which would allow you to write this: getopt!(string, ref bool, string, ref int)(args, "option|o", option, "counter|c", counter); But that doesn't work with type deduction. It could work however if you allowed specifying the 'ref' as part of the argument list: getopt(args, "option|o", ref option, "counter|c", ref counter); I'd prefer if we had a solution that doesn't require you to write 'ref' at the call site, but I haven't found any. Ideas? -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Aug 08 2011
bearophile Wrote:This is a recently opened (not by me) enhancement request thread: http://d.puremagic.com/issues/show_bug.cgi?id=6442D is the language to save keystrokes. This proposal is plain invalid.
Aug 08 2011
On Aug 9, 11 02:32, Kagamin wrote:bearophile Wrote:I disagree. If you want to save keystrokes, use Perl. "D is a multi-paradigm programming language that combines a principled approach with a focus on practicality. In D you get to harness the power and high performance of C and C++ and also the safety and programmer productivity of modern languages such as Ruby and Python. Special attention is given to the needs of quality assurance, documentation, portability, and reliability." Nowhere mentions saving keystrokes. The proposal is OK, as a mean to provide reliability (where you ensure a variable passed is not modified in opaque because it is pass by 'ref') and documentation at call-site.This is a recently opened (not by me) enhancement request thread: http://d.puremagic.com/issues/show_bug.cgi?id=6442D is the language to save keystrokes. This proposal is plain invalid.
Aug 08 2011
KennyTM~ Wrote:I disagree. If you want to save keystrokes, use Perl.Perl is dynamically typed, right? D is statically typed, so it can statically check most things like out variables won't overwrite const arguments.
Aug 08 2011
FWIW, Google's C++ style guide explicitly requires passing pointers to arguments (whenever possible) when they are to be modified or used as out parameters, and passed by const& when they are not. This makes it more obvious at the caller's end which parameters are going to be modified and which ones aren't. -- Ziad On Mon, Aug 8, 2011 at 12:23 PM, Kagamin <spam here.lot> wrote:KennyTM~ Wrote:I disagree. If you want to save keystrokes, use Perl.Perl is dynamically typed, right? D is statically typed, so it can statically check most things like out variables won't overwrite const arguments.
Aug 08 2011
Ziad Hatahet:FWIW, Google's C++ style guide explicitly requires passing pointers to arguments (whenever possible) when they are to be modified or used as out parameters, and passed by const& when they are not.It's here: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Reference_Arguments Bye, bearophile
Aug 08 2011
bearophile Wrote:We're not going to reject a feature proposal simply because it involves more typing (unless it's excessive). What matters are what overall advantages and disadvantages it provides. Saving keystrokes is nice, but it's generally not enough of a reason to accept or reject a feature proposal. D does generally let you do more in less code than C++, but saving keystrokes is just a nice bonus on top of everything else that it provides, not the reason for its existance. - Jonathan M DavisThis is a recently opened (not by me) enhancement request thread: http://d.puremagic.com/issues/show_bug.cgi?id=6442D is the language to save keystrokes. This proposal is plain invalid.
Aug 08 2011