std.getopt suggestion
Okay. I have a suggestion for an improvement to std.getopt that I think merits a bit of discussion. There's currently a pull request with some improvements for getopt which are mostly internal changes rather than API changes ( https://github.com/D-Programming-Language/phobos/pull/272 ), but I think that there is an API change that we should consider. Right now, there are three configuration options which are mutable module-level variables: dchar optionChar = '-'; string endOfOptions = "--"; dchar assignChar = '='; and the aforementioned pull request adds another for an array separator. Mutable module/global variables are generally considered to be bad design (though they're sometimes necessary), and I'm very much inclined to have those variables _not_ be at the module scope like that. So, my suggestion is that we create a GetOpt struct which contains all of the options for getopt, and we make getopt a member function of that struct. That way, if you're doing any configuration to getopt, you create a GetOpt object, set whatever properties you want to set on it, and call getopt on it - much cleaner than setting module-level variables. However, because you generally don't care about setting options on getopt, we then have a getopt function which is a free function (as we do now) which internally uses GetOpt.init and calls its getopt. So, it improves the configuration situation but leaves the usage of std.getopt to be pretty much the same if you don't want to mess with the default configuration. Does anyone think that that's a bad idea for any particular reason? Personally, I think that it's a significant improvement given that it's getting rid of the mutable module-level variables and better encapsulating getopt's functionality, but I think that there's some value in discussing the idea first. Also, it gives us a good opportunity to rename getopt to getOpt (so that it's properly camelcased per Phobos' naming conventions) as well as change any defaults which need changing. For instance, the aforementioned pull request adds a noSpaceOnlyForShortNumericOptions option, which it then recommends using but doesn't make the default, because it would break code. With this change, we could make it the default (with the old getopt function still using the current behavior for as long as its around). Personally, I'd also like to see bundling be the default, since that's how most command line programs work (at least on Posix), but regardless, renaming getopt to getOpt gives us a good opportunity to change some of the defaults if appropriate. In any case, the primary question is whether the basic idea of creating a GetOpt struct for configuring getOpt, making getOpt a member function of it, and then having a free function getOpt which uses GetOpt.init seems like a good idea or whether anyone can come up with a good reason why it _wouldn't_ be a good idea. - Jonathan M Davis
Re: std.getopt suggestion
On 2011-09-28 21:44, Jonathan M Davis wrote: Okay. I have a suggestion for an improvement to std.getopt that I think merits a bit of discussion. There's currently a pull request with some improvements for getopt which are mostly internal changes rather than API changes ( https://github.com/D-Programming-Language/phobos/pull/272 ), but I think that there is an API change that we should consider. Right now, there are three configuration options which are mutable module-level variables: dchar optionChar = '-'; string endOfOptions = "--"; dchar assignChar = '='; and the aforementioned pull request adds another for an array separator. Mutable module/global variables are generally considered to be bad design (though they're sometimes necessary), and I'm very much inclined to have those variables _not_ be at the module scope like that. So, my suggestion is that we create a GetOpt struct which contains all of the options for getopt, and we make getopt a member function of that struct. That way, if you're doing any configuration to getopt, you create a GetOpt object, set whatever properties you want to set on it, and call getopt on it - much cleaner than setting module-level variables. However, because you generally don't care about setting options on getopt, we then have a getopt function which is a free function (as we do now) which internally uses GetOpt.init and calls its getopt. So, it improves the configuration situation but leaves the usage of std.getopt to be pretty much the same if you don't want to mess with the default configuration. Does anyone think that that's a bad idea for any particular reason? Personally, I think that it's a significant improvement given that it's getting rid of the mutable module-level variables and better encapsulating getopt's functionality, but I think that there's some value in discussing the idea first. Also, it gives us a good opportunity to rename getopt to getOpt (so that it's properly camelcased per Phobos' naming conventions) as well as change any defaults which need changing. For instance, the aforementioned pull request adds a noSpaceOnlyForShortNumericOptions option, which it then recommends using but doesn't make the default, because it would break code. With this change, we could make it the default (with the old getopt function still using the current behavior for as long as its around). Personally, I'd also like to see bundling be the default, since that's how most command line programs work (at least on Posix), but regardless, renaming getopt to getOpt gives us a good opportunity to change some of the defaults if appropriate. In any case, the primary question is whether the basic idea of creating a GetOpt struct for configuring getOpt, making getOpt a member function of it, and then having a free function getOpt which uses GetOpt.init seems like a good idea or whether anyone can come up with a good reason why it _wouldn't_ be a good idea. - Jonathan M Davis Sounds like a good idea. -- /Jacob Carlborg
Re: std.getopt suggestion
"Jonathan M Davis" wrote in message news:mailman.260.1317239096.26225.digitalmar...@puremagic.com... > Okay. I have a suggestion for an improvement to std.getopt that I think > merits > a bit of discussion. There's currently a pull request with some > improvements > for getopt which are mostly internal changes rather than API changes ( > https://github.com/D-Programming-Language/phobos/pull/272 ), but I think > that > there is an API change that we should consider. > > Right now, there are three configuration options which are mutable > module-level > variables: > > dchar optionChar = '-'; > string endOfOptions = "--"; > dchar assignChar = '='; > > and the aforementioned pull request adds another for an array separator. > Mutable module/global variables are generally considered to be bad design > (though they're sometimes necessary), and I'm very much inclined to have > those > variables _not_ be at the module scope like that. > > So, my suggestion is that we create a GetOpt struct which contains all of > the > options for getopt, and we make getopt a member function of that struct. > That > way, if you're doing any configuration to getopt, you create a GetOpt > object, > set whatever properties you want to set on it, and call getopt on it - > much > cleaner than setting module-level variables. However, because you > generally > don't care about setting options on getopt, we then have a getopt function > which is a free function (as we do now) which internally uses GetOpt.init > and > calls its getopt. So, it improves the configuration situation but leaves > the > usage of std.getopt to be pretty much the same if you don't want to mess > with > the default configuration. > > Does anyone think that that's a bad idea for any particular reason? > Personally, I think that it's a significant improvement given that it's > getting > rid of the mutable module-level variables and better encapsulating > getopt's > functionality, but I think that there's some value in discussing the idea > first. > > Also, it gives us a good opportunity to rename getopt to getOpt (so that > it's > properly camelcased per Phobos' naming conventions) as well as change any > defaults which need changing. For instance, the aforementioned pull > request > adds a noSpaceOnlyForShortNumericOptions option, which it then recommends > using but doesn't make the default, because it would break code. With this > change, we could make it the default (with the old getopt function still > using > the current behavior for as long as its around). Personally, I'd also like > to > see bundling be the default, since that's how most command line programs > work > (at least on Posix), but regardless, renaming getopt to getOpt gives us a > good > opportunity to change some of the defaults if appropriate. > > In any case, the primary question is whether the basic idea of creating a > GetOpt struct for configuring getOpt, making getOpt a member function of > it, > and then having a free function getOpt which uses GetOpt.init seems like a > good idea or whether anyone can come up with a good reason why it > _wouldn't_ > be a good idea. > I like it. I wonder if having the GetOpt struct's defaults being different from getopt() might be confusing. Other than that, I can't think of any issues with any of it, unless there was some other aspect of the API we'd want to change, too.
Re: std.getopt suggestion
On Wednesday, September 28, 2011 13:59 Nick Sabalausky wrote: > I like it. I wonder if having the GetOpt struct's defaults being different > from getopt() might be confusing. Other than that, I can't think of any > issues with any of it, unless there was some other aspect of the API we'd > want to change, too. getOpt's defaults would be exactly the same as GetOpt's defaults, because it would be using GetOpt.init. If fact, getOpt's body would likely be pretty much just GetOpt.init.getOpt(args); It's getopt's defaults that might vary. If they vary, it's because we decided that the defaults should be changed, and GetOpt and the new getOpt reflect the changes, but the old getopt would keep its behavior and be put on the deprecation path. - Jonathan M Davis
Re: std.getopt suggestion
On 28-09-2011 21:44, Jonathan M Davis wrote: Okay. I have a suggestion for an improvement to std.getopt that I think merits a bit of discussion. There's currently a pull request with some improvements for getopt which are mostly internal changes rather than API changes ( https://github.com/D-Programming-Language/phobos/pull/272 ), but I think that there is an API change that we should consider. Right now, there are three configuration options which are mutable module-level variables: dchar optionChar = '-'; string endOfOptions = "--"; dchar assignChar = '='; and the aforementioned pull request adds another for an array separator. Mutable module/global variables are generally considered to be bad design (though they're sometimes necessary), and I'm very much inclined to have those variables _not_ be at the module scope like that. So, my suggestion is that we create a GetOpt struct which contains all of the options for getopt, and we make getopt a member function of that struct. That way, if you're doing any configuration to getopt, you create a GetOpt object, set whatever properties you want to set on it, and call getopt on it - much cleaner than setting module-level variables. However, because you generally don't care about setting options on getopt, we then have a getopt function which is a free function (as we do now) which internally uses GetOpt.init and calls its getopt. So, it improves the configuration situation but leaves the usage of std.getopt to be pretty much the same if you don't want to mess with the default configuration. Does anyone think that that's a bad idea for any particular reason? Personally, I think that it's a significant improvement given that it's getting rid of the mutable module-level variables and better encapsulating getopt's functionality, but I think that there's some value in discussing the idea first. Also, it gives us a good opportunity to rename getopt to getOpt (so that it's properly camelcased per Phobos' naming conventions) as well as change any defaults which need changing. For instance, the aforementioned pull request adds a noSpaceOnlyForShortNumericOptions option, which it then recommends using but doesn't make the default, because it would break code. With this change, we could make it the default (with the old getopt function still using the current behavior for as long as its around). Personally, I'd also like to see bundling be the default, since that's how most command line programs work (at least on Posix), but regardless, renaming getopt to getOpt gives us a good opportunity to change some of the defaults if appropriate. In any case, the primary question is whether the basic idea of creating a GetOpt struct for configuring getOpt, making getOpt a member function of it, and then having a free function getOpt which uses GetOpt.init seems like a good idea or whether anyone can come up with a good reason why it _wouldn't_ be a good idea. - Jonathan M Davis Sounds good to me. - Alex
Re: std.getopt suggestion
On Wed, 28 Sep 2011 22:44:29 +0300, Jonathan M Davis wrote: Personally, I think that it's a significant improvement given that it's getting rid of the mutable module-level variables and better encapsulating getopt's functionality, but I think that there's some value in discussing the idea first. Another idea: GetOptOptions options = { assignChar : ':' }; getopt(args, options, ...); Passing GetOptOptions overrides the deprecated global options. -- Best regards, Vladimirmailto:vladi...@thecybershadow.net
Re: std.getopt suggestion
On 9/28/11 12:44 PM, Jonathan M Davis wrote: Okay. I have a suggestion for an improvement to std.getopt that I think merits a bit of discussion. There's currently a pull request with some improvements for getopt which are mostly internal changes rather than API changes ( https://github.com/D-Programming-Language/phobos/pull/272 ), but I think that there is an API change that we should consider. Right now, there are three configuration options which are mutable module-level variables: dchar optionChar = '-'; string endOfOptions = "--"; dchar assignChar = '='; and the aforementioned pull request adds another for an array separator. Mutable module/global variables are generally considered to be bad design (though they're sometimes necessary), and I'm very much inclined to have those variables _not_ be at the module scope like that. Why? So, my suggestion is that we create a GetOpt struct which contains all of the options for getopt, and we make getopt a member function of that struct. If the only motivation is that "globals are bad" without further reasoning, I see this as keeping with the letter but not with the spirit of the law. Andrei
Re: std.getopt suggestion
+1 On Wed, Sep 28, 2011 at 9:44 PM, Jonathan M Davis wrote: > Okay. I have a suggestion for an improvement to std.getopt that I think > merits > a bit of discussion. There's currently a pull request with some > improvements > for getopt which are mostly internal changes rather than API changes ( > https://github.com/D-Programming-Language/phobos/pull/272 ), but I think > that > there is an API change that we should consider. > > Right now, there are three configuration options which are mutable > module-level > variables: > > dchar optionChar = '-'; > string endOfOptions = "--"; > dchar assignChar = '='; > > and the aforementioned pull request adds another for an array separator. > Mutable module/global variables are generally considered to be bad design > (though they're sometimes necessary), and I'm very much inclined to have > those > variables _not_ be at the module scope like that. > > So, my suggestion is that we create a GetOpt struct which contains all of > the > options for getopt, and we make getopt a member function of that struct. > That > way, if you're doing any configuration to getopt, you create a GetOpt > object, > set whatever properties you want to set on it, and call getopt on it - much > cleaner than setting module-level variables. However, because you generally > don't care about setting options on getopt, we then have a getopt function > which is a free function (as we do now) which internally uses GetOpt.init > and > calls its getopt. So, it improves the configuration situation but leaves > the > usage of std.getopt to be pretty much the same if you don't want to mess > with > the default configuration. > > Does anyone think that that's a bad idea for any particular reason? > Personally, I think that it's a significant improvement given that it's > getting > rid of the mutable module-level variables and better encapsulating getopt's > functionality, but I think that there's some value in discussing the idea > first. > > Also, it gives us a good opportunity to rename getopt to getOpt (so that > it's > properly camelcased per Phobos' naming conventions) as well as change any > defaults which need changing. For instance, the aforementioned pull request > adds a noSpaceOnlyForShortNumericOptions option, which it then recommends > using but doesn't make the default, because it would break code. With this > change, we could make it the default (with the old getopt function still > using > the current behavior for as long as its around). Personally, I'd also like > to > see bundling be the default, since that's how most command line programs > work > (at least on Posix), but regardless, renaming getopt to getOpt gives us a > good > opportunity to change some of the defaults if appropriate. > > In any case, the primary question is whether the basic idea of creating a > GetOpt struct for configuring getOpt, making getOpt a member function of > it, > and then having a free function getOpt which uses GetOpt.init seems like a > good idea or whether anyone can come up with a good reason why it > _wouldn't_ > be a good idea. > > - Jonathan M Davis >
Re: std.getopt suggestion
Andrei Alexandrescu , dans le message (digitalmars.D:145699), a écrit : >> and the aforementioned pull request adds another for an array separator. >> Mutable module/global variables are generally considered to be bad design >> (though they're sometimes necessary), and I'm very much inclined to have >> those >> variables _not_ be at the module scope like that. > > Why? > >> So, my suggestion is that we create a GetOpt struct which contains all of the >> options for getopt, and we make getopt a member function of that struct. > > If the only motivation is that "globals are bad" without further > reasoning, I see this as keeping with the letter but not with the spirit > of the law. And why should the spirit of the law not apply to getopt ? I'll give you further reasoning then: I want to make a program that reads a file and parse lines with a getopt-like syntax. This program uses getopt both to read the program argument, and the lines to be read. I decide in a few months to change the way the program arguments are parsed. I may inavertedly change the parsing options in the file-reading part of my program. Should I have forseen this and reset all the getopt options before calling getopt for line-reading ? Making getopt work with a global state means that getopt is only meant to be used once at the beginning of the program for reading arguments, and that it is not suitable for any other uses, because otherwise, the different uses of getopt would interfere with each other. Why should such a nice function be reserved for only one usage ? -- Christophe
Re: std.getopt suggestion
On 9/29/11 2:11 AM, Christophe wrote: Andrei Alexandrescu , dans le message (digitalmars.D:145699), a écrit : and the aforementioned pull request adds another for an array separator. Mutable module/global variables are generally considered to be bad design (though they're sometimes necessary), and I'm very much inclined to have those variables _not_ be at the module scope like that. Why? So, my suggestion is that we create a GetOpt struct which contains all of the options for getopt, and we make getopt a member function of that struct. If the only motivation is that "globals are bad" without further reasoning, I see this as keeping with the letter but not with the spirit of the law. And why should the spirit of the law not apply to getopt ? I'll give you further reasoning then: I want to make a program that reads a file and parse lines with a getopt-like syntax. This program uses getopt both to read the program argument, and the lines to be read. I decide in a few months to change the way the program arguments are parsed. I may inavertedly change the parsing options in the file-reading part of my program. Should I have forseen this and reset all the getopt options before calling getopt for line-reading ? Making getopt work with a global state means that getopt is only meant to be used once at the beginning of the program for reading arguments, and that it is not suitable for any other uses, because otherwise, the different uses of getopt would interfere with each other. Why should such a nice function be reserved for only one usage ? You can easily build the abstraction you mention on top of std.getopt, which means its design is adequate. Andrei
Re: std.getopt suggestion
On Thursday, September 29, 2011 00:40:44 Andrei Alexandrescu wrote: > On 9/28/11 12:44 PM, Jonathan M Davis wrote: > > Okay. I have a suggestion for an improvement to std.getopt that I think > > merits a bit of discussion. There's currently a pull request with some > > improvements for getopt which are mostly internal changes rather than > > API changes ( https://github.com/D-Programming-Language/phobos/pull/272 > > ), but I think that there is an API change that we should consider. > > > > Right now, there are three configuration options which are mutable > > module-level variables: > > > > dchar optionChar = '-'; > > string endOfOptions = "--"; > > dchar assignChar = '='; > > > > and the aforementioned pull request adds another for an array separator. > > Mutable module/global variables are generally considered to be bad > > design > > (though they're sometimes necessary), and I'm very much inclined to have > > those variables _not_ be at the module scope like that. > > Why? 1. Mutable globals are generally considered to be bad practice. As you yourself have stated before, Phobos should be an example of good software practices in D. Having mutable globals goes directly contrary to that goal. 2. Conceptually, what happens with getopt is that you configure it and then run it. It is much better encapsulation for the configuration to be tied to the function call. The normal way to do this (at least in an OO language) is to make it a member function of the configuration. As it stands, those configuration variables are just sitting in the same module. As getopt is really the only function of consequence in the module, it's not as big a deal as it would be in most modules, but it's still better encapsulation to actually tie the configuration to the function that it's configuring. 3. By putting the configuration options in a struct, they are better organized. It makes it easier to see what the whole list is without having to search the module. It also gives a very good place to document them all together. 4. If you need to run getopt multiple times - particularly if you need to run it with different configurations each time - it's definitely cleaner to do that when you can just use a different GetOpt instance in each case. You don't have to worry about one run of getopt affecting another. Now, this matters far less for getopt than it would your average function, since it would be highly abnormal to need to run getopt multiple times like that, but the general design principle holds. 5. Assuming that we were creating std.getopt from scratch, there would be _zero_ benefit in having any of its configuration options be at the module level. There is a definite argument for leaving them there given that moving them could break code (though honestly, it wouldn't surprise me if no one in the history of D has ever written a program that changed any of those variables from their defaults given how standard they are and how little gain there normally is in changing them), but from the perspective of design, I don't see any reason why it would ever be better to have the variables be at module scope. On the contrary, it goes against what is generally considered good design. 6. Putting the configuration in a struct would probably allow getopt to be pure (depending on its implementation). I don't know if there would ever be a program where that would really matter given how getopt is normally used, but it would be a benefit to having the configuration encapsulated in a struct rather than at module scope. And as it stands, getopt definitely can't be pure, so if it ever did matter, it would be a problem. Honestly, I think that it primarily comes down to it being better design to encapsulate the configuration options together, tying them to the function that they're for, rather than having mutable variables at module scope. And Phobos should not only be well-designed on general principle, but it's supposed to be an example good D code and practices, and as it stands, std.getopt doesn't do that with regards to module-level variables. The only reason that I see to leave it as it is is because it's already that way. And if we mess with what's currently there in order to change any of the defaults for the config enum (as opposed to the variables at module scope which we've been discussing) and/or to change getopt to getOpt to follow Phobos' naming conventions, it just makes sense to change anything about the design which is suboptimal which can be reasonably changed. - Jonathan M Davis
Re: std.getopt suggestion
"Jonathan M Davis" wrote in message news:mailman.290.1317291489.26225.digitalmar...@puremagic.com... > > 5. Assuming that we were creating std.getopt from scratch, there would be > _zero_ benefit in having any of its configuration options be at the module > level. There is a definite argument for leaving them there given that > moving > them could break code (though honestly, it wouldn't surprise me if no one > in > the history of D has ever written a program that changed any of those > variables from their defaults given how standard they are and how little > gain > there normally is in changing them), And that would be a trivial thing to fix anyway. It's not as if it would give the same code different semantics. > but from the perspective of design, I > don't see any reason why it would ever be better to have the variables be > at > module scope. On the contrary, it goes against what is generally > considered > good design. >
Re: std.getopt suggestion
On 9/29/11 3:17 AM, Jonathan M Davis wrote: On Thursday, September 29, 2011 00:40:44 Andrei Alexandrescu wrote: Why? 1. Mutable globals are generally considered to be bad practice. As you yourself have stated before, Phobos should be an example of good software practices in D. Having mutable globals goes directly contrary to that goal. Globals are bad when functions communicate through them. std.getopt is one function, which is overwhelmingly called once. The variables that condition its workings are unrestricted. It is poorer style to create an object just for the sake of calling a method for it. GetOpt doesn't even make sense as a noun. It would be something like OptGetter - ah, the stigma of "er"-ending objects. 2. Conceptually, what happens with getopt is that you configure it and then run it. It is much better encapsulation for the configuration to be tied to the function call. The normal way to do this (at least in an OO language) is to make it a member function of the configuration. As it stands, those configuration variables are just sitting in the same module. As getopt is really the only function of consequence in the module, it's not as big a deal as it would be in most modules, but it's still better encapsulation to actually tie the configuration to the function that it's configuring. Encapsulation makes sense when there's matter to encapsulate. I don't see a point in encapsulating one function that's called once and two unrestricted variables. 3. By putting the configuration options in a struct, they are better organized. It makes it easier to see what the whole list is without having to search the module. It also gives a very good place to document them all together. Not buying this at all. It's a module with one blessed function! 4. If you need to run getopt multiple times - particularly if you need to run it with different configurations each time - it's definitely cleaner to do that when you can just use a different GetOpt instance in each case. You don't have to worry about one run of getopt affecting another. Now, this matters far less for getopt than it would your average function, since it would be highly abnormal to need to run getopt multiple times like that, but the general design principle holds. It would be quite abnormal to run getopt multiple times in the same app with different configurations. So in this case using globals is _better_, not worse. 5. Assuming that we were creating std.getopt from scratch, there would be _zero_ benefit in having any of its configuration options be at the module level. If I were creating std.getopt today from scratch, I'd define it the same way it is. It is simple, to the point, and gets its job done. It compares favorably with all getopt frameworks I've ever seen. I am very happy with its design and implementation. There is a definite argument for leaving them there given that moving them could break code (though honestly, it wouldn't surprise me if no one in the history of D has ever written a program that changed any of those variables from their defaults given how standard they are and how little gain there normally is in changing them), but from the perspective of design, I don't see any reason why it would ever be better to have the variables be at module scope. On the contrary, it goes against what is generally considered good design. Not buying this at all. I've seen "good" and "better" a lot of times in this email, but not properly substantiated for the case at hand. The design of a simple artifact should be simple. Introducing an object to obey design principles not applicable to the case at hand strikes me as futile. 6. Putting the configuration in a struct would probably allow getopt to be pure (depending on its implementation). I don't know if there would ever be a program where that would really matter given how getopt is normally used, but it would be a benefit to having the configuration encapsulated in a struct rather than at module scope. And as it stands, getopt definitely can't be pure, so if it ever did matter, it would be a problem. This is a good argument. Honestly, I think that it primarily comes down to it being better design to encapsulate the configuration options together, tying them to the function that they're for, rather than having mutable variables at module scope. And Phobos should not only be well-designed on general principle, but it's supposed to be an example good D code and practices, and as it stands, std.getopt doesn't do that with regards to module-level variables. The only reason that I see to leave it as it is is because it's already that way. I see another reason: it works very well and it keeps simple things simple. And if we mess with what's currently there in order to change any of the defaults for the config enum (as opposed to the variables at module scope which we've been discussing) and/or to change getopt to getOpt to follow Phobos' namin
Re: std.getopt suggestion
On Thu, 29 Sep 2011 18:41:33 +0300, Andrei Alexandrescu wrote: It would be quite abnormal to run getopt multiple times in the same app with different configurations. So in this case using globals is _better_, not worse. How about this: your program uses a logging component. You pass the command-line arguments to the logging component, so that it uses getopt to pick out the logging options and returns the rest. One day, the maintainers of the logging component decide to add compatibility with Brand X logging component, which uses ':' for the equal-sign separator. Naturally the maintainers are sloppy and don't restore the option after setting it. You know what happens next... -- Best regards, Vladimirmailto:vladi...@thecybershadow.net
Re: std.getopt suggestion
On 9/29/11 8:49 AM, Vladimir Panteleev wrote: On Thu, 29 Sep 2011 18:41:33 +0300, Andrei Alexandrescu wrote: It would be quite abnormal to run getopt multiple times in the same app with different configurations. So in this case using globals is _better_, not worse. How about this: your program uses a logging component. You pass the command-line arguments to the logging component, so that it uses getopt to pick out the logging options and returns the rest. One day, the maintainers of the logging component decide to add compatibility with Brand X logging component, which uses ':' for the equal-sign separator. Naturally the maintainers are sloppy and don't restore the option after setting it. You know what happens next... Sloppy maintainers may also take the GetOpt object by reference, change its state, and pass it back. Andrei
Re: std.getopt suggestion
"Andrei Alexandrescu" wrote in message news:j623kg$rfi$1...@digitalmars.com... > > The proposed change adds net negative value. It forces people to create an > object in order to call a simple function > Not really: OptGetter.optGet(...); Even that "OptGetter." can be eliminated (parhaps after the existing opget is deprecated). And for cases that need non-default settings, setting values on a struct is no harder than setting a few variables. You accuse people of using unsubstantiated "good" and "better", but then you dismiss and hand-wave-away half the stated benefits. Can we at least stop with the meta-arguments? That kind of debate inevitably ends up becoming hippocritical.
Re: std.getopt suggestion
On 9/29/11 9:25 AM, Nick Sabalausky wrote: "Andrei Alexandrescu" wrote in message news:j623kg$rfi$1...@digitalmars.com... The proposed change adds net negative value. It forces people to create an object in order to call a simple function Not really: OptGetter.optGet(...); Even that "OptGetter." can be eliminated (parhaps after the existing opget is deprecated). Why do you need it if all you want is to get rid of it? And for cases that need non-default settings, setting values on a struct is no harder than setting a few variables. You accuse people of using unsubstantiated "good" and "better", but then you dismiss and hand-wave-away half the stated benefits. Can we at least stop with the meta-arguments? That kind of debate inevitably ends up becoming hippocritical. Not criticizing any hippopotamus here :o). I think I stated my argument fairly and without appealing to either honor or guilt by association. Andrei
Re: std.getopt suggestion
Andrei Alexandrescu , dans le message (digitalmars.D:145742), a écrit : >> 4. If you need to run getopt multiple times - particularly if you need to run >> it with different configurations each time - it's definitely cleaner to do >> that >> when you can just use a different GetOpt instance in each case. You don't >> have >> to worry about one run of getopt affecting another. Now, this matters far >> less >> for getopt than it would your average function, since it would be highly >> abnormal to need to run getopt multiple times like that, but the general >> design principle holds. > > It would be quite abnormal to run getopt multiple times in the same app > with different configurations. So in this case using globals is > _better_, not worse. I think it is a bad to restrict the use of such a nice function to only one call per program because you want to make this precise call a bit simpler (and it is not simpler if you have to clean up the options after the call in case somebody else is going to use it). Using globals seems to be easier to you because it is what you are used to because of the previous langage your learned, but I do not buy that it is a proper D-way of doing things. You already did a whole work to pass so many options as arguments, I'm still asking myself why you left 3 options behind. Implementation issues? BTW, I don't like to use a OptGeter.getopt(...), I prefer to pass all options as arguments to getopt. Either something like getopt(..., OptGetter, ...) or getopt(..., option.equalsign, ':', ...) -- Christophe
Re: std.getopt suggestion
"Andrei Alexandrescu" wrote in message news:j626io$10pu$1...@digitalmars.com... > On 9/29/11 9:25 AM, Nick Sabalausky wrote: >> "Andrei Alexandrescu" wrote in message >> news:j623kg$rfi$1...@digitalmars.com... >>> >>> The proposed change adds net negative value. It forces people to create >>> an >>> object in order to call a simple function >>> >> >> Not really: >> >> OptGetter.optGet(...); >> >> Even that "OptGetter." can be eliminated (parhaps after the existing >> opget >> is deprecated). > > Why do you need it if all you want is to get rid of it? > You're the one that's pushing to keep the user syntax for the simple cases as much the same as possible. I'm demonstrating how that can be reasonably accomodated within the proposal. The idea is to make complex cases less error-prone without overcomplicating the simple cases. You seem to be dismissive of the more complex cases. Why? Just because they're less common (but not to the point of being unrealistic) doesn't mean such scenarios should be dismissed and/or kept error-prone if it can be reasonably avoided. And Jonathan's suggestion sounds like it falls into that "reasonably" category to me, even if we might want some minor details of it tweaked. >> And for cases that need non-default settings, setting values on a struct >> is >> no harder than setting a few variables. >> >> You accuse people of using unsubstantiated "good" and "better", but then >> you >> dismiss and hand-wave-away half the stated benefits. Can we at least stop >> with the meta-arguments? That kind of debate inevitably ends up becoming >> hippocritical. > > Not criticizing any hippopotamus here :o). Heh. Yea, well, I never claimed I could spell worth a damn ;) Especially without my minimum caffeine quota... > I think I stated my argument fairly and without appealing to either honor > or guilt by association. > And the rest of us feel the same way about our arguments. But pretty much any argument can be nitpicked apart by overapplying the rules of proper debating. You may not feel you were doing that, but I feel that you were, even if it wasn't intentional (as I'm sure it wasn't).
Re: std.getopt suggestion
On 9/29/11 9:55 AM, Nick Sabalausky wrote: And the rest of us feel the same way about our arguments. Argumentum ad populum :o). Andrei
Re: std.getopt suggestion
On 9/29/11 9:53 AM, Christophe wrote: Andrei Alexandrescu , dans le message (digitalmars.D:145742), a écrit : 4. If you need to run getopt multiple times - particularly if you need to run it with different configurations each time - it's definitely cleaner to do that when you can just use a different GetOpt instance in each case. You don't have to worry about one run of getopt affecting another. Now, this matters far less for getopt than it would your average function, since it would be highly abnormal to need to run getopt multiple times like that, but the general design principle holds. It would be quite abnormal to run getopt multiple times in the same app with different configurations. So in this case using globals is _better_, not worse. I think it is a bad to restrict the use of such a nice function to only one call per program because you want to make this precise call a bit simpler (and it is not simpler if you have to clean up the options after the call in case somebody else is going to use it). I wrote: "It would be quite abnormal to run getopt multiple times in the same app with different configurations." Let me rephrase a bit: "Running getopt multiple times in the same app with different configurations would be quite abnormal." Using globals seems to be easier to you because it is what you are used to because of the previous langage your learned, but I do not buy that it is a proper D-way of doing things. Well I need go get with the times. You already did a whole work to pass so many options as arguments, I'm still asking myself why you left 3 options behind. Implementation issues? BTW, I don't like to use a OptGeter.getopt(...), I prefer to pass all options as arguments to getopt. Either something like getopt(..., OptGetter, ...) or getopt(..., option.equalsign, ':', ...) That fits better within the current design. Andrei
Re: std.getopt suggestion
On 9/29/11 6:57 PM, Andrei Alexandrescu wrote: On 9/29/11 9:55 AM, Nick Sabalausky wrote: And the rest of us feel the same way about our arguments. Argumentum ad populum :o). Errm … no? Argumentum ad populum would e.g. be »and the rest of us believe that your arguments are inferior, Andrei, so you are wrong«. :P David
Re: std.getopt suggestion
On 9/29/11 10:15 AM, David Nadlinger wrote: On 9/29/11 6:57 PM, Andrei Alexandrescu wrote: On 9/29/11 9:55 AM, Nick Sabalausky wrote: And the rest of us feel the same way about our arguments. Argumentum ad populum :o). Errm … no? Argumentum ad populum would e.g. be »and the rest of us believe that your arguments are inferior, Andrei, so you are wrong«. :P That is implied. Either way, "the rest of us" attempts to build strength in numbers. Andrei
Re: std.getopt suggestion
"Andrei Alexandrescu" wrote in message news:j629g0$15tr$2...@digitalmars.com... > On 9/29/11 10:15 AM, David Nadlinger wrote: >> On 9/29/11 6:57 PM, Andrei Alexandrescu wrote: >>> On 9/29/11 9:55 AM, Nick Sabalausky wrote: And the rest of us feel the same way about our arguments. >>> >>> Argumentum ad populum :o). >> >> Errm . no? Argumentum ad populum would e.g. be »and the rest of us >> believe that your arguments are inferior, Andrei, so you are wrong«. :P > > That is implied. Either way, "the rest of us" attempts to build strength > in numbers. > Pardon the confusion. That's not the way I meant it. (Perhaps you're just looking for fallacies where there aren't any? j/k ;) ) What I meant is that: 1. Both you and the rest of us all feel that we stated our arguments "fairly and without appealing to either honor or guilt by association". 2. There is and will always be room for both sides to come up with claims of logical fallacies. 3. Therefore, pulling out nitpicky meta-argument cards doesn't do either side any good - it just ends up a stalemate and draws attention away from the more important face-value discussion.
Re: std.getopt suggestion
On Thursday, September 29, 2011 08:41 Andrei Alexandrescu wrote: > The proposed change adds net negative value. It forces people to create > an object in order to call a simple function, for the vague benefit of > tenuous corner cases. I specifically suggested that there still be a free getopt function which wraps the call to GetOpt.init. So, for most people, there would be no cost to having a struct to hold the configuration options. Yes, if I were suggesting that everyone be forced to create a an object to call getopt, that would be definite net negative change, making the average user of std.getopt pay for improving a rare use case. But I'm not suggesting that. And if people think that it's better to have a GetOpt struct (or whatever you want to call it; the name isn't all that important to me - GetOptConfig?) which is passed to getOpt, then that's fine too. It just seems simpler to me to make getOpt a member function, so I suggested that. The main point was that it's more poorly encapsulated to have the mutable variables free in the module, it breaks purity, and while it might work fine for std.getopt since it's really only doing one thing, it's still generally bad design to put mutable variables at module scope, so it looks bad to a lot of programmers, and there's no real cost that I see to having them in a struct. So, if the issue is that getOpt is a member function on a struct rather than taking the struct, then we can have it take the struct. And on the whole, I do think that std.getopt works great and has a solid design. But I don't understand why you would ever have mutable globals. They don't really buy you anything. With the struct, worst case, you create it and pass it to the getOpt call, and it adds one line of code for constructing the type before setting the value. GetOptConfig config; config.endOfOptions = "@"; getOpt(args, config, ...); And if you construct it and pass it directly, it could _save_ you a line of code. It also better enables those _rare_ cases where you actually want to call getOpt twice as well as make it possible for getOpt to be pure for those rare cases where that might matter - all at no cost to 99.99% of the uses of getOpt. > I kindly suggest we stop the isometric workout and look into adding good > value to Phobos. Someone else has been working on improving some of the guts of getopt. I was merely pointing out a place that it could be further improved as part of that. The extra work would be minimal and give a net improvement IMHO, and if the defaults are changed at all (which there is some reason to do due to a new value in the config enum) or if getopt is changed to getOpt to follow the naming convention, then we'd be making a change anyway. So, this small change that I'm suggesting wouldn't really create any issues or affect much code at all. It would just improve the basic module design. - Jonathan M Davis
Re: std.getopt suggestion
On 9/29/11 11:07 AM, Nick Sabalausky wrote: "Andrei Alexandrescu" wrote in message news:j629g0$15tr$2...@digitalmars.com... On 9/29/11 10:15 AM, David Nadlinger wrote: On 9/29/11 6:57 PM, Andrei Alexandrescu wrote: On 9/29/11 9:55 AM, Nick Sabalausky wrote: And the rest of us feel the same way about our arguments. Argumentum ad populum :o). Errm . no? Argumentum ad populum would e.g. be »and the rest of us believe that your arguments are inferior, Andrei, so you are wrong«. :P That is implied. Either way, "the rest of us" attempts to build strength in numbers. Pardon the confusion. That's not the way I meant it. (Perhaps you're just looking for fallacies where there aren't any? j/k ;) ) Well to a good extent. What I meant is that: 1. Both you and the rest of us all feel that we stated our arguments "fairly and without appealing to either honor or guilt by association". I think I can create a case that a recurring argument in favor of changing std.getopt was guilt and honor by association. The existing design was associated with the generally poor practice of using globals, and the proposed design was associated with the generally desirable practice of encapsulation. The fact of the matter is that std.getopt is fine as it is. It is not even a singleton object - it's the monostate pattern, for which module-level data is perfect. I argue that you don't want to create several distinct "GetOpter" objects and the design should emphatically NOT cater for such cases. Since it's only one monomorphic object (and one with only one "method" at that), the current design is entirely adequate. 2. There is and will always be room for both sides to come up with claims of logical fallacies. Mos def. For what I can tell I was struck by the honor by association. Designs without globals are good, therefore the proposal for changing std.getopt marks an improvement. This syllogism is fallacious. 3. Therefore, pulling out nitpicky meta-argument cards doesn't do either side any good - it just ends up a stalemate and draws attention away from the more important face-value discussion. Yah, the banter could go on forever. Andrei
Re: std.getopt suggestion
On Thu, 29 Sep 2011 18:55:39 +0300, Andrei Alexandrescu wrote: Sloppy maintainers may also take the GetOpt object by reference, change its state, and pass it back. See my suggestion earlier in this thread. -- Best regards, Vladimirmailto:vladi...@thecybershadow.net
Re: std.getopt suggestion
On 29.09.2011 21:01, Andrei Alexandrescu wrote: On 9/29/11 9:53 AM, Christophe wrote: Andrei Alexandrescu , dans le message (digitalmars.D:145742), a écrit : 4. If you need to run getopt multiple times - particularly if you need to run it with different configurations each time - it's definitely cleaner to do that when you can just use a different GetOpt instance in each case. You don't have to worry about one run of getopt affecting another. Now, this matters far less for getopt than it would your average function, since it would be highly abnormal to need to run getopt multiple times like that, but the general design principle holds. It would be quite abnormal to run getopt multiple times in the same app with different configurations. So in this case using globals is _better_, not worse. I think it is a bad to restrict the use of such a nice function to only one call per program because you want to make this precise call a bit simpler (and it is not simpler if you have to clean up the options after the call in case somebody else is going to use it). I wrote: "It would be quite abnormal to run getopt multiple times in the same app with different configurations." Let me rephrase a bit: "Running getopt multiple times in the same app with different configurations would be quite abnormal." Using globals seems to be easier to you because it is what you are used to because of the previous langage your learned, but I do not buy that it is a proper D-way of doing things. Well I need go get with the times. You already did a whole work to pass so many options as arguments, I'm still asking myself why you left 3 options behind. Implementation issues? BTW, I don't like to use a OptGeter.getopt(...), I prefer to pass all options as arguments to getopt. Either something like getopt(..., OptGetter, ...) or getopt(..., option.equalsign, ':', ...) That fits better within the current design. IMHO it's about the best suggestion we can get from this thread. Just make 'option' objects analogous to existing config values: getopt(...< use '=' >..., assignChar(':'), ...< use ':' >...); Both parties are happy: a helper struct is here, and getopt is still not a member ;) -- Dmitry Olshansky
Re: std.getopt suggestion
On 9/29/11 11:18 AM, Jonathan M Davis wrote: On Thursday, September 29, 2011 08:41 Andrei Alexandrescu wrote: The proposed change adds net negative value. It forces people to create an object in order to call a simple function, for the vague benefit of tenuous corner cases. I specifically suggested that there still be a free getopt function which wraps the call to GetOpt.init. So, for most people, there would be no cost to having a struct to hold the configuration options. Yes, if I were suggesting that everyone be forced to create a an object to call getopt, that would be definite net negative change, making the average user of std.getopt pay for improving a rare use case. But I'm not suggesting that. And if people think that it's better to have a GetOpt struct (or whatever you want to call it; the name isn't all that important to me - GetOptConfig?) which is passed to getOpt, then that's fine too. It just seems simpler to me to make getOpt a member function, so I suggested that. The main point was that it's more poorly encapsulated to have the mutable variables free in the module, it breaks purity, and while it might work fine for std.getopt since it's really only doing one thing, it's still generally bad design to put mutable variables at module scope, so it looks bad to a lot of programmers, and there's no real cost that I see to having them in a struct. We won't be able to please everyone. That being said, the current design is sound. http://c2.com/cgi/wiki?MonostatePattern So, if the issue is that getOpt is a member function on a struct rather than taking the struct, then we can have it take the struct. And on the whole, I do think that std.getopt works great and has a solid design. But I don't understand why you would ever have mutable globals. They don't really buy you anything. With the struct, worst case, you create it and pass it to the getOpt call, and it adds one line of code for constructing the type before setting the value. GetOptConfig config; config.endOfOptions = "@"; getOpt(args, config, ...); And if you construct it and pass it directly, it could _save_ you a line of code. It also better enables those _rare_ cases where you actually want to call getOpt twice as well as make it possible for getOpt to be pure for those rare cases where that might matter - all at no cost to 99.99% of the uses of getOpt. The cost is there in the documentation, examples, etc. etc. Here's the baseline: "In order to get a command-line options for your program, you must import std.getopt, define the variables holding the options, and call a function to fill them." This is the baseline. We don't need to motivate the baseline. Everything adding to the baseline must be motivated. I kindly suggest we stop the isometric workout and look into adding good value to Phobos. Someone else has been working on improving some of the guts of getopt. I was merely pointing out a place that it could be further improved as part of that. The extra work would be minimal and give a net improvement IMHO, and if the defaults are changed at all (which there is some reason to do due to a new value in the config enum) or if getopt is changed to getOpt to follow the naming convention, then we'd be making a change anyway. So, this small change that I'm suggesting wouldn't really create any issues or affect much code at all. It would just improve the basic module design. I don't think it would improve the module design, even without considering cost of change. It just adds useless clutter. Andrei
Re: std.getopt suggestion
On 9/29/11 11:24 AM, Vladimir Panteleev wrote: On Thu, 29 Sep 2011 18:55:39 +0300, Andrei Alexandrescu wrote: Sloppy maintainers may also take the GetOpt object by reference, change its state, and pass it back. See my suggestion earlier in this thread. You mean this: > Another idea: > > GetOptOptions options = { assignChar : ':' }; > getopt(args, options, ...); > > Passing GetOptOptions overrides the deprecated global options. I don't think this adds value. It's just churn. Andrei
Re: std.getopt suggestion
On Thursday, September 29, 2011 11:39 Andrei Alexandrescu wrote: > I don't think it would improve the module design, even without > considering cost of change. It just adds useless clutter. Well, out of those who have responded in this thread, you're the only one who thinks that. Everyone else has been in favor of either making those config options passable to getopt or in favor of putting getopt on a struct which holds the those config options (with a free function which uses the init value of the struct for the common case). And yes, that's an argument by ad populum (or whatever the exact name is), but what's considered "clutter" is subjective. Yes, the improvement would be relatively minor, but so's the cost of the change, and while it doesn't necessarily show that you're wrong when no one seems to agree with you, it does at least say something when no one agrees with you. - Jonathan M Davis
Re: std.getopt suggestion
On 9/29/11 11:54 AM, Jonathan M Davis wrote: On Thursday, September 29, 2011 11:39 Andrei Alexandrescu wrote: I don't think it would improve the module design, even without considering cost of change. It just adds useless clutter. Well, out of those who have responded in this thread, you're the only one who thinks that. Everyone else has been in favor of either making those config options passable to getopt or in favor of putting getopt on a struct which holds the those config options (with a free function which uses the init value of the struct for the common case). Upon further thinking, I'm even less sure than before that that's a good idea. And yes, that's an argument by ad populum (or whatever the exact name is), but what's considered "clutter" is subjective. Clutter is stuff on top of the baseline that doesn't pull its weight. The baseline is: "In order to get a command-line options for your program, you must import std.getopt, define the variables holding the options, and call a function to fill them." Yes, the improvement would be relatively minor, but so's the cost of the change, and while it doesn't necessarily show that you're wrong when no one seems to agree with you, it does at least say something when no one agrees with you. A good argument would be a whole lot better. My perception is, again, that we're not looking at a small improvement. It's a step back. Andrei
Re: std.getopt suggestion
Andrei Alexandrescu Wrote: > On 9/29/11 11:18 AM, Jonathan M Davis wrote: > > On Thursday, September 29, 2011 08:41 Andrei Alexandrescu wrote: > >> The proposed change adds net negative value. It forces people to create > >> an object in order to call a simple function, for the vague benefit of > >> tenuous corner cases. > > > > I specifically suggested that there still be a free getopt function which > > wraps the call to GetOpt.init. So, for most people, there would be no cost > > to > > having a struct to hold the configuration options. Yes, if I were suggesting > > that everyone be forced to create a an object to call getopt, that would be > > definite net negative change, making the average user of std.getopt pay for > > improving a rare use case. But I'm not suggesting that. And if people think > > that it's better to have a GetOpt struct (or whatever you want to call it; > > the > > name isn't all that important to me - GetOptConfig?) which is passed to > > getOpt, then that's fine too. It just seems simpler to me to make getOpt a > > member function, so I suggested that. The main point was that it's more > > poorly > > encapsulated to have the mutable variables free in the module, it breaks > > purity, and while it might work fine for std.getopt since it's really only > > doing one thing, it's still generally bad design to put mutable variables at > > module scope, so it looks bad to a lot of programmers, and there's no real > > cost that I see to having them in a struct. > > We won't be able to please everyone. That being said, the current design > is sound. http://c2.com/cgi/wiki?MonostatePattern > > > So, if the issue is that getOpt is a member function on a struct rather than > > taking the struct, then we can have it take the struct. And on the whole, I > > do > > think that std.getopt works great and has a solid design. But I don't > > understand why you would ever have mutable globals. They don't really buy > > you > > anything. With the struct, worst case, you create it and pass it to the > > getOpt > > call, and it adds one line of code for constructing the type before setting > > the value. > > > > GetOptConfig config; > > config.endOfOptions = "@"; > > getOpt(args, config, ...); > > > > And if you construct it and pass it directly, it could _save_ you a line of > > code. It also better enables those _rare_ cases where you actually want to > > call getOpt twice as well as make it possible for getOpt to be pure for > > those > > rare cases where that might matter - all at no cost to 99.99% of the uses of > > getOpt. > > The cost is there in the documentation, examples, etc. etc. > > Here's the baseline: > > "In order to get a command-line options for your program, you must > import std.getopt, define the variables holding the options, and call a > function to fill them." > > This is the baseline. We don't need to motivate the baseline. Everything > adding to the baseline must be motivated. > > >> I kindly suggest we stop the isometric workout and look into adding good > >> value to Phobos. > > > > Someone else has been working on improving some of the guts of getopt. I was > > merely pointing out a place that it could be further improved as part of > > that. > > The extra work would be minimal and give a net improvement IMHO, and if the > > defaults are changed at all (which there is some reason to do due to a new > > value in the config enum) or if getopt is changed to getOpt to follow the > > naming convention, then we'd be making a change anyway. So, this small > > change > > that I'm suggesting wouldn't really create any issues or affect much code at > > all. It would just improve the basic module design. > > I don't think it would improve the module design, even without > considering cost of change. It just adds useless clutter. > > > Andrei I just read through the above link provided by Andrei. I have a few notes/questions: a. The article states that this is an evil pattern. b. The examples are using a struct/namespace to encapsulate the data as suggested by Jonathan. c. Using global variables causes two main problems, non of which you acknowledged: 1. Name pollution - Yes, it is solvable in D with renamed imports and such but is still annoying. 2. MT / purity. Are these variables marked 'shared'? If yes, then access to them needs to be properly synchronized. If no, than the assertion regarding a single state is false as there would be a separate state for each thread. Does getopt (btw, awful name) handle any of these issues?
Re: std.getopt suggestion
On Thursday, September 29, 2011 13:40 Andrei Alexandrescu wrote: > On 9/29/11 11:54 AM, Jonathan M Davis wrote: > > On Thursday, September 29, 2011 11:39 Andrei Alexandrescu wrote: > >> I don't think it would improve the module design, even without > >> considering cost of change. It just adds useless clutter. > > > > Well, out of those who have responded in this thread, you're the only one > > who thinks that. Everyone else has been in favor of either making those > > config options passable to getopt or in favor of putting getopt on a > > struct which holds the those config options (with a free function which > > uses the init value of the struct for the common case). > > Upon further thinking, I'm even less sure than before that that's a good > idea. > > > And yes, that's an argument by ad populum > > (or whatever the exact name is), but what's considered "clutter" is > > subjective. > > Clutter is stuff on top of the baseline that doesn't pull its weight. > The baseline is: > > "In order to get a command-line options for your program, you must > import std.getopt, define the variables holding the options, and call a > function to fill them." I'm having to wonder if you're misunderstanding what my suggestion is. I'm not proposing a major redesign of getopt. The normal use case would be _completely_ unchanged. Right now, if you want to alter optionChar, you do std.getopt.optionChar = '^'; getopt(args, ...); With my suggestion, you'd do something more like GetOptConfig config; config.optionChar = '^'; getopt(args, config, ...); and you might even just construct the struct and pass it directly, in which case, you _save_ a line of code. And that's in the rare case where you actually want to mess with those values. In the normal case, it's still getopt(args, ...); You only need the struct if you're going to mess with optionChar, endOfOptions, or assignChar - which I would expect to be rather rare. The _only_ reason that I can think of that someone might want to alter those options (assuming that they're just not doing something incredibly abnormal) is to try and make the options more Windows-like with / or whatever it is that Windows uses instead of - or --. And if _that_ is the use case for altering those options, then the struct is an even _better_ idea, because then we could provide an instance of GetOptConfig tailored specifically for Windows, where the default would still be what we have now, but it would be as simple as getopt(args, std.getopt.windowsConfig, ...); and you'd get whatever Windows would normally use. This suggested change does _not_ drastically change how getopt works in the normal use case. It simply better encapsulates those configuration strings/dchars for getopt and gets rid of the mutable global variables (which are generally considered to be bad practice). The change for the abnormal use case is minor, and it's arguably better, since then the options are encapsulated instead of sitting at module scope, and getopt can also be pure, which may or may not be a big deal, but it _is_ an improvement. No, my suggestion is not going to make a huge difference. It's a relatively minor improvement. But I do not understand how you can think that it's actually better practice to stick mutable variables at module scope instead of encapsulating them in a struct for the one function that actually uses them. I have never before heard anyone actually try and argue that mutable global variables were a _good_ thing. At best, I've heard it argued that they were a necessary evil in a particular situation, but never that they were _good_. Honestly, I would vote against any code being included in Phobos which had any mutable global variables without a _very_ good reason. And I really don't see any such reason here. - Jonathan M Davis
Re: std.getopt suggestion
On 2011-09-29 22:40, Andrei Alexandrescu wrote: On 9/29/11 11:54 AM, Jonathan M Davis wrote: On Thursday, September 29, 2011 11:39 Andrei Alexandrescu wrote: I don't think it would improve the module design, even without considering cost of change. It just adds useless clutter. Well, out of those who have responded in this thread, you're the only one who thinks that. Everyone else has been in favor of either making those config options passable to getopt or in favor of putting getopt on a struct which holds the those config options (with a free function which uses the init value of the struct for the common case). Upon further thinking, I'm even less sure than before that that's a good idea. And yes, that's an argument by ad populum (or whatever the exact name is), but what's considered "clutter" is subjective. Clutter is stuff on top of the baseline that doesn't pull its weight. The baseline is: "In order to get a command-line options for your program, you must import std.getopt, define the variables holding the options, and call a function to fill them." How can you miss some many times that with the suggestion there will still be a free function that you can call if you want to use the default settings. -- /Jacob Carlborg
Re: std.getopt suggestion
On 9/29/11 11:35 PM, Jacob Carlborg wrote: On 2011-09-29 22:40, Andrei Alexandrescu wrote: On 9/29/11 11:54 AM, Jonathan M Davis wrote: On Thursday, September 29, 2011 11:39 Andrei Alexandrescu wrote: I don't think it would improve the module design, even without considering cost of change. It just adds useless clutter. Well, out of those who have responded in this thread, you're the only one who thinks that. Everyone else has been in favor of either making those config options passable to getopt or in favor of putting getopt on a struct which holds the those config options (with a free function which uses the init value of the struct for the common case). Upon further thinking, I'm even less sure than before that that's a good idea. And yes, that's an argument by ad populum (or whatever the exact name is), but what's considered "clutter" is subjective. Clutter is stuff on top of the baseline that doesn't pull its weight. The baseline is: "In order to get a command-line options for your program, you must import std.getopt, define the variables holding the options, and call a function to fill them." How can you miss some many times that with the suggestion there will still be a free function that you can call if you want to use the default settings. If anyone missed anything, it's you who missed my not missing it :o). Andrei
Re: std.getopt suggestion
"Jonathan M Davis" , dans le message (digitalmars.D:145800), a écrit : > Honestly, I would vote against any code being included in Phobos which had any > mutable global variables without a _very_ good reason. And I really don't see > any such reason here. Look closely at the new benchmark proposal then. There is a module clockwatch (it is private though).
Re: std.getopt suggestion
foobar , dans le message (digitalmars.D:145799), a écrit : > Does getopt (btw, awful name) getopt is the name of a Posix function to read option arguments in many langages. I don't think it should be changed. People trying to accomplish this task will be looking for a function with that name. -- Christophe
Re: std.getopt suggestion
On 2011-09-30 08:51, Andrei Alexandrescu wrote: On 9/29/11 11:35 PM, Jacob Carlborg wrote: On 2011-09-29 22:40, Andrei Alexandrescu wrote: On 9/29/11 11:54 AM, Jonathan M Davis wrote: On Thursday, September 29, 2011 11:39 Andrei Alexandrescu wrote: I don't think it would improve the module design, even without considering cost of change. It just adds useless clutter. Well, out of those who have responded in this thread, you're the only one who thinks that. Everyone else has been in favor of either making those config options passable to getopt or in favor of putting getopt on a struct which holds the those config options (with a free function which uses the init value of the struct for the common case). Upon further thinking, I'm even less sure than before that that's a good idea. And yes, that's an argument by ad populum (or whatever the exact name is), but what's considered "clutter" is subjective. Clutter is stuff on top of the baseline that doesn't pull its weight. The baseline is: "In order to get a command-line options for your program, you must import std.getopt, define the variables holding the options, and call a function to fill them." How can you miss some many times that with the suggestion there will still be a free function that you can call if you want to use the default settings. If anyone missed anything, it's you who missed my not missing it :o). Andrei Since you're repeating the same argument over and over it looks like you missed it. -- /Jacob Carlborg
Re: std.getopt suggestion
On Friday, September 30, 2011 13:07:55 Christophe wrote: > foobar , dans le message (digitalmars.D:145799), a écrit : > > Does getopt (btw, awful name) > > getopt is the name of a Posix function to read option arguments in many > langages. I don't think it should be changed. People trying to > accomplish this task will be looking for a function with that name. The _module_ is named std.getopt. People looking for it are going to find it. std.getopt.getopt doesn't follow Phobos' naming convention, so that would be a good reason to change the name to getOpt or getOptions. The fact that Posix has a function with the same name doesn't necessarily mean all that much, since Posix uses different naming conventions from Phobos, and our getopt does not work the same way as Posix' getopt (as I understand it, it's closer to perl's). Now, there is some argument for leaving it as getopt because of the fact that several languages use that name, but if we need to change the defaults for getopt (and it looks like it's probably going to be a good idea to do so), then we need to change the function's name to avoid silently breaking code, which makes it so that we need to rename the function anyway. So, it becomes the perfect opportunity to make the name match Phobos' naming conventions. If there's no need to try and avoid code breakage by changing the name, then it's more debatable, but from the looks of it, at minimum, the new enum value in the pull request, noSpaceOnlyForShortNumericOptions, looks like it should probably be the default. So, I expect that the defaults will change slightly. - Jonathan M Davis
Re: std.getopt suggestion
On 9/30/11 9:01 AM, Jonathan M Davis wrote: On Friday, September 30, 2011 13:07:55 Christophe wrote: foobar , dans le message (digitalmars.D:145799), a écrit : Does getopt (btw, awful name) getopt is the name of a Posix function to read option arguments in many langages. I don't think it should be changed. People trying to accomplish this task will be looking for a function with that name. The _module_ is named std.getopt. People looking for it are going to find it. std.getopt.getopt doesn't follow Phobos' naming convention, so that would be a good reason to change the name to getOpt or getOptions. The fact that Posix has a function with the same name doesn't necessarily mean all that much, since Posix uses different naming conventions from Phobos, and our getopt does not work the same way as Posix' getopt (as I understand it, it's closer to perl's). Now, there is some argument for leaving it as getopt because of the fact that several languages use that name, but if we need to change the defaults for getopt (and it looks like it's probably going to be a good idea to do so), ahem Andrei
Re: std.getopt suggestion
On Friday, September 30, 2011 09:37 Andrei Alexandrescu wrote: > On 9/30/11 9:01 AM, Jonathan M Davis wrote: > > On Friday, September 30, 2011 13:07:55 Christophe wrote: > >> foobar , dans le message (digitalmars.D:145799), a écrit : > >>> Does getopt (btw, awful name) > >> > >> getopt is the name of a Posix function to read option arguments in many > >> langages. I don't think it should be changed. People trying to > >> accomplish this task will be looking for a function with that name. > > > > The _module_ is named std.getopt. People looking for it are going to find > > it. std.getopt.getopt doesn't follow Phobos' naming convention, so that > > would be a good reason to change the name to getOpt or getOptions. The > > fact that Posix has a function with the same name doesn't necessarily > > mean all that much, since Posix uses different naming conventions from > > Phobos, and our getopt does not work the same way as Posix' getopt (as I > > understand it, it's closer to perl's). Now, there is some argument for > > leaving it as getopt because of the fact that several languages use that > > name, but if we need to change the defaults for getopt (and it looks > > like it's probably going to be a good idea to do so), > > ahem ??? Please elaborate. - Jonathan M Davis
Re: std.getopt suggestion
"Jonathan M Davis" , dans le message (digitalmars.D:145845), a écrit : >> >> ahem > > ??? Please elaborate. Let me guess: He considers their is not enough improvement to justify a breaking change. It's quite obvious, since he considers this is a negative improvement.
Re: std.getopt suggestion
On Wed, Sep 28, 2011 at 12:44 PM, Jonathan M Davis wrote: > So, my suggestion is that we create a GetOpt struct which contains all of the > options for getopt, and we make getopt a member function of that struct. Making it a struct gives you a design flexibility that really is an illusion. Most people it not all people use getopt to parse command line param. Giving the user the flexibility to have multiple GetOpt with different configuration when in essence they are parsing the same share resource (the command line) is incorrect. I prefer if we take std.getopt one step further (or create another) and make it completely global. Don't allow the parsing of anything but the command line and make the results of the parsing available as immutable to all the threads in the process. We can even extends getopt to also look at environment variables.
Re: std.getopt suggestion
On Friday, September 30, 2011 10:30 Christophe wrote: > "Jonathan M Davis" , dans le message (digitalmars.D:145845), a écrit : > >> ahem > > > > ??? Please elaborate. > > Let me guess: He considers their is not enough improvement to justify a > breaking change. It's quite obvious, since he considers this is a > negative improvement. I wasn't talking about having to change the name because of possible changes to the mutable global variables. I was talking about the fact that we may want to change the defaults as far as the config enum goes. The pull request has an improvement to those options which it is currently listing as "recommended" in the docs, because changing the defaults would silently break code. Changing the name would fix that problem. It would also mean that getopt could then match Phobos' naming conventions. If we don't change the defaults, then it's more debatable as to whether it's worth fixing the name so that it matches Phobos' naming conventions - particularly in light of the fact that the name getopt is fairly common. Regardless, if Andrei (or anyone) wants me (or anyone else) to understand what they mean in post, they need to be clear, and Andrei was not clear in this particular case - hence why I'm asking for clarification. Your assessment of what he meant may or may not be correct. - Jonathan M Davis
Re: std.getopt suggestion
On 9/30/11 10:55 AM, Jonathan M Davis wrote: On Friday, September 30, 2011 10:30 Christophe wrote: "Jonathan M Davis" , dans le message (digitalmars.D:145845), a écrit : ahem ??? Please elaborate. Let me guess: He considers their is not enough improvement to justify a breaking change. It's quite obvious, since he considers this is a negative improvement. I wasn't talking about having to change the name because of possible changes to the mutable global variables. I was talking about the fact that we may want to change the defaults as far as the config enum goes. Oh ok, sorry for being confus(ed|ing). Andrei
Re: std.getopt suggestion
"Jose Armando Garcia" wrote in message news:mailman.317.1317404375.26225.digitalmar...@puremagic.com... > > I prefer if we take std.getopt one step further (or create another) > and make it completely global. Don't allow the parsing of anything but > the command line Are you serious? Don't allow it? Why? What benefit could that possibly provide? It makes perfect sence to think that there may be legitimate reason to use a commandline parser on something other than the current process's cmd args. Unittesting, for one, just off the top of my head. Other people here have mentioned other uses. It doesn't make any sence at all to arbitrarily prevent a tool from being applied to whatever the user chooses to apply it to. > and make the results of the parsing available as > immutable to all the threads in the process. So you want to prevent people from being able to enforce encapsulation of that? If they want to make it available, they can trivially do that theirself. But you can't go the other way around.
Re: std.getopt suggestion
"Nick Sabalausky" wrote in message news:j651l8$7m7$1...@digitalmars.com... > "Jose Armando Garcia" wrote in message > news:mailman.317.1317404375.26225.digitalmar...@puremagic.com... >> >> I prefer if we take std.getopt one step further (or create another) >> and make it completely global. Don't allow the parsing of anything but >> the command line > > Are you serious? Don't allow it? Why? What benefit could that possibly > provide? It makes perfect sence to think that there may be legitimate > reason to use a commandline parser on something other than the current > process's cmd args. Unittesting, for one, just off the top of my head. > Other people here have mentioned other uses. > > It doesn't make any sence at all to arbitrarily prevent a tool from being > applied to whatever the user chooses to apply it to. > It's like applying fascism to API design. >> and make the results of the parsing available as >> immutable to all the threads in the process. > > So you want to prevent people from being able to enforce encapsulation of > that? If they want to make it available, they can trivially do that > theirself. But you can't go the other way around. > >
Re: std.getopt suggestion
On 2011-09-30 19:39, Jose Armando Garcia wrote: On Wed, Sep 28, 2011 at 12:44 PM, Jonathan M Davis wrote: So, my suggestion is that we create a GetOpt struct which contains all of the options for getopt, and we make getopt a member function of that struct. Making it a struct gives you a design flexibility that really is an illusion. Most people it not all people use getopt to parse command line param. Giving the user the flexibility to have multiple GetOpt with different configuration when in essence they are parsing the same share resource (the command line) is incorrect. I don't agree. Take this command line for example: "foo -a bar -b" You're calling the "foo" tool with the global "-a" option, the "bar" command/action and the "bar" specific "-b" option. This is how I would implement that (I have no idea if it's possible with getopt but lets assume that for now): class Application calls getopt once with the "sloppy" option. This will handle all options this "instance" of getopt knows about, the rest will be untouched. Now we have this command line: "bar -b" The Application slices off "bar" and invokes the bar command, i.e. calling some method in the Bar class. Bar has its own "instance" and settings for getopt. Bar will call getopt with the "strict" option on what's left of the command line: "-b". Bar now handles the "-b". If an invalid option is passed the Application class will ignore it since the "sloppy" option was set and passed it through to the action. The action will then loudly complain if an invalid option was passed to the tool since it called getopt with the "strict" option. -- /Jacob Carlborg
Re: std.getopt suggestion
On 9/30/11 12:23 PM, Jacob Carlborg wrote: On 2011-09-30 19:39, Jose Armando Garcia wrote: On Wed, Sep 28, 2011 at 12:44 PM, Jonathan M Davis wrote: So, my suggestion is that we create a GetOpt struct which contains all of the options for getopt, and we make getopt a member function of that struct. Making it a struct gives you a design flexibility that really is an illusion. Most people it not all people use getopt to parse command line param. Giving the user the flexibility to have multiple GetOpt with different configuration when in essence they are parsing the same share resource (the command line) is incorrect. I don't agree. Take this command line for example: "foo -a bar -b" You're calling the "foo" tool with the global "-a" option, the "bar" command/action and the "bar" specific "-b" option. This is how I would implement that (I have no idea if it's possible with getopt but lets assume that for now): It is possible, and rdmd does that by using the stopOnFirstNonOption flag. Andrei
Re: std.getopt suggestion
On Fri, Sep 30, 2011 at 11:27 AM, Nick Sabalausky wrote: > "Jose Armando Garcia" wrote in message > Are you serious? Don't allow it? Why? What benefit could that possibly > provide? It makes perfect sence to think that there may be legitimate reason > to use a commandline parser on something other than the current process's > cmd args. Unittesting, for one, just off the top of my head. Other people > here have mentioned other uses. You can easily unittest my suggestion. Just implement it internally using struct/encapsulation etc but don't expose it. A large part of an API is about restricting people's option by solving a set of use cases. No technology/API is the correct fit for every problem. If you want to parse command lines use getopt. If you want to parse config files use YAML, XML, etc. You don't want to arbitrarily prevent the user from doing something but you want to limit the user's possibility to shoot themselves on the foot! Just my two cents.
Re: std.getopt suggestion
Am 30.09.2011, 20:28 Uhr, schrieb Nick Sabalausky : "Nick Sabalausky" wrote in message news:j651l8$7m7$1...@digitalmars.com... "Jose Armando Garcia" wrote in message news:mailman.317.1317404375.26225.digitalmar...@puremagic.com... I prefer if we take std.getopt one step further (or create another) and make it completely global. Don't allow the parsing of anything but the command line Are you serious? Don't allow it? Why? What benefit could that possibly provide? It makes perfect sence to think that there may be legitimate reason to use a commandline parser on something other than the current process's cmd args. Unittesting, for one, just off the top of my head. Other people here have mentioned other uses. It doesn't make any sence at all to arbitrarily prevent a tool from being applied to whatever the user chooses to apply it to. It's like applying fascism to API design. You know, this will eventually end up where all discussions on the internet end. ;) If anything I'd like this tool to be extended to usage help à la Python. The setup of the cmd line parser there is documentation on the usage of the program.
Re: std.getopt suggestion
On 2011-10-01 00:17, Andrei Alexandrescu wrote: On 9/30/11 12:23 PM, Jacob Carlborg wrote: On 2011-09-30 19:39, Jose Armando Garcia wrote: On Wed, Sep 28, 2011 at 12:44 PM, Jonathan M Davis wrote: So, my suggestion is that we create a GetOpt struct which contains all of the options for getopt, and we make getopt a member function of that struct. Making it a struct gives you a design flexibility that really is an illusion. Most people it not all people use getopt to parse command line param. Giving the user the flexibility to have multiple GetOpt with different configuration when in essence they are parsing the same share resource (the command line) is incorrect. I don't agree. Take this command line for example: "foo -a bar -b" You're calling the "foo" tool with the global "-a" option, the "bar" command/action and the "bar" specific "-b" option. This is how I would implement that (I have no idea if it's possible with getopt but lets assume that for now): It is possible, and rdmd does that by using the stopOnFirstNonOption flag. Andrei I forgot to mention that I don't want the order of the arguments to matter. I should be possible to write: "foo bar -b -a" Or at least it should be possible to put global options anywhere in the command line. So I guess that would be using the passThrough option the first time getopt is called and then using the noPassThrough option when it's called the second time from the action implementation. So there we have a use case for calling getopt more than once, at least I have a use case for that. -- /Jacob Carlborg
Re: std.getopt suggestion
"Marco Leise" wrote in message news:op.v2no2ljx9y6...@dslb-088-070-130-181.pools.arcor-ip.net... >Am 30.09.2011, 20:28 Uhr, schrieb Nick Sabalausky : >> >> It's like applying fascism to API design. > >You know, this will eventually end up where all discussions on the >internet end. ;) > Saskatchewan! :) >If anything I'd like this tool to be extended to usage help à la Python. >The setup of the cmd line parser there is documentation on the usage of >the program. That's the main reason I've been using my own (desperately in need of rewrite) cmd line parser instead of getopt.
Re: std.getopt suggestion
"Jose Armando Garcia" wrote in message news:mailman.321.1317434277.26225.digitalmar...@puremagic.com... > On Fri, Sep 30, 2011 at 11:27 AM, Nick Sabalausky wrote: >> "Jose Armando Garcia" wrote in message >> Are you serious? Don't allow it? Why? What benefit could that possibly >> provide? It makes perfect sence to think that there may be legitimate >> reason >> to use a commandline parser on something other than the current process's >> cmd args. Unittesting, for one, just off the top of my head. Other people >> here have mentioned other uses. > > You can easily unittest my suggestion. Just implement it internally > using struct/encapsulation etc but don't expose it. > > A large part of an API is about restricting people's option by solving > a set of use cases. No technology/API is the correct fit for every > problem. If you want to parse command lines use getopt. If you want to > parse config files use YAML, XML, etc. > > You don't want to arbitrarily prevent the user from doing something > but you want to limit the user's possibility to shoot themselves on > the foot! > Parsing cmd line arguments that didn't come directly from the unmodified args passed into main is hardly shooting one's self in the foot.
Re: std.getopt suggestion
On 10/1/11 5:42 AM, Jacob Carlborg wrote: On 2011-10-01 00:17, Andrei Alexandrescu wrote: On 9/30/11 12:23 PM, Jacob Carlborg wrote: On 2011-09-30 19:39, Jose Armando Garcia wrote: On Wed, Sep 28, 2011 at 12:44 PM, Jonathan M Davis wrote: So, my suggestion is that we create a GetOpt struct which contains all of the options for getopt, and we make getopt a member function of that struct. Making it a struct gives you a design flexibility that really is an illusion. Most people it not all people use getopt to parse command line param. Giving the user the flexibility to have multiple GetOpt with different configuration when in essence they are parsing the same share resource (the command line) is incorrect. I don't agree. Take this command line for example: "foo -a bar -b" You're calling the "foo" tool with the global "-a" option, the "bar" command/action and the "bar" specific "-b" option. This is how I would implement that (I have no idea if it's possible with getopt but lets assume that for now): It is possible, and rdmd does that by using the stopOnFirstNonOption flag. Andrei I forgot to mention that I don't want the order of the arguments to matter. I should be possible to write: "foo bar -b -a" Or at least it should be possible to put global options anywhere in the command line. So I guess that would be using the passThrough option the first time getopt is called and then using the noPassThrough option when it's called the second time from the action implementation. So there we have a use case for calling getopt more than once, at least I have a use case for that. Clearly there are legit use cases. The use of monostate does not impede them. Andrei
Re: std.getopt suggestion
"Andrei Alexandrescu" wrote in message news:j679o0$1hdm$1...@digitalmars.com... > On 10/1/11 5:42 AM, Jacob Carlborg wrote: >> >> I forgot to mention that I don't want the order of the arguments to >> matter. I should be possible to write: >> >> "foo bar -b -a" >> >> Or at least it should be possible to put global options anywhere in the >> command line. >> >> So I guess that would be using the passThrough option the first time >> getopt is called and then using the noPassThrough option when it's >> called the second time from the action implementation. >> >> So there we have a use case for calling getopt more than once, at least >> I have a use case for that. > > Clearly there are legit use cases. The use of monostate does not impede > them. > It makes them error-prone whenever you want to use a different option. The use of Jon's suggestion does not impede the single-use cases. But it does make the other cases less problematic. So there's benefit with no downside.
Re: std.getopt suggestion
On 10/1/11 12:56 PM, Nick Sabalausky wrote: "Andrei Alexandrescu" wrote in message news:j679o0$1hdm$1...@digitalmars.com... On 10/1/11 5:42 AM, Jacob Carlborg wrote: I forgot to mention that I don't want the order of the arguments to matter. I should be possible to write: "foo bar -b -a" Or at least it should be possible to put global options anywhere in the command line. So I guess that would be using the passThrough option the first time getopt is called and then using the noPassThrough option when it's called the second time from the action implementation. So there we have a use case for calling getopt more than once, at least I have a use case for that. Clearly there are legit use cases. The use of monostate does not impede them. It makes them error-prone whenever you want to use a different option. The use of Jon's suggestion does not impede the single-use cases. But it does make the other cases less problematic. So there's benefit with no downside. I don't see it like that. Someone who's liable to make errors with one function and three variables is just as liable to make errors with one function and one object containing three variables. Andrei
Re: std.getopt suggestion
"Andrei Alexandrescu" wrote in message news:j67s2l$9h2$1...@digitalmars.com... > On 10/1/11 12:56 PM, Nick Sabalausky wrote: >> "Andrei Alexandrescu" wrote in message >> news:j679o0$1hdm$1...@digitalmars.com... >>> On 10/1/11 5:42 AM, Jacob Carlborg wrote: I forgot to mention that I don't want the order of the arguments to matter. I should be possible to write: "foo bar -b -a" Or at least it should be possible to put global options anywhere in the command line. So I guess that would be using the passThrough option the first time getopt is called and then using the noPassThrough option when it's called the second time from the action implementation. So there we have a use case for calling getopt more than once, at least I have a use case for that. >>> >>> Clearly there are legit use cases. The use of monostate does not impede >>> them. >>> >> >> It makes them error-prone whenever you want to use a different option. >> >> The use of Jon's suggestion does not impede the single-use cases. But it >> does make the other cases less problematic. So there's benefit with no >> downside. > > I don't see it like that. Someone who's liable to make errors with one > function and three variables is just as liable to make errors with one > function and one object containing three variables. > It's well established that the errors with three global vars are a hell of a lot easier to make. And yes, that *does* apply to getopt: -- // Original version void oneFunc(...) { ... getopt(...); // Use defaults } void anotherFunc(...) { ... getopt(...); // Use defaults } oneFunc(...); anotherFunc(...); -- // Make change: Version 2 void oneFunc(...) { ... // Don't want defaults anymore endOfOptions = ...; optionChar = ...; getopt(...); } void anotherFunc(...) { ... getopt(...); // Use defaults OH FUCK THEY'RE NOT THE DEFAULTS ANYMORE BOOM } oneFunc(...); anotherFunc(...); -- Now compare that with the proposal: -- // Same damn original version void oneFunc(...) { ... getopt(...); // Use defaults } void anotherFunc(...) { ... getopt(...); // Use defaults } oneFunc(...); anotherFunc(...); -- // Make change: Version 2B void oneFunc(...) { ... // Don't want defaults anymore auto opts = GetOpt(endOfOptions:..., optionChar:...); opts.getopt(...); } void anotherFunc(...) { ... getopt(...); // Use defaults JESUS FUCK LOOK AT THAT IT'S STILL FUCKING WORKING **RIGHT** HOLY CRAP } oneFunc(...); anotherFunc(...); -- Wow! Every damn programmer in the world was right all along! Globals *are* worse! Who'd have thought?!
Re: std.getopt suggestion
On 10/1/11 4:17 PM, Nick Sabalausky wrote: [snip] Not buying it. Sorry. Andrei
Re: std.getopt suggestion
On 10/2/11 1:01 AM, Andrei Alexandrescu wrote: On 10/1/11 4:17 PM, Nick Sabalausky wrote: [snip] Not buying it. Sorry. Andrei Sorry Andrei, not buying your opinion either. David And how exactly did this get us any further? :P
Re: std.getopt suggestion
On Sunday, October 02, 2011 01:35:09 David Nadlinger wrote: > On 10/2/11 1:01 AM, Andrei Alexandrescu wrote: > > On 10/1/11 4:17 PM, Nick Sabalausky wrote: > > [snip] > > > > Not buying it. Sorry. > > > > Andrei > > Sorry Andrei, not buying your opinion either. > > David > > > > And how exactly did this get us any further? :P I think that it's quite clear at this point that no one is going to convince Andrei and that Andrei is not going to convince anyone else. I think that it's horrible that we have mutable global variables in std.getopt, but the actual impact in this particular case is fairly minor, and I don't think that it's worth continuing this argument that is clearly going nowhere. If it were a new module, we could vote against its inclusion in Phobos, but it's already in there and has been for some time. And since Andrei is the original author, and I'd prefer to not just change things like that when he's clearly in strong opposition to it (particularly in a module that _he_ wrote), we appear to be pretty much stuck with how it is. If anything, this is an example of why having a formal review process can be valuable. - Jonathan M Davis
Re: std.getopt suggestion
On 2011-10-02 02:31, Jonathan M Davis wrote: On Sunday, October 02, 2011 01:35:09 David Nadlinger wrote: On 10/2/11 1:01 AM, Andrei Alexandrescu wrote: On 10/1/11 4:17 PM, Nick Sabalausky wrote: [snip] Not buying it. Sorry. Andrei Sorry Andrei, not buying your opinion either. David And how exactly did this get us any further? :P I think that it's quite clear at this point that no one is going to convince Andrei and that Andrei is not going to convince anyone else. I think that it's horrible that we have mutable global variables in std.getopt, but the actual impact in this particular case is fairly minor, and I don't think that it's worth continuing this argument that is clearly going nowhere. If it were a new module, we could vote against its inclusion in Phobos, but it's already in there and has been for some time. And since Andrei is the original author, and I'd prefer to not just change things like that when he's clearly in strong opposition to it (particularly in a module that _he_ wrote), we appear to be pretty much stuck with how it is. If anything, this is an example of why having a formal review process can be valuable. - Jonathan M Davis How about starting to review modules that existed before we started with the review process. But I guess many will complain that the time can be better spent elsewhere. -- /Jacob Carlborg
Re: std.getopt suggestion
On Monday, October 03, 2011 08:43:37 Jacob Carlborg wrote: > How about starting to review modules that existed before we started with > the review process. But I guess many will complain that the time can be > better spent elsewhere. I think that for the most part where there's really an issue with a module, we've already discussed revamping it. The new design is then reviewed as part of the formal review process. So, on the whole, I think that the issue is covered. And as much as I would like Phobos' lingering issues to be resolved, I don't think that going over all of the older code in formal reviews is really going to improve things much. For the most part, stuff which isn't being fixed by the wholesale overhaul of an older module can be fixed through pull requests and the like. - Jonathan M Davis
Re: std.getopt suggestion
On 9/29/2011 11:54 AM, Jonathan M Davis wrote: And yes, that's an argument by ad populum (or whatever the exact name is), but what's considered "clutter" is subjective. Yes, the improvement would be relatively minor, but so's the cost of the change, and while it doesn't necessarily show that you're wrong when no one seems to agree with you, it does at least say something when no one agrees with you. I've been only a casual user of std.getopt, barely scratching the surface of what it can do. But I do have a few general thoughts on this. One of the very hardest things in design is knowing when to say "no" to a new feature. The feature is desired by some subset of the users, it can be ignored by those who have no use for it, so it seems like an unequivocal win, right? But: 1. It adds to the "cognitive load" of the product. The cognitive load is how thick the manual is. The bigger it is, the more intimidating it is, and the fewer will dare to even open it. There is immense attraction in simple to understand products. std.getopt is supposed to make life easier for programmers - pages and pages and pages of documentation, options, complex examples, etc., just lead one to say "screw it, I'll roll my own" and it has failed. Steve Jobs is famously successful for paring down feature sets to the bare minimum that works for 90% of the users, and then doing those features very well. 2. Once a feature is there, it stays forever. It's very hard to judge how many people rely on a feature that turns out in hindsight to be baggage. Removing it arbitrarily will break existing code and tick off people. C++ has a number of hare-brained features (like trigraphs) that everyone hates but prove impossible to remove, despite it mucking up progress with language. 3. Increasing the complexity means more maintenance, cognitive load for the maintenance programmer, and bugs, bugs, bugs. 4. If a user really needs a special case not supported by std.getopt, it is straightforward to roll his own. 5. Supporting (well) only a reduced feature set means that apps will tend to have command line behavior that is more consistent and predictable, which is a good thing. It's why I have rather bull-headedly resisted adding feature after feature to D's unittest facility. The unittest feature has been a home run for D, and I suspect a lot of its success has been its no-brainer simplicity and focus on doing one thing well.
Re: std.getopt suggestion
On Monday, October 03, 2011 21:20:48 Walter Bright wrote: > On 9/29/2011 11:54 AM, Jonathan M Davis wrote: > > And yes, that's an argument by ad populum > > (or whatever the exact name is), but what's considered "clutter" is > > subjective. Yes, the improvement would be relatively minor, but so's the > > cost of the change, and while it doesn't necessarily show that you're > > wrong when no one seems to agree with you, it does at least say > > something when no one agrees with you. > > I've been only a casual user of std.getopt, barely scratching the surface of > what it can do. But I do have a few general thoughts on this. > > One of the very hardest things in design is knowing when to say "no" to a > new feature. The feature is desired by some subset of the users, it can be > ignored by those who have no use for it, so it seems like an unequivocal > win, right? > > But: > > 1. It adds to the "cognitive load" of the product. The cognitive load is how > thick the manual is. The bigger it is, the more intimidating it is, and the > fewer will dare to even open it. There is immense attraction in simple to > understand products. std.getopt is supposed to make life easier for > programmers - pages and pages and pages of documentation, options, complex > examples, etc., just lead one to say "screw it, I'll roll my own" and it > has failed. > > Steve Jobs is famously successful for paring down feature sets to the bare > minimum that works for 90% of the users, and then doing those features very > well. > > 2. Once a feature is there, it stays forever. It's very hard to judge how > many people rely on a feature that turns out in hindsight to be baggage. > Removing it arbitrarily will break existing code and tick off people. C++ > has a number of hare-brained features (like trigraphs) that everyone hates > but prove impossible to remove, despite it mucking up progress with > language. > > 3. Increasing the complexity means more maintenance, cognitive load for the > maintenance programmer, and bugs, bugs, bugs. > > 4. If a user really needs a special case not supported by std.getopt, it is > straightforward to roll his own. > > 5. Supporting (well) only a reduced feature set means that apps will tend to > have command line behavior that is more consistent and predictable, which > is a good thing. > > > It's why I have rather bull-headedly resisted adding feature after feature > to D's unittest facility. The unittest feature has been a home run for D, > and I suspect a lot of its success has been its no-brainer simplicity and > focus on doing one thing well. All good thoughts, but in this case, it's an argument over rearranging how some of the options are set (options which are probably more or less _never_ set and arguably should never have been configurable in the first place for essentially the reasons that you're giving). So, we wouldn't be looking at complicating anything or increasing the cognitive load in using it. All it would do would be to make some mutable global variables into a struct which would be passed in were the programmer to actually want to set them (which probably never happens). - Jonathan M Davis
Re: std.getopt suggestion
"Walter Bright" wrote in message news:j6e1k9$2p9u$1...@digitalmars.com... > > Steve Jobs is famously successful for paring down feature sets to the bare > minimum that works for 90% of the users, and then doing those features > very well. > Steve Jobs is famous for handling the bare minimum that works for 90% of *average Joe* users and saying "Fuck off" to everyone and everything else. That's why all his products are shit.
Re: std.getopt suggestion
"Nick Sabalausky" wrote in message news:j6e836$2gj$1...@digitalmars.com... > "Walter Bright" wrote in message > news:j6e1k9$2p9u$1...@digitalmars.com... >> >> Steve Jobs is famously successful for paring down feature sets to the >> bare minimum that works for 90% of the users, and then doing those >> features very well. >> > > Steve Jobs is famous for handling the bare minimum that works for 90% of > *average Joe* users and saying "Fuck off" to everyone and everything else. > That's why all his products are shit. > He's also famous for being a pretentious fucking tool.
Re: std.getopt suggestion
"Walter Bright" wrote in message news:j6e1k9$2p9u$1...@digitalmars.com... > > 2. Once a feature is there, it stays forever. It's very hard to judge how > many people rely on a feature that turns out in hindsight to be baggage. If people are relying on it, is it really baggage? > It's why I have rather bull-headedly resisted adding feature after feature > to D's unittest facility. The unittest feature has been a home run for D, > and I suspect a lot of its success has been its no-brainer simplicity and > focus on doing one thing well. What makes D's unittests attractive is the simplicity of the minimal-while-still-being-useful case, and *not* it's limitations. The general guiding principle of making the typical cases simple and the advances cases possible is one of the primary things that makes D fantastic. Unittest's approach of making the typical cases simple and ignoring advanced cases smacks of Jobs-ian arrogance and stands in contrast to normal D principles. (Again, Jobs is to be reviled, not revered.)
Re: std.getopt suggestion
On 10/3/2011 11:11 PM, Nick Sabalausky wrote: Steve Jobs is famous for handling the bare minimum that works for 90% of *average Joe* users and saying "Fuck off" to everyone and everything else. That's why all his products are shit. On the other hand, D makes no attempt at a "walled garden". Nobody is prevented from going outside std.getopt to handle the command line.
Re: std.getopt suggestion
On 10/4/2011 1:06 AM, Nick Sabalausky wrote: "Walter Bright" wrote in message news:j6e1k9$2p9u$1...@digitalmars.com... 2. Once a feature is there, it stays forever. It's very hard to judge how many people rely on a feature that turns out in hindsight to be baggage. If people are relying on it, is it really baggage? Yes. The C++0x Committee attempted to dump support for trigraphs. I read the adamant ripostes to that proposal from a very small handful of users. Those users' arguments were flat out wrong (in my not-so-humble opinion) and there is an obvious, easy workaround for their old code. But they still carried the day, and trigraphs stayed in, still wreaking havoc. I'm not willing to go as far as C++ in maintaining compatibility with misfeatures, but there's no denying the success it has had with that approach. It's why I have rather bull-headedly resisted adding feature after feature to D's unittest facility. The unittest feature has been a home run for D, and I suspect a lot of its success has been its no-brainer simplicity and focus on doing one thing well. What makes D's unittests attractive is the simplicity of the minimal-while-still-being-useful case, and *not* it's limitations. The general guiding principle of making the typical cases simple and the advances cases possible is one of the primary things that makes D fantastic. Unittest's approach of making the typical cases simple and ignoring advanced cases smacks of Jobs-ian arrogance and stands in contrast to normal D principles. (Again, Jobs is to be reviled, not revered.) I don't agree that the advanced cases are impossible with D. They just are not built-in, and one will need to do a bit of extra work to do them.
Re: std.getopt suggestion
On 2011-10-04 11:02, Walter Bright wrote: On 10/4/2011 1:06 AM, Nick Sabalausky wrote: "Walter Bright" wrote in message news:j6e1k9$2p9u$1...@digitalmars.com... 2. Once a feature is there, it stays forever. It's very hard to judge how many people rely on a feature that turns out in hindsight to be baggage. If people are relying on it, is it really baggage? Yes. The C++0x Committee attempted to dump support for trigraphs. I read the adamant ripostes to that proposal from a very small handful of users. Those users' arguments were flat out wrong (in my not-so-humble opinion) and there is an obvious, easy workaround for their old code. But they still carried the day, and trigraphs stayed in, still wreaking havoc. They at least removed export templates. -- /Jacob Carlborg
Re: std.getopt suggestion
On Tue, 04 Oct 2011 05:20:48 +0100, Walter Bright wrote: I've been only a casual user of std.getopt, barely scratching the surface of what it can do. But I do have a few general thoughts on this. One of the very hardest things in design is knowing when to say "no" to a new feature. The feature is desired by some subset of the users, it can be ignored by those who have no use for it, so it seems like an unequivocal win, right? But: 1. It adds to the "cognitive load" of the product. The cognitive load is how thick the manual is. The bigger it is, the more intimidating it is, and the fewer will dare to even open it. There is immense attraction in simple to understand products. std.getopt is supposed to make life easier for programmers - pages and pages and pages of documentation, options, complex examples, etc., just lead one to say "screw it, I'll roll my own" and it has failed. Steve Jobs is famously successful for paring down feature sets to the bare minimum that works for 90% of the users, and then doing those features very well. 2. Once a feature is there, it stays forever. It's very hard to judge how many people rely on a feature that turns out in hindsight to be baggage. Removing it arbitrarily will break existing code and tick off people. C++ has a number of hare-brained features (like trigraphs) that everyone hates but prove impossible to remove, despite it mucking up progress with language. 3. Increasing the complexity means more maintenance, cognitive load for the maintenance programmer, and bugs, bugs, bugs. 4. If a user really needs a special case not supported by std.getopt, it is straightforward to roll his own. 5. Supporting (well) only a reduced feature set means that apps will tend to have command line behavior that is more consistent and predictable, which is a good thing. It's why I have rather bull-headedly resisted adding feature after feature to D's unittest facility. The unittest feature has been a home run for D, and I suspect a lot of its success has been its no-brainer simplicity and focus on doing one thing well. One technique for avoiding a lot of the problems with "feature creep" is to create new things using existing things, instead of modifying the existing thing. In this way the cognitive load of the original remains the same, and don't increase it's complexity or add bugs. But, this is only possible if the original thing is written in an "orthogonal" manner: http://en.wikipedia.org/wiki/Orthogonality#Computer_science Meaning, typically, that the parts of the thing need to be encapsulated, so that they can be re-used by the more complex thing without introducing any side-effects to the original thing, or uses of the original thing. In this particular case, because these std,.getopt options are global variables, building something which uses them, or std.getopt will introduce side effects to other uses of std.getopt. Meaning the current design makes it impossible to build upon in an orthogonal manner. This is the 'problem' people have with it. -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: std.getopt suggestion
On 2011-10-04 13:21, Regan Heath wrote: On Tue, 04 Oct 2011 05:20:48 +0100, Walter Bright wrote: I've been only a casual user of std.getopt, barely scratching the surface of what it can do. But I do have a few general thoughts on this. One of the very hardest things in design is knowing when to say "no" to a new feature. The feature is desired by some subset of the users, it can be ignored by those who have no use for it, so it seems like an unequivocal win, right? But: 1. It adds to the "cognitive load" of the product. The cognitive load is how thick the manual is. The bigger it is, the more intimidating it is, and the fewer will dare to even open it. There is immense attraction in simple to understand products. std.getopt is supposed to make life easier for programmers - pages and pages and pages of documentation, options, complex examples, etc., just lead one to say "screw it, I'll roll my own" and it has failed. Steve Jobs is famously successful for paring down feature sets to the bare minimum that works for 90% of the users, and then doing those features very well. 2. Once a feature is there, it stays forever. It's very hard to judge how many people rely on a feature that turns out in hindsight to be baggage. Removing it arbitrarily will break existing code and tick off people. C++ has a number of hare-brained features (like trigraphs) that everyone hates but prove impossible to remove, despite it mucking up progress with language. 3. Increasing the complexity means more maintenance, cognitive load for the maintenance programmer, and bugs, bugs, bugs. 4. If a user really needs a special case not supported by std.getopt, it is straightforward to roll his own. 5. Supporting (well) only a reduced feature set means that apps will tend to have command line behavior that is more consistent and predictable, which is a good thing. It's why I have rather bull-headedly resisted adding feature after feature to D's unittest facility. The unittest feature has been a home run for D, and I suspect a lot of its success has been its no-brainer simplicity and focus on doing one thing well. One technique for avoiding a lot of the problems with "feature creep" is to create new things using existing things, instead of modifying the existing thing. In this way the cognitive load of the original remains the same, and don't increase it's complexity or add bugs. But, this is only possible if the original thing is written in an "orthogonal" manner: http://en.wikipedia.org/wiki/Orthogonality#Computer_science Meaning, typically, that the parts of the thing need to be encapsulated, so that they can be re-used by the more complex thing without introducing any side-effects to the original thing, or uses of the original thing. In this particular case, because these std,.getopt options are global variables, building something which uses them, or std.getopt will introduce side effects to other uses of std.getopt. Meaning the current design makes it impossible to build upon in an orthogonal manner. This is the 'problem' people have with it. Exactly, yet another reason why std.getopt is badly designed. -- /Jacob Carlborg
Re: std.getopt suggestion
On 10/04/11 09:09, Jacob Carlborg wrote: On 2011-10-04 13:21, Regan Heath wrote: In this particular case, because these std,.getopt options are global variables, building something which uses them, or std.getopt will introduce side effects to other uses of std.getopt. Meaning the current design makes it impossible to build upon in an orthogonal manner. This is the 'problem' people have with it. Exactly, yet another reason why std.getopt is badly designed. Wait, I thought that was the one! Now I wonder what the others were. Andrei
Re: std.getopt suggestion
I'm don't often use getopt just for the fact that I can't use single-dash arguments like '-release'. DMD uses this syntax, and so to other tools. It's not a big deal thanks to D's fantastic string-manipulation abilities, so I just roll my own. All I need is a switch(args) statement.
Re: std.getopt suggestion
On 2011-10-04 17:48, Andrei Alexandrescu wrote: On 10/04/11 09:09, Jacob Carlborg wrote: On 2011-10-04 13:21, Regan Heath wrote: In this particular case, because these std,.getopt options are global variables, building something which uses them, or std.getopt will introduce side effects to other uses of std.getopt. Meaning the current design makes it impossible to build upon in an orthogonal manner. This is the 'problem' people have with it. Exactly, yet another reason why std.getopt is badly designed. Wait, I thought that was the one! Now I wonder what the others were. Andrei Ok, sorry. I meant something like: yet another reason why global values are bad. And another thing that will hard(er) to do with the current design of std.getopt. -- /Jacob Carlborg
Re: std.getopt suggestion
On 10/4/2011 2:55 AM, Jacob Carlborg wrote: They at least removed export templates. True. I know there were some adamant defenders of it in the past, but I don't know if anyone defended it this time. A difference from trigraphs is that export was implemented by only one vendor, and every other vendor refused to do it. Even its adherents knew it was a lame duck.
Re: std.getopt suggestion
Andrej Mitrovic , dans le message (digitalmars.D:146060), a écrit : > I'm don't often use getopt just for the fact that I can't use > single-dash arguments like '-release'. DMD uses this syntax, and so to > other tools. It's not a big deal thanks to D's fantastic > string-manipulation abilities, so I just roll my own. All I need is a > switch(args) statement. I don't use getopt often either. That does not prevent me to wish getopt could become adequate to my needs...
Re: std.getopt suggestion
On 10/4/11 12:46 PM, Jacob Carlborg wrote: On 2011-10-04 17:48, Andrei Alexandrescu wrote: On 10/04/11 09:09, Jacob Carlborg wrote: On 2011-10-04 13:21, Regan Heath wrote: In this particular case, because these std,.getopt options are global variables, building something which uses them, or std.getopt will introduce side effects to other uses of std.getopt. Meaning the current design makes it impossible to build upon in an orthogonal manner. This is the 'problem' people have with it. Exactly, yet another reason why std.getopt is badly designed. Wait, I thought that was the one! Now I wonder what the others were. Andrei Ok, sorry. I meant something like: yet another reason why global values are bad. And another thing that will hard(er) to do with the current design of std.getopt. Did it ever prevent you from getting anything done with it? Andrei
Re: std.getopt suggestion
On 10/4/11 2:39 PM, Andrei Alexandrescu wrote: On 10/4/11 12:05 PM, Christophe wrote: Andrej Mitrovic , dans le message (digitalmars.D:146060), a écrit : I'm don't often use getopt just for the fact that I can't use single-dash arguments like '-release'. DMD uses this syntax, and so to other tools. It's not a big deal thanks to D's fantastic string-manipulation abilities, so I just roll my own. All I need is a switch(args) statement. I don't use getopt often either. That does not prevent me to wish getopt could become adequate to my needs... It already is because your needs are the empty set. Andrei On second thought what you said suggests your needs set may be nonempty, but said needs are not fulfilled by the current std.getopt. What exactly in std.getopt does not fulfill your needs? Would assembling the three variables into a structure help? Andrei
Re: std.getopt suggestion
On 10/4/11 12:05 PM, Christophe wrote: Andrej Mitrovic , dans le message (digitalmars.D:146060), a écrit : I'm don't often use getopt just for the fact that I can't use single-dash arguments like '-release'. DMD uses this syntax, and so to other tools. It's not a big deal thanks to D's fantastic string-manipulation abilities, so I just roll my own. All I need is a switch(args) statement. I don't use getopt often either. That does not prevent me to wish getopt could become adequate to my needs... It already is because your needs are the empty set. Andrei
Re: std.getopt suggestion
Andrei Alexandrescu , dans le message (digitalmars.D:146070), a écrit : > On 10/4/11 2:39 PM, Andrei Alexandrescu wrote: >> On 10/4/11 12:05 PM, Christophe wrote: >>> Andrej Mitrovic , dans le message (digitalmars.D:146060), a écrit : I'm don't often use getopt just for the fact that I can't use single-dash arguments like '-release'. DMD uses this syntax, and so to other tools. It's not a big deal thanks to D's fantastic string-manipulation abilities, so I just roll my own. All I need is a switch(args) statement. >>> >>> I don't use getopt often either. That does not prevent me to wish getopt >>> could become adequate to my needs... >> >> It already is because your needs are the empty set. >> >> Andrei > > On second thought what you said suggests your needs set may be nonempty, > but said needs are not fulfilled by the current std.getopt. > > What exactly in std.getopt does not fulfill your needs? Would assembling > the three variables into a structure help? No, it wouldn't. The main reason why I don't want to use getopt is because the syntax "-o output" (short-option, space, argument), and that is the main thing I want to do. I think I posted about this in the thread. Enabling single-dash long option would be nice too. The fact that it uses global parameters just doesn't help. -- Christophe
Re: std.getopt suggestion
On 10/4/11 3:10 PM, Christophe wrote: Andrei Alexandrescu , dans le message (digitalmars.D:146070), a écrit : On 10/4/11 2:39 PM, Andrei Alexandrescu wrote: On 10/4/11 12:05 PM, Christophe wrote: Andrej Mitrovic , dans le message (digitalmars.D:146060), a écrit : I'm don't often use getopt just for the fact that I can't use single-dash arguments like '-release'. DMD uses this syntax, and so to other tools. It's not a big deal thanks to D's fantastic string-manipulation abilities, so I just roll my own. All I need is a switch(args) statement. I don't use getopt often either. That does not prevent me to wish getopt could become adequate to my needs... It already is because your needs are the empty set. Andrei On second thought what you said suggests your needs set may be nonempty, but said needs are not fulfilled by the current std.getopt. What exactly in std.getopt does not fulfill your needs? Would assembling the three variables into a structure help? No, it wouldn't. Aha! The main reason why I don't want to use getopt is because the syntax "-o output" (short-option, space, argument), and that is the main thing I want to do. I think I posted about this in the thread. This is a sensible thing to ask for. Enabling single-dash long option would be nice too. Hm, that's a bit unusual (albeit dmd does use it). The problem is this feature interacts badly with bundling of single-letter arguments, i.e. does -in mean --in or -i -n? The fact that it uses global parameters just doesn't help. It doesn't hurt one soul. It's a non-problem. Andrei
Re: std.getopt suggestion
Am 04.10.2011, 22:41 Uhr, schrieb Andrei Alexandrescu : does -in mean --in or -i -n? This case must be prohibited and exorcised. You should decide to either use bundling of -i -n to -in *or* use single dash long arguments. DMD does *not* allow -wv for example although both letters are valid single-letter options.
Re: std.getopt suggestion
Yeah I've never seen --abc used as -a -b -c before, it looks quite strange to me. Is this common in unixland?
Re: std.getopt suggestion
On Wednesday, October 05, 2011 02:51:47 Andrej Mitrovic wrote: > Yeah I've never seen --abc used as -a -b -c before, it looks quite > strange to me. Is this common in unixland? In unix land, the normal situation is that -- denotes a flag with one or more characters in it, whereas - denotes a flag with exactly one character in it, and flags with one character can usually be concatenated. So, --abc denotes the flag abc, and -abc denotes the flags a, b, and c. I don't believe that I have ever seen a program which took single character flags with --, and programs which take multi-character flags with - are rare. - Jonathan M Davis
Re: std.getopt suggestion
On 10/4/11 7:51 PM, Andrej Mitrovic wrote: Yeah I've never seen --abc used as -a -b -c before, it looks quite strange to me. Is this common in unixland? No, but bundling -abc as -a -b -c is quite common, particularly in older programs. Andrei
Re: std.getopt suggestion
On Tuesday, October 04, 2011 20:28:30 Andrei Alexandrescu wrote: > On 10/4/11 7:51 PM, Andrej Mitrovic wrote: > > Yeah I've never seen --abc used as -a -b -c before, it looks quite > > strange to me. Is this common in unixland? > > No, but bundling -abc as -a -b -c is quite common, particularly in older > programs. Though for whatever reason, it's not the default in std.getopt in spite of the fact that it's quite standard. - Jonathan M Davis
Re: std.getopt suggestion
Am 05.10.2011, 03:28 Uhr, schrieb Jonathan M Davis : On Wednesday, October 05, 2011 02:51:47 Andrej Mitrovic wrote: Yeah I've never seen --abc used as -a -b -c before, it looks quite strange to me. Is this common in unixland? In unix land, the normal situation is that -- denotes a flag with one or more characters in it, whereas - denotes a flag with exactly one character in it, and flags with one character can usually be concatenated. So, --abc denotes the flag abc, and -abc denotes the flags a, b, and c. I don't believe that I have ever seen a program which took single character flags with --, and programs which take multi-character flags with - are rare. - Jonathan M Davis In Python they use this syntax exclusively in the command-line parser. Disallowing Windows-style or other non-GNU standard options. That's one way to get rid of an "options" parameter I guess.
Re: std.getopt suggestion
On 2011-10-04 21:39, Andrei Alexandrescu wrote: On 10/4/11 12:46 PM, Jacob Carlborg wrote: On 2011-10-04 17:48, Andrei Alexandrescu wrote: On 10/04/11 09:09, Jacob Carlborg wrote: On 2011-10-04 13:21, Regan Heath wrote: In this particular case, because these std,.getopt options are global variables, building something which uses them, or std.getopt will introduce side effects to other uses of std.getopt. Meaning the current design makes it impossible to build upon in an orthogonal manner. This is the 'problem' people have with it. Exactly, yet another reason why std.getopt is badly designed. Wait, I thought that was the one! Now I wonder what the others were. Andrei Ok, sorry. I meant something like: yet another reason why global values are bad. And another thing that will hard(er) to do with the current design of std.getopt. Did it ever prevent you from getting anything done with it? Andrei Not, prevent. But makes some things not as easy as it could be. -- /Jacob Carlborg
Re: std.getopt suggestion
On Tue, 04 Oct 2011 20:39:42 +0100, Andrei Alexandrescu wrote: On 10/4/11 12:46 PM, Jacob Carlborg wrote: On 2011-10-04 17:48, Andrei Alexandrescu wrote: On 10/04/11 09:09, Jacob Carlborg wrote: On 2011-10-04 13:21, Regan Heath wrote: In this particular case, because these std,.getopt options are global variables, building something which uses them, or std.getopt will introduce side effects to other uses of std.getopt. Meaning the current design makes it impossible to build upon in an orthogonal manner. This is the 'problem' people have with it. Exactly, yet another reason why std.getopt is badly designed. Wait, I thought that was the one! Now I wonder what the others were. Andrei Ok, sorry. I meant something like: yet another reason why global values are bad. And another thing that will hard(er) to do with the current design of std.getopt. Did it ever prevent you from getting anything done with it? That's not the question we should be asking. The question we should be asking is, will anyone ever want to re-use getopts parser for something other than a once off command line parse for a command line application. The answer is, maybe. And given that, isn't it better if they can re-use it without running any risk of side-effects etc. Lets imagine a possible use-case. Say you have an application, like a development environment. In it, you have external tools configured, each with it's own customisable set of command line options. Lets say, for a certain argument or set of arguments that you pass to the tool, you need to behave/react in different ways. Now, it makes sense to use getopt to parse the arguments you're going to pass to the tool, to decide how to behave prior to running it. The tool may be used multiple times in the lifetime of the development environment, so getopt is being reused repeatedly. Now, lets suppose each tool uses slightly different command line arguments, such that one of more of the existing global variables need to be set, for it to parse correctly. For this to work each use of getopt MUST set all 3 globals, or risk one of them being set by another use. Now, lets further suppose that these tools can/are run in parallel. With getopt in it's current incarnation it would be impossible to re-use it for this. With a very small change we can retain the current simple interface, but also encapsulate the globals and make the whole re-usable, for example... // ** Current getopt ** dchar optionChar = '-'; string endOfOptions = "--"; dchar assignChar = '='; void getopt(T...)(ref string[] args, T opts) {} // ** Proposed getopt ** struct GetOpt { dchar optionChar = '-'; string endOfOptions = "--"; dchar assignChar = '='; void getopt(T...)(ref string[] args, T opts) {} } void getopt(T...)(ref string[] args, T opts) { GetOpt go; return go.getOpt(args, opts); } Seems like a no-brainer to me. Unless you want to argue that stacking a struct is too inefficient for a once off command line parse, done once at the start of a command line application .. I think not. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: std.getopt suggestion
On Wed, 05 Oct 2011 07:53:25 -0400, Regan Heath wrote: On Tue, 04 Oct 2011 20:39:42 +0100, Andrei Alexandrescu wrote: On 10/4/11 12:46 PM, Jacob Carlborg wrote: On 2011-10-04 17:48, Andrei Alexandrescu wrote: On 10/04/11 09:09, Jacob Carlborg wrote: On 2011-10-04 13:21, Regan Heath wrote: In this particular case, because these std,.getopt options are global variables, building something which uses them, or std.getopt will introduce side effects to other uses of std.getopt. Meaning the current design makes it impossible to build upon in an orthogonal manner. This is the 'problem' people have with it. Exactly, yet another reason why std.getopt is badly designed. Wait, I thought that was the one! Now I wonder what the others were. Andrei Ok, sorry. I meant something like: yet another reason why global values are bad. And another thing that will hard(er) to do with the current design of std.getopt. Did it ever prevent you from getting anything done with it? That's not the question we should be asking. The question we should be asking is, will anyone ever want to re-use getopts parser for something other than a once off command line parse for a command line application. The answer is, maybe. And given that, isn't it better if they can re-use it without running any risk of side-effects etc. busybox. (not that I have an opinion here, I've never used getopt before) -Steve
Re: std.getopt suggestion
Christophe wrote: > Andrei Alexandrescu , dans le message (digitalmars.D:146070), a écrit : > > On 10/4/11 2:39 PM, Andrei Alexandrescu wrote: > >> On 10/4/11 12:05 PM, Christophe wrote: > >>> Andrej Mitrovic , dans le message (digitalmars.D:146060), a écrit : > I'm don't often use getopt just for the fact that I can't use > single-dash arguments like '-release'. DMD uses this syntax, and so to > other tools. It's not a big deal thanks to D's fantastic > string-manipulation abilities, so I just roll my own. All I need is a > switch(args) statement. > >>> > >>> I don't use getopt often either. That does not prevent me to wish getopt > >>> could become adequate to my needs... > >> > >> It already is because your needs are the empty set. > >> > >> Andrei > > > > On second thought what you said suggests your needs set may be nonempty, > > but said needs are not fulfilled by the current std.getopt. > > > > What exactly in std.getopt does not fulfill your needs? Would assembling > > the three variables into a structure help? > > > No, it wouldn't. > > The main reason why I don't want to use getopt is because the syntax "-o > output" (short-option, space, argument), and that is the main thing > I want to do. I think I posted about this in the thread. This will be supported with my changes. I hope I can act soon on the feedback and clean up the pull request. > Enabling single-dash long option would be nice too. I suppose there is no technical to not support this kind of option. Though it does make configuring getopt more difficult and I don't see enough usage to add it. Why is this important to you? I see little benefit of -pedantic over --pedantic. If you believe this option is very important (because you want to save a single character), then you could provide the short alias -p. Is this just a matter of taste? Please convince me. Jens
Re: std.getopt suggestion
Jens Mueller , dans le message (digitalmars.D:146111), a écrit : > Christophe wrote: >> Andrei Alexandrescu , dans le message (digitalmars.D:146070), a écrit : >> > On 10/4/11 2:39 PM, Andrei Alexandrescu wrote: >> >> On 10/4/11 12:05 PM, Christophe wrote: >> >>> Andrej Mitrovic , dans le message (digitalmars.D:146060), a écrit : >> I'm don't often use getopt just for the fact that I can't use >> single-dash arguments like '-release'. DMD uses this syntax, and so to >> other tools. It's not a big deal thanks to D's fantastic >> string-manipulation abilities, so I just roll my own. All I need is a >> switch(args) statement. >> >>> >> >>> I don't use getopt often either. That does not prevent me to wish getopt >> >>> could become adequate to my needs... >> >> >> >> It already is because your needs are the empty set. >> >> >> >> Andrei >> > >> > On second thought what you said suggests your needs set may be nonempty, >> > but said needs are not fulfilled by the current std.getopt. >> > >> > What exactly in std.getopt does not fulfill your needs? Would assembling >> > the three variables into a structure help? >> >> >> No, it wouldn't. >> >> The main reason why I don't want to use getopt is because the syntax "-o >> output" (short-option, space, argument), and that is the main thing >> I want to do. I think I posted about this in the thread. > > This will be supported with my changes. I hope I can act soon on the > feedback and clean up the pull request. > >> Enabling single-dash long option would be nice too. > > I suppose there is no technical to not support this kind of option. > Though it does make configuring getopt more difficult and I don't see > enough usage to add it. Why is this important to you? I see little > benefit of -pedantic over --pedantic. If you believe this option is very > important (because you want to save a single character), then you could > provide the short alias -p. > Is this just a matter of taste? > Please convince me. I can't convince you on that, because I am not really convinced myself. --longOption is the posix way, so it is fine with me, even if I think -longOption could be nicer to some eyes. However, the current way to parametrise getopt is to change the character for options ('-'), and I belive the string for long option is twice the character for short option ("--"). I don't think this makes great sense. We could parametrize a long option string (that we could set to "-"), and a short option char (that may or may not be automatically set to longOptionString[0]). But no parametrization on the shortOptionChar and on the longOptionString is fine too. Nobody would complain the call to getopt could be screwed up by another programmer modifiying the shortOptionChar behind your back if this could not be changed in the first place... Well, too much parametrization is wrong. But the posix way has to be supported, and it includes "-o output" (which is much more helpful than -ooutput for readability and for auto-completion in the shell). -- Christophe
Re: std.getopt suggestion
Christophe wrote: > Jens Mueller , dans le message (digitalmars.D:146111), a écrit : > > Christophe wrote: > >> Andrei Alexandrescu , dans le message (digitalmars.D:146070), a écrit : > >> > On 10/4/11 2:39 PM, Andrei Alexandrescu wrote: > >> >> On 10/4/11 12:05 PM, Christophe wrote: > >> >>> Andrej Mitrovic , dans le message (digitalmars.D:146060), a écrit : > >> I'm don't often use getopt just for the fact that I can't use > >> single-dash arguments like '-release'. DMD uses this syntax, and so to > >> other tools. It's not a big deal thanks to D's fantastic > >> string-manipulation abilities, so I just roll my own. All I need is a > >> switch(args) statement. > >> >>> > >> >>> I don't use getopt often either. That does not prevent me to wish > >> >>> getopt > >> >>> could become adequate to my needs... > >> >> > >> >> It already is because your needs are the empty set. > >> >> > >> >> Andrei > >> > > >> > On second thought what you said suggests your needs set may be nonempty, > >> > but said needs are not fulfilled by the current std.getopt. > >> > > >> > What exactly in std.getopt does not fulfill your needs? Would assembling > >> > the three variables into a structure help? > >> > >> > >> No, it wouldn't. > >> > >> The main reason why I don't want to use getopt is because the syntax "-o > >> output" (short-option, space, argument), and that is the main thing > >> I want to do. I think I posted about this in the thread. > > > > This will be supported with my changes. I hope I can act soon on the > > feedback and clean up the pull request. > > > >> Enabling single-dash long option would be nice too. > > > > I suppose there is no technical to not support this kind of option. > > Though it does make configuring getopt more difficult and I don't see > > enough usage to add it. Why is this important to you? I see little > > benefit of -pedantic over --pedantic. If you believe this option is very > > important (because you want to save a single character), then you could > > provide the short alias -p. > > Is this just a matter of taste? > > Please convince me. > > I can't convince you on that, because I am not really convinced myself. > --longOption is the posix way, so it is fine with me, even if I think > -longOption could be nicer to some eyes. Does this mean you would write D programs with command options like --longOption instead of -longOption? I just need to know how strong you disagree with the current solution. Because you said you wrote your own. I think we have failed, if a significant number of users rather write their own command line parsing than using the built-in one. > However, the current way to parametrise getopt is to change the > character for options ('-'), and I belive the string for long option is > twice the character for short option ("--"). I don't think this makes > great sense. We could parametrize a long option string (that we could > set to "-"), and a short option char (that may or may not be > automatically set to longOptionString[0]). But no parametrization on the > shortOptionChar and on the longOptionString is fine too. Nobody would > complain the call to getopt could be screwed up by another programmer > modifiying the shortOptionChar behind your back if this could not be > changed in the first place... This can be implemented. But right now I'm trying to figure out whether it's worth it. > Well, too much parametrization is wrong. But the posix way has to be > supported, and it includes "-o output" (which is much more helpful than > -ooutput for readability and for auto-completion in the shell). Yes. That's why we added it. Hope to finish the pull request soon. Jens
Re: std.getopt suggestion
On 10/5/11 6:53 AM, Regan Heath wrote: On Tue, 04 Oct 2011 20:39:42 +0100, Andrei Alexandrescu wrote: Did it ever prevent you from getting anything done with it? That's not the question we should be asking. The question we should be asking is, will anyone ever want to re-use getopts parser for something other than a once off command line parse for a command line application. I don't think yours is the right question either. This thread has become illustrative of a trend that would be great to change course a bit. I sustained my position in this thread longer than necessary in an attempt to explain this to me and others. Let me give a little context. This summer there was serious talk about using D at Facebook for a project that would last three months in development. D fulfilled all requirements, but had problems with library availability. For example, I was asked about D's connectivity to OpenSSL and MySQL. I told them they can translate the appropriate C headers manually or semi-automatically. They looked into it but they gave up because they saw this effort as a foreshadow of several other missing libraries. The barrier of entry for using OpenSSL or MySQL in Python is very low. The project was written in Python. A friend of mine, startup owner, read TDPL cover to cover and loved it. Then he did some more research and spent $7000 on a top-of-the-line machine to run his service-based application, written in Python. This is because he figured he has a lot of libraries already available for Python that will accelerate his productivity, and estimated that for his projected load he can compensate the speed difference. "Not everybody is Google, Facebook, or Yahoo", he said. There are other similar stories; these are the most recent I remember. We now have the GNU integration to get busy with, and we need a host of other APIs that connect us to the world. The right question is, can we afford to discuss packing three globals into one struct in std.getopt at this time? Making working code a tad better could go on forever, and might seem like progress. But it's not - it's asymptotic progress towards a local optimum, while we're looking at a hill of potential ahead. I kindly suggest anyone with an interest in D's future to focus on moving the big rocks. We can worry about the gravel and the sand later. Thanks, Andrei
Re: std.getopt suggestion
On Wednesday, October 05, 2011 16:24:32 Jens Mueller wrote: > > However, the current way to parametrise getopt is to change the > > character for options ('-'), and I belive the string for long option is > > twice the character for short option ("--"). I don't think this makes > > great sense. We could parametrize a long option string (that we could > > set to "-"), and a short option char (that may or may not be > > automatically set to longOptionString[0]). But no parametrization on the > > shortOptionChar and on the longOptionString is fine too. Nobody would > > complain the call to getopt could be screwed up by another programmer > > modifiying the shortOptionChar behind your back if this could not be > > changed in the first place... > > This can be implemented. But right now I'm trying to figure out whether > it's worth it. Personally, I think that the usage of a single dash with long options is the sort of thing that should be discouraged in programs, since it goes against how posix programs normally work. - Jonathan M Davis
Re: std.getopt suggestion
Jens Mueller , dans le message (digitalmars.D:146114), a écrit : > Christophe wrote: >> Jens Mueller , dans le message (digitalmars.D:146111), a écrit : >> > Christophe wrote: >> >> Andrei Alexandrescu , dans le message (digitalmars.D:146070), a écrit : >> >> > On 10/4/11 2:39 PM, Andrei Alexandrescu wrote: >> >> >> On 10/4/11 12:05 PM, Christophe wrote: >> >> >>> Andrej Mitrovic , dans le message (digitalmars.D:146060), a écrit : >> >> I'm don't often use getopt just for the fact that I can't use >> >> single-dash arguments like '-release'. DMD uses this syntax, and so >> >> to >> >> other tools. It's not a big deal thanks to D's fantastic >> >> string-manipulation abilities, so I just roll my own. All I need is a >> >> switch(args) statement. >> >> >>> >> >> >>> I don't use getopt often either. That does not prevent me to wish >> >> >>> getopt >> >> >>> could become adequate to my needs... >> >> >> >> >> >> It already is because your needs are the empty set. >> >> >> >> >> >> Andrei >> >> > >> >> > On second thought what you said suggests your needs set may be >> >> > nonempty, >> >> > but said needs are not fulfilled by the current std.getopt. >> >> > >> >> > What exactly in std.getopt does not fulfill your needs? Would >> >> > assembling >> >> > the three variables into a structure help? >> >> >> >> >> >> No, it wouldn't. >> >> >> >> The main reason why I don't want to use getopt is because the syntax "-o >> >> output" (short-option, space, argument), and that is the main thing >> >> I want to do. I think I posted about this in the thread. >> > >> > This will be supported with my changes. I hope I can act soon on the >> > feedback and clean up the pull request. >> > >> >> Enabling single-dash long option would be nice too. >> > >> > I suppose there is no technical to not support this kind of option. >> > Though it does make configuring getopt more difficult and I don't see >> > enough usage to add it. Why is this important to you? I see little >> > benefit of -pedantic over --pedantic. If you believe this option is very >> > important (because you want to save a single character), then you could >> > provide the short alias -p. >> > Is this just a matter of taste? >> > Please convince me. >> >> I can't convince you on that, because I am not really convinced myself. >> --longOption is the posix way, so it is fine with me, even if I think >> -longOption could be nicer to some eyes. > > Does this mean you would write D programs with command options like > --longOption instead of -longOption? I just need to know how strong you > disagree with the current solution. Because you said you wrote your own. > I think we have failed, if a significant number of users rather write > their own command line parsing than using the built-in one. > >> However, the current way to parametrise getopt is to change the >> character for options ('-'), and I belive the string for long option is >> twice the character for short option ("--"). I don't think this makes >> great sense. We could parametrize a long option string (that we could >> set to "-"), and a short option char (that may or may not be >> automatically set to longOptionString[0]). But no parametrization on the >> shortOptionChar and on the longOptionString is fine too. Nobody would >> complain the call to getopt could be screwed up by another programmer >> modifiying the shortOptionChar behind your back if this could not be >> changed in the first place... > > This can be implemented. But right now I'm trying to figure out whether > it's worth it. > >> Well, too much parametrization is wrong. But the posix way has to be >> supported, and it includes "-o output" (which is much more helpful than >> -ooutput for readability and for auto-completion in the shell). > > Yes. That's why we added it. Hope to finish the pull request soon. Posix behavior is enough for me to use getopt to parse command line options. No parametrization by global parameters is really preferable to use getopt for any other purpose that parsing of the command line argument. That is something I may use one day. I have a backend program written in c++ that parses commands and uses options with '-' preceding them, that I may, one day, translate to D to improve it). I would not be confortable with global parameters, but I don't know if I would use getopt in that case (in the program in c++, I use the posix getopt only for the first command line parsing, but there are many reasons for that, and my input line parsing is crap). One think I don't know regarding getopt, and that I didn't find in the documentation (maybe because I didn't look close enough after having found that -o output was not supported), is if the arguments are sorted like in the c getopt, and how to get the remaining arguments ? Shouldn't getopt return an array of the remaning arguments ? -- Christophe
Re: std.getopt suggestion
At last you say something I can agree with in this thread.