www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - std.getopt suggestion

reply Jonathan M Davis <jmdavisProg gmx.com> writes:
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
Sep 28 2011
next sibling parent Jacob Carlborg <doob me.com> writes:
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
Sep 28 2011
prev sibling next sibling parent "Nick Sabalausky" <a a.a> writes:
"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message 
news:mailman.260.1317239096.26225.digitalmars-d 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.
Sep 28 2011
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
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
Sep 28 2011
prev sibling next sibling parent =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= <xtzgzorex gmail.com> writes:
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
Sep 29 2011
prev sibling next sibling parent "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Wed, 28 Sep 2011 22:44:29 +0300, Jonathan M Davis <jmdavisProg gmx.com>  
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, Vladimir mailto:vladimir thecybershadow.net
Sep 29 2011
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Sep 29 2011
next sibling parent reply travert phare.normalesup.org (Christophe) writes:
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
Sep 29 2011
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Sep 29 2011
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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'
 naming conventions, it just makes sense to change anything about the design
 which is suboptimal which can be reasonably changed.

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 kindly suggest we stop the isometric workout and look into adding good value to Phobos. Thanks, Andrei
Sep 29 2011
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/29/11 8:49 AM, Vladimir Panteleev wrote:
 On Thu, 29 Sep 2011 18:41:33 +0300, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> 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
Sep 29 2011
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/29/11 11:24 AM, Vladimir Panteleev wrote:
 On Thu, 29 Sep 2011 18:55:39 +0300, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> 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
Sep 29 2011
prev sibling next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> 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.
Sep 29 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/29/11 9:25 AM, Nick Sabalausky wrote:
 "Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org>  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
Sep 29 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message 
news:j626io$10pu$1 digitalmars.com...
 On 9/29/11 9:25 AM, Nick Sabalausky wrote:
 "Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org>  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).
Sep 29 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Sep 29 2011
parent reply David Nadlinger <see klickverbot.at> writes:
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
Sep 29 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Sep 29 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> 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.
Sep 29 2011
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/29/11 11:07 AM, Nick Sabalausky wrote:
 "Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org>  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
Sep 29 2011
prev sibling next sibling parent reply travert phare.normalesup.org (Christophe) writes:
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
Sep 29 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Sep 29 2011
parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
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
Sep 29 2011
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Sep 29 2011
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Sep 29 2011
next sibling parent reply Jacob Carlborg <doob me.com> writes:
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
Sep 29 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Sep 29 2011
parent Jacob Carlborg <doob me.com> writes:
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
Sep 30 2011
prev sibling parent travert phare.normalesup.org (Christophe) writes:
"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).
Sep 30 2011
prev sibling next sibling parent reply foobar <foo bar.com> writes:
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?
Sep 29 2011
parent reply travert phare.normalesup.org (Christophe) writes:
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
Sep 30 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Sep 30 2011
parent reply travert phare.normalesup.org (Christophe) writes:
"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.
Sep 30 2011
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Sep 30 2011
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
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.
Oct 03 2011
next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Walter Bright" <newshound2 digitalmars.com> 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.
Oct 03 2011
next sibling parent "Nick Sabalausky" <a a.a> writes:
"Nick Sabalausky" <a a.a> wrote in message 
news:j6e836$2gj$1 digitalmars.com...
 "Walter Bright" <newshound2 digitalmars.com> 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.
Oct 03 2011
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
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.
Oct 04 2011
prev sibling next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Walter Bright" <newshound2 digitalmars.com> 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.)
Oct 04 2011
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 10/4/2011 1:06 AM, Nick Sabalausky wrote:
 "Walter Bright"<newshound2 digitalmars.com>  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.
Oct 04 2011
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-10-04 11:02, Walter Bright wrote:
 On 10/4/2011 1:06 AM, Nick Sabalausky wrote:
 "Walter Bright"<newshound2 digitalmars.com> 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
Oct 04 2011
parent Walter Bright <newshound2 digitalmars.com> writes:
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.
Oct 04 2011
prev sibling parent reply travert phare.normalesup.org (Christophe) writes:
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...
Oct 04 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Oct 04 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Oct 04 2011
parent reply travert phare.normalesup.org (Christophe) writes:
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
Oct 04 2011
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Oct 04 2011
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Oct 04 2011
prev sibling parent reply travert phare.normalesup.org (Christophe) writes:
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
Oct 05 2011
next sibling parent reply travert phare.normalesup.org (Christophe) writes:
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
Oct 05 2011
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/5/11 10:12 AM, Christophe wrote:
 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 ?

Second paragraph after synopsis. "In all cases, the command-line options that were parsed and used by getopt are removed from args. Whatever in the arguments did not look like an option is left in args for further processing by the program." Well at a point one does need to Read The Fine Manual or try a little experiment. Andrei
Oct 05 2011
parent travert phare.normalesup.org (Christophe) writes:
Andrei Alexandrescu , dans le message (digitalmars.D:146123), a écrit :
 On 10/5/11 10:12 AM, Christophe wrote:
 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 ?

Second paragraph after synopsis. "In all cases, the command-line options that were parsed and used by getopt are removed from args. Whatever in the arguments did not look like an option is left in args for further processing by the program." Well at a point one does need to Read The Fine Manual or try a little experiment.

Sorry to bother you, I read this manual a long time ago, and was just trying to answer Jens' question with a minimal involvment on my part, with no d compiler available where I am. Thanks for the answer anyway.
Oct 05 2011
prev sibling parent travert phare.normalesup.org (Christophe) writes:
Jens Mueller , dans le message (digitalmars.D:146124), a écrit :
 Christophe wrote:
 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 ?

By remaining arguments you mean unrecognized options, aren't you? These are left in the passed array if configured with passThrough. I.e. getopt removes an option iff it is recognized. What do you mean by sorted arguments?

the GNU getopt in c changes the order of the arguments of the argv parameter, to put the options in the front, and the remaining arguments at the end. The global variable optind is used to find the first remaining argument. http://www.gnu.org/s/hello/manual/libc/Using-Getopt.html#Using-Getopt That is what I meant by 'sorted arguments'. But I got my answer. Thanks.
Oct 05 2011
prev sibling parent "Nick Sabalausky" <a a.a> writes:
"Christophe" <travert phare.normalesup.org> wrote in message 
news:j6ho92$gtr$1 digitalmars.com...
 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).

Both of those always seemed goofy to me. "-o=output" and "-o:output" are the only ones that ever made much sense to me. (FWIW)
Oct 05 2011
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-10-04 13:21, Regan Heath wrote:
 On Tue, 04 Oct 2011 05:20:48 +0100, Walter Bright
 <newshound2 digitalmars.com> 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
Oct 04 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Oct 04 2011
parent reply Jacob Carlborg <doob me.com> writes:
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
Oct 04 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Oct 04 2011
next sibling parent Jacob Carlborg <doob me.com> writes:
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
Oct 04 2011
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/5/11 6:53 AM, Regan Heath wrote:
 On Tue, 04 Oct 2011 20:39:42 +0100, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> 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
Oct 05 2011
next sibling parent travert phare.normalesup.org (Christophe) writes:
At last you say something I can agree with in this thread.
Oct 05 2011
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/5/11 10:27 AM, Regan Heath wrote:
 I understand the issue, and the point you're making below, and I agree
 completely. At the same time, this particular change being as simple as
 it is, and as obviously beneficial as I hope I have managed to show,
 would have taken less time to simply change than it has taken to argue
 about.

There is the issue that every small change creates a precedent for similar or smaller changes. I spent this much time on this particular issue hoping that it would improve an entire trend going forward. Andrei
Oct 05 2011
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2011-10-06 12:25, Regan Heath wrote:
 It's obvious from my last post that I think a change should be allowed.
 I think you'd agree, were it not for the urgent need of other library
 components.

 I've been lurking and contributing to this news group on and off for
 years (since 2005/2006, maybe earlier). But, in all that time I have
 contributed nothing to Phobos. I have contributed a set of
 digest/hashing routines to Tango, because at the time Phobos wasn't
 taking submissions. I have been meaning to clean my originals of these
 up, get them properly documented, etc and submit them for review for
 Phobos, but I just haven't had the time, and/or inclination to do so (my
 free time is precious and I've just not been feeling the urge/itch to
 code.. blame minecraft :p)

 However, I am more than happy to hand them off in their current state to
 anyone who does have both time and inclination .. and I wonder how many
 other blocks of code are out there, just like mine, just waiting for the
 right person to take charge of them. Would this be useful do you think?
 Or would the time it takes someone to pick up new code, learn it, fine
 tune it and document it.. etc be more than if they just started again
 from scratch. It seems to me that sometimes, all that is needed to get a
 new module off the ground is a working prototype for the guts of it,
 which is what people like me who have some experience/knowledge but
 little time/energy could do, before handing it to someone who has a
 better idea of the D/Phobos 'way' and can organise the guts into a well
 formed module which complies with D style and Phobos guidelines etc.

 Part of what puts people off (I suspect) is the 'relative' complexity of
 submitting code (obtaining/learning GIT etc), the standard the code
 needs to be at (well organised, documented etc), and the implied
 promise/commitment that submitting code brings with it (that you'll hang
 around and maintain it). But, what if we were to create a system where
 people could submit code, no strings attached, in any state (they would
 define the state they believe it to be in) for the more dedicated
 contributors to pick up, clean up, and include as and when they could?
 It could be as simple as a web page, where code is pasted, files
 attached, and a license waiver agreed to.

 I know I have several pieces of code floating about the place which do
 useful things and would be motivated to create more if it would help the
 effort, and I could get a mention in the comments at the top of the
 finished module :p

I think it sounds like a good idea, assuming there actually is people willing to do these clean ups. -- /Jacob Carlborg
Oct 06 2011
prev sibling next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/6/11 4:44 AM, Regan Heath wrote:
 On Wed, 05 Oct 2011 16:44:31 +0100, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 10/5/11 10:27 AM, Regan Heath wrote:
 I understand the issue, and the point you're making below, and I agree
 completely. At the same time, this particular change being as simple as
 it is, and as obviously beneficial as I hope I have managed to show,
 would have taken less time to simply change than it has taken to argue
 about.

There is the issue that every small change creates a precedent for similar or smaller changes. I spent this much time on this particular issue hoping that it would improve an entire trend going forward.

I think it may have backfired somewhat. Now people are going to think no change is possible and Andrei is an 'Ogre' when it comes to his own modules. In situations like this some sort of precedent or impression will always be created. The best you can do is take control of it, and clearly define it. In this case clearly define the conditions under which the change is allowed i.e. 1. The interface MUST not change (retaining the getopt free function for example) 2. The default behaviour MUST not change (retaining the current default values for the globals) and make that the precedent to enforce on future occasions. It should be like "common law", defined by the first instance, changed hesitantly and only for very good reasons.

It's a great thought, and definitely my image out there should not be that of an ogre! :o) Problem here is, it's very difficult to come up with hard and fast rules, as inflexible rules tend to get used as justification for a variety of otherwise odd outcomes. For example, it is possible to modify std.getopt to keep the existing interface unmodified and add a wrapper for the globals etc. Generally such constraints make the implementation (and often the interface) more difficult and convoluted, which in turn becomes a liability that must be justified by significant added value. The only rule is, please use good judgment and focus on adding real and significant value, as opposed to shuffling the deck. Andrei
Oct 06 2011
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/6/11 5:25 AM, Regan Heath wrote:
 I've been lurking and contributing to this news group on and off for
 years (since 2005/2006, maybe earlier). But, in all that time I have
 contributed nothing to Phobos. I have contributed a set of
 digest/hashing routines to Tango, because at the time Phobos wasn't
 taking submissions. I have been meaning to clean my originals of these
 up, get them properly documented, etc and submit them for review for
 Phobos, but I just haven't had the time, and/or inclination to do so (my
 free time is precious and I've just not been feeling the urge/itch to
 code.. blame minecraft :p)

 However, I am more than happy to hand them off in their current state to
 anyone who does have both time and inclination .. and I wonder how many
 other blocks of code are out there, just like mine, just waiting for the
 right person to take charge of them. Would this be useful do you think?
 Or would the time it takes someone to pick up new code, learn it, fine
 tune it and document it.. etc be more than if they just started again
 from scratch. It seems to me that sometimes, all that is needed to get a
 new module off the ground is a working prototype for the guts of it,
 which is what people like me who have some experience/knowledge but
 little time/energy could do, before handing it to someone who has a
 better idea of the D/Phobos 'way' and can organise the guts into a well
 formed module which complies with D style and Phobos guidelines etc.

 Part of what puts people off (I suspect) is the 'relative' complexity of
 submitting code (obtaining/learning GIT etc), the standard the code
 needs to be at (well organised, documented etc), and the implied
 promise/commitment that submitting code brings with it (that you'll hang
 around and maintain it). But, what if we were to create a system where
 people could submit code, no strings attached, in any state (they would
 define the state they believe it to be in) for the more dedicated
 contributors to pick up, clean up, and include as and when they could?
 It could be as simple as a web page, where code is pasted, files
 attached, and a license waiver agreed to.

 I know I have several pieces of code floating about the place which do
 useful things and would be motivated to create more if it would help the
 effort, and I could get a mention in the comments at the top of the
 finished module :p

Thanks for your thoughts and generosity. It's great you are sharing your code in the hope it adds value to the community. I'm sure it does, but I am skeptical the impact is nearly as strong as it could. Also, if past is indicative of future, it's possible but unlikely that someone will take your code, bring it to perfection, and go through the hurdles of submitting it to Phobos. Making a body of code into a reusable library is often comparable work with writing the code itself. It's also seen by many as unpleasant work, which means most people would be more motivated to do it for their own work rather than others'. Things have changed a lot in the way D is evolving. This includes migration to git, opening the compiler, runtime, and standard library for contributions, and a review process for adding to the standard library. Focusing on the last aspect, this has been a big change from the previous approach in which the standard library was closed, and from an awkward stage in which we were inclined to accept somewhat random contributions (encoding, xml, json) without much due process. By any measure I can think of, establishing a review process has been a tremendous success, and everything else failed. We have std.datetime, std.parallelism to show, and there are many more to come. The difficulty in carrying through a Phobos submission also means establishing a strong esprit de corps, a commitment to quality, and a sense of meaningfully moving things forward together. As far as I know many other open source projects follow a similar model. There is essentially no evidence in this space to suggest that your hypothetical model of development would work. Andrei
Oct 06 2011
parent reply Steve Teale <steve.teale britseyeview.com> writes:
Andrei,

Are there guidelines for the Phobos process?

I have put a fair amount of work, two years ago and recently, into a piece for
accessing MySQL via D. I'm looking at this as a bottom-up investigation into
what
might be a more generalized interface for database access.

I've got to the point where I can support a good range of database operations,
and
present result sets as arrays of D structs, which presumably implies Ranges.
There's also lower level stuff to do more complex operations. So I'm wondering
if
I should take the first process steps. I'm retired, so I do have time to spend
on it.

The MySQL C api is not what you could call orthogonal - in crystallography terms
it is probably Triclinic, so it may not have been the best place to start.
There's
another guy I've had some correspondence with who is working on Postgres. He's
interested in the same idea.

What do you think?

Steve
Oct 06 2011
next sibling parent Jesse Phillips <jessekphillips+D gmail.com> writes:
Steve Teale Wrote:

 Andrei,
 
 Are there guidelines for the Phobos process?
 
 I have put a fair amount of work, two years ago and recently, into a piece for
 accessing MySQL via D. I'm looking at this as a bottom-up investigation into
what
 might be a more generalized interface for database access.
 
 I've got to the point where I can support a good range of database operations,
and
 present result sets as arrays of D structs, which presumably implies Ranges.
 There's also lower level stuff to do more complex operations. So I'm wondering
if
 I should take the first process steps. I'm retired, so I do have time to spend
on it.
 
 The MySQL C api is not what you could call orthogonal - in crystallography
terms
 it is probably Triclinic, so it may not have been the best place to start.
There's
 another guy I've had some correspondence with who is working on Postgres. He's
 interested in the same idea.
 
 What do you think?
 
 Steve

My suggestion, work with those you can find to help you. And keep these points in mind. * There is interest in having a standard Database interface. * It does not have to support ever obscure option of every database * The Database specific "glue layer" does not need to be part of Phobos, though the popular ones would be good. * The glue layer should expose the more intricate options and hopefully work with the generic interface. * You will have to keep pushing for it. If you have a good solid API that you think is ready for inclusion in Phobos you will get more attention and a more critical review. * The generic interface will be the main interest, and I think many envision it looking like C#'s LINQ over Java's prepare and execute. (C# has this too, I couldn't figure out how to use LINQ as it seemed to require more setup, I think D can do better)
Oct 06 2011
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/6/11 10:27 AM, Steve Teale wrote:
 Andrei,

 Are there guidelines for the Phobos process?

We follow the Boost review process: http://www.boost.org/community/reviews.html
 I have put a fair amount of work, two years ago and recently, into a piece for
 accessing MySQL via D. I'm looking at this as a bottom-up investigation into
what
 might be a more generalized interface for database access.

 I've got to the point where I can support a good range of database operations,
and
 present result sets as arrays of D structs, which presumably implies Ranges.
 There's also lower level stuff to do more complex operations. So I'm wondering
if
 I should take the first process steps. I'm retired, so I do have time to spend
on it.

 The MySQL C api is not what you could call orthogonal - in crystallography
terms
 it is probably Triclinic, so it may not have been the best place to start.
There's
 another guy I've had some correspondence with who is working on Postgres. He's
 interested in the same idea.

 What do you think?

I think this is a great initiative. Perhaps it would be nice to have a C-level API translation in etc.mysql. Then we should have a driver-style interface a la Java's JDBC, Perl's DBI, Python's PEP249 etc. For D in particular, I think the range aspect is secondary. Probably it will be more important to interoperate with Variant. Most APIs store columns in a Variant structure that captures all possible types of the database. Resultsets come as input ranges of array of Variant. It's not important to make them compatible with the input range interface because it's unlikely you'll pass that array of Variant directly to some algorithm. That being said, people will naturally expect to use the canonical range interface. It would probably be gratuitous to choose other primitive(s) than empty/front/popFront. Making the database interface generic over other SQL databases will probably be considerable more work, and will need study of existing APIs and input from the community. Thanks, Andrei
Oct 06 2011
next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message 
news:j6ljvs$1if5$1 digitalmars.com...
 For D in particular, I think the range aspect is secondary. Probably it 
 will be more important to interoperate with Variant. Most APIs store 
 columns in a Variant structure that captures all possible types of the 
 database.

 Resultsets come as input ranges of array of Variant. It's not important to 
 make them compatible with the input range interface because it's unlikely 
 you'll pass that array of Variant directly to some algorithm. That being 
 said, people will naturally expect to use the canonical range interface. 
 It would probably be gratuitous to choose other primitive(s) than 
 empty/front/popFront.

Personally, I would *expect* a good DB API to provide statically-typed columns. I use D because I hate dynamic typing, not because it provides a Variant. Whether or not the DB API *also* has messy^H^H^H^H^HVariant capability for those who want it, I wouldn't care at all either way.
Oct 06 2011
next sibling parent reply Piotr Szturmaj <bncrbme jadamspam.pl> writes:
Nick Sabalausky wrote:
 "Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org>  wrote in message
 news:j6ljvs$1if5$1 digitalmars.com...
 For D in particular, I think the range aspect is secondary. Probably it
 will be more important to interoperate with Variant. Most APIs store
 columns in a Variant structure that captures all possible types of the
 database.

 Resultsets come as input ranges of array of Variant. It's not important to
 make them compatible with the input range interface because it's unlikely
 you'll pass that array of Variant directly to some algorithm. That being
 said, people will naturally expect to use the canonical range interface.
 It would probably be gratuitous to choose other primitive(s) than
 empty/front/popFront.

Personally, I would *expect* a good DB API to provide statically-typed columns. I use D because I hate dynamic typing, not because it provides a Variant. Whether or not the DB API *also* has messy^H^H^H^H^HVariant capability for those who want it, I wouldn't care at all either way.

What do you think about ddb(http://pszturmaj.github.com/ddb/db.html) ?. It provides statically typed columns or dynamic Variant columns. What you want is what you get :)
Oct 06 2011
parent reply Jacob Carlborg <doob me.com> writes:
On 2011-10-07 04:56, Piotr Szturmaj wrote:
 Nick Sabalausky wrote:
 "Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org> wrote in message
 news:j6ljvs$1if5$1 digitalmars.com...
 For D in particular, I think the range aspect is secondary. Probably it
 will be more important to interoperate with Variant. Most APIs store
 columns in a Variant structure that captures all possible types of the
 database.

 Resultsets come as input ranges of array of Variant. It's not
 important to
 make them compatible with the input range interface because it's
 unlikely
 you'll pass that array of Variant directly to some algorithm. That being
 said, people will naturally expect to use the canonical range interface.
 It would probably be gratuitous to choose other primitive(s) than
 empty/front/popFront.

Personally, I would *expect* a good DB API to provide statically-typed columns. I use D because I hate dynamic typing, not because it provides a Variant. Whether or not the DB API *also* has messy^H^H^H^H^HVariant capability for those who want it, I wouldn't care at all either way.

What do you think about ddb(http://pszturmaj.github.com/ddb/db.html) ?. It provides statically typed columns or dynamic Variant columns. What you want is what you get :)

I think it's important to have a solid low level database API which an object oriented abstraction can be built upon. -- /Jacob Carlborg
Oct 06 2011
parent Jacob Carlborg <doob me.com> writes:
On 2011-10-07 09:30, Russel Winder wrote:
 On Fri, 2011-10-07 at 08:51 +0200, Jacob Carlborg wrote:
 [ . . . ]
 I think it's important to have a solid low level database API which an
 object oriented abstraction can be built upon.

Why object oriented? Why not functional?

The point was that the low level should not be object oriented like, an ORM, to allow different high level abstractions built on top of the low level API. I don't think that the low level API should have functions which takes a struct or an object and fills it fields with results from a query. That's up to the high level API. -- /Jacob Carlborg
Oct 07 2011
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/6/11 8:55 PM, Nick Sabalausky wrote:
 "Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org>  wrote in message
 news:j6ljvs$1if5$1 digitalmars.com...
 For D in particular, I think the range aspect is secondary. Probably it
 will be more important to interoperate with Variant. Most APIs store
 columns in a Variant structure that captures all possible types of the
 database.

 Resultsets come as input ranges of array of Variant. It's not important to
 make them compatible with the input range interface because it's unlikely
 you'll pass that array of Variant directly to some algorithm. That being
 said, people will naturally expect to use the canonical range interface.
 It would probably be gratuitous to choose other primitive(s) than
 empty/front/popFront.

Personally, I would *expect* a good DB API to provide statically-typed columns. I use D because I hate dynamic typing, not because it provides a Variant. Whether or not the DB API *also* has messy^H^H^H^H^HVariant capability for those who want it, I wouldn't care at all either way.

A statically-typed interface is nice when you know the schema a priori, but definitely there's a need for dynamically-created queries too. Andrei
Oct 06 2011
prev sibling next sibling parent reply Steve Teale <steve.teale britseyeview.com> writes:
Andrei,

I was thinking the same thing about the C level interface sometime in the middle
of last night. A straight translation of mysqld could be put there almost
immediately. I have to make myself translate the character set stuff, and add
that, but it's probably only a days work.

As for the interface, I was influenced at the intermediate level by my memory of
using C#.

I think that a DB interface for D should be something that provides an
understood
set of facilities rather than an interface in the language sense that provides
certain specific methods. This would allow a decent job to be done on individual
databases strengths, while making it easy for D programmers to move from one to
another. I will write up a summary of my thoughts later today, and post it here.

Briefly, I had thought of variants, but am also attracted to the idea of
'compatible structs'. These would be struct definition that when fed to a
suitable
template function, could be determined to be a match for a stated query - a bit
like isForwardRange ;=). Other templates would be provided to automate the
process
of 'applying' arrays of such structs to/from the database. Similar facilities
could be provided for arrays of arrays of variants.

At an even higher level one could have templates that implemented entire
operations, like updating a batch of records.

D's template facilities make such stuff easy to implement once you have certain
primitives to base them on. I am at that point now. I have bridgehead and can
consider breakout.

Steve
Oct 06 2011
parent Jacob Carlborg <doob me.com> writes:
On 2011-10-07 07:24, Steve Teale wrote:
 Andrei,

 I was thinking the same thing about the C level interface sometime in the
middle
 of last night. A straight translation of mysqld could be put there almost
 immediately. I have to make myself translate the character set stuff, and add
 that, but it's probably only a days work.

 As for the interface, I was influenced at the intermediate level by my memory
of
 using C#.

 I think that a DB interface for D should be something that provides an
understood
 set of facilities rather than an interface in the language sense that provides
 certain specific methods. This would allow a decent job to be done on
individual
 databases strengths, while making it easy for D programmers to move from one to
 another. I will write up a summary of my thoughts later today, and post it
here.

 Briefly, I had thought of variants, but am also attracted to the idea of
 'compatible structs'. These would be struct definition that when fed to a
suitable
 template function, could be determined to be a match for a stated query - a bit
 like isForwardRange ;=). Other templates would be provided to automate the
process
 of 'applying' arrays of such structs to/from the database. Similar facilities
 could be provided for arrays of arrays of variants.

 At an even higher level one could have templates that implemented entire
 operations, like updating a batch of records.

 D's template facilities make such stuff easy to implement once you have certain
 primitives to base them on. I am at that point now. I have bridgehead and can
 consider breakout.

 Steve

As I replied to another post: I think it's important to have a solid low level database API which later an object oriented abstraction can be built upon. In this low level API I don't think that results from SQL quires should be converted to structs. I think that's up to the higher, object oriented, level to do. -- /Jacob Carlborg
Oct 06 2011
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-10-07 03:17, Andrei Alexandrescu wrote:
 On 10/6/11 10:27 AM, Steve Teale wrote:
 Andrei,

 Are there guidelines for the Phobos process?

We follow the Boost review process: http://www.boost.org/community/reviews.html
 I have put a fair amount of work, two years ago and recently, into a
 piece for
 accessing MySQL via D. I'm looking at this as a bottom-up
 investigation into what
 might be a more generalized interface for database access.

 I've got to the point where I can support a good range of database
 operations, and
 present result sets as arrays of D structs, which presumably implies
 Ranges.
 There's also lower level stuff to do more complex operations. So I'm
 wondering if
 I should take the first process steps. I'm retired, so I do have time
 to spend on it.

 The MySQL C api is not what you could call orthogonal - in
 crystallography terms
 it is probably Triclinic, so it may not have been the best place to
 start. There's
 another guy I've had some correspondence with who is working on
 Postgres. He's
 interested in the same idea.

 What do you think?

I think this is a great initiative. Perhaps it would be nice to have a C-level API translation in etc.mysql. Then we should have a driver-style interface a la Java's JDBC, Perl's DBI, Python's PEP249 etc. For D in particular, I think the range aspect is secondary. Probably it will be more important to interoperate with Variant. Most APIs store columns in a Variant structure that captures all possible types of the database. Resultsets come as input ranges of array of Variant. It's not important to make them compatible with the input range interface because it's unlikely you'll pass that array of Variant directly to some algorithm. That being said, people will naturally expect to use the canonical range interface. It would probably be gratuitous to choose other primitive(s) than empty/front/popFront.

I think it's important to support the range interface (or if it's simpler, the array interface). I think ActiveRecord has a good high level API which allows to lazily evaluate SQL queries. persons = Person.all # no query is performed here persons = persons.where("name = 'Joe'") # or here persons.each do |p| # The actual query is performed here # do something with each Person end I don't think it would be strange to see something like this: Person.where("age > 10").map{ |p| p.name } # using "map" on an SQL query -- /Jacob Carlborg
Oct 06 2011
parent reply Jacob Carlborg <doob me.com> writes:
On 2011-10-07 09:26, Russel Winder wrote:
 On Fri, 2011-10-07 at 08:49 +0200, Jacob Carlborg wrote:
 [ . . . ]
 I think it's important to support the range interface (or if it's
 simpler, the array interface). I think ActiveRecord has a good high
 level API which allows to lazily evaluate SQL queries.

 persons = Person.all # no query is performed here
 persons = persons.where("name = 'Joe'") # or here

 persons.each do |p| # The actual query is performed here
       # do something with each Person
 end

 I don't think it would be strange to see something like this:

 Person.where("age>  10").map{ |p| p.name } # using "map" on an SQL query

Not just Ruby an Rails with ActiveRecord. Groovy/Grails/GORM does what is basically the same. Python cannot do the same in the same way Ruby and Groovy can, but it has it equivalent (augmented with SQLAlchemy). Basically it comes down to constructing dynamic queries using the dynamic and MOP nature of the languages. The crucial keyword here is Builder. The trick is that what looks like function call is actually interpreted via the builder/MOP as the construction of a data structure, which then creates the query on demand -- with template placeholder filling as required. Does D have the reflection capabilities to do this in any way, shape or form similar tp the way the dynamic languages do it?

It depends on what you want to achieve. If you want just the above example (and similar) to work, including lazy loading that would be possible and not very hard. If you want a more complete ORM and do things like (in Ruby): person = Person.find_all_by_name_and_age("Joe", 15) p person.name That's a little harder. You could use opDispatch to make "find_all_by_name_and_age" or "name" work, but not both. The problem is that you can not overload methods on static and you are not forced to call a static method prefixed with the class name. class Foo { void bar () {}; static void bar () {}; } Currently the above doesn't work. You can also call a static method on an instance, which will also cause problems. What we want here is to be able to have two versions of opDispatch, one static and one non-static. -- /Jacob Carlborg
Oct 07 2011
parent reply Adam Ruppe <destructionator gmail.com> writes:
What's the big advantage of

Person.find_all_by_name_and_age("Joe", 15)

over

db.query("select * from people where name = ? and age = ?", "Joe", 15);



The latter is much easier to write in the library and you retain all
the flexibility of sql itself if needed.
Oct 07 2011
parent Jacob Carlborg <doob me.com> writes:
On 2011-10-07 15:34, Adam Ruppe wrote:
 What's the big advantage of

 Person.find_all_by_name_and_age("Joe", 15)

 over

 db.query("select * from people where name = ? and age = ?", "Joe", 15);



 The latter is much easier to write in the library and you retain all
 the flexibility of sql itself if needed.

I guess it just depends on what you like. I prefer to use the first example. One advantage the first example could have would be to validate the column names. If it already knows the column names it won't have to query the database if the column names don't match. Of course it should always be possible to execute raw sql queries, like that last example. I suggest you take a look at the documentation for ActiveRecord, just to get a feel for the API: http://guides.rubyonrails.org/active_record_querying.html -- /Jacob Carlborg
Oct 07 2011
prev sibling next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message 
news:j6hrko$ni3$1 digitalmars.com...
 On 10/5/11 6:53 AM, Regan Heath wrote:
 On Tue, 04 Oct 2011 20:39:42 +0100, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> 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 assume you're referring to the trend of being unsatisfied with unwavering single-person vetos on trivial-to-implement issues that have landslide support?
 I sustained my position in this thread longer than necessary in an
 attempt to explain this to me and others.

 [snip big long story]

In other words, there are many ways in which D's existing libs fail to be sufficient for people's uses. Ummm, like getopt. Except getopt is easy low-hanging fruit.
 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?

For god's sake, it would have taken less time to implement the fucking change (that nobody but you has been opposed to), than to write that little story about why we should ignore the matter.
 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.

Not to be an ass, but even *I* don't think reviewing and getting outdent whipped into shape was a "big rock" or anything bigger than gravel. (Though I am very appreciative of it and I'm very happy with the final result.)
Oct 05 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/05/11 16:25, Nick Sabalausky wrote:
 "Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org>  wrote in message
 news:j6hrko$ni3$1 digitalmars.com...
 On 10/5/11 6:53 AM, Regan Heath wrote:
 On Tue, 04 Oct 2011 20:39:42 +0100, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org>  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 assume you're referring to the trend of being unsatisfied with unwavering single-person vetos on trivial-to-implement issues that have landslide support?

That would be a mistaken assumption.
 I sustained my position in this thread longer than necessary in an
 attempt to explain this to me and others.

 [snip big long story]

In other words, there are many ways in which D's existing libs fail to be sufficient for people's uses.

Actually, it's about entire libraries that are missing. We don't "kind of" have a MySQL library. We just don't have one.
 Ummm, like getopt.

 Except getopt is easy low-hanging fruit.

There's low hanging fruit. And then there's low hanging berries, seeds, and spores.
 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?

For god's sake, it would have taken less time to implement the fucking change (that nobody but you has been opposed to), than to write that little story about why we should ignore the matter.

I agree. That's not the point. (And relax.)
 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.

Not to be an ass, but even *I* don't think reviewing and getting outdent whipped into shape was a "big rock" or anything bigger than gravel. (Though I am very appreciative of it and I'm very happy with the final result.)

I'm happy too. Although it entailed essentially as much work from me as a full-fledged implementation (actually a tad more), it's a good outcome because (a) it adds genuine new functionality, (b) it sets up the stage for more new things in the future from you and others. Andrei
Oct 05 2011
parent reply Adam Ruppe <destructionator gmail.com> writes:
Andrei wrote:
 We don't "kind of" have a MySQL library. We just don't have one.

Actually, we have three or four. Maybe more. There aren't any in phobos, but they are still fairly easy to find. (Or hell to just wrap C takes less than an hour.)
Oct 05 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/05/11 17:53, Adam Ruppe wrote:
 Andrei wrote:
 We don't "kind of" have a MySQL library. We just don't have one.

Actually, we have three or four. Maybe more. There aren't any in phobos, but they are still fairly easy to find.

Well that wasn't the best example, but you know what I mean. Speaking of MySQL (and general SQL database) bindings, I'd be curious if you linked to a few. I know Steve Teale has suggested we add a binding to etc.c, which we should.
 (Or hell to just wrap C takes less than an hour.)

That turns out to require a fair amount of C and D expertise. It doesn't sit well with a new D user. Andrei
Oct 05 2011
parent reply Adam Ruppe <destructionator gmail.com> writes:
Andrei wrote:
 link to a few

There's mine: https://github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff see database.d and mysql.d for mysql. Also some code for postgres and sqlite in there own modules. Piotr Szturmaj's is postgres only, but generally vastly superior to my postgres module: http://www.digitalmars.com/d/archives/digitalmars/D/learn/D2_postgresql_interface_-_Phobos2_23693.html You remember Steve's post from a week or two ago. There's also this one I've heard of: http://www.dsource.org/projects/ddbi I'm sure it's ancient, but there might be something to use there. I'm pretty sure there's more but this is what I know off the top of my head.
Oct 05 2011
parent sclytrack <sclytrack linky.com> writes:
== Quote from Adam Ruppe (destructionator gmail.com)'s article
 Andrei wrote:
 link to a few

https://github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff see database.d and mysql.d for mysql. Also some code for postgres and sqlite in there own modules.

Are you using the 32 bit compiler?
 Piotr Szturmaj's is postgres only, but generally vastly superior
 to my postgres module:

https://github.com/pszturmaj/ddb boost
 You remember Steve's post from a week or two ago.
 There's also this one I've heard of:
 http://www.dsource.org/projects/ddbi
 I'm sure it's ancient, but there might be something to use there.
 I'm pretty sure there's more but this is what I know off the top
 of my head.

Oct 05 2011
prev sibling parent reply kennytm <kennytm gmail.com> writes:
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:
 On 10/5/11 6:53 AM, Regan Heath wrote:
 On Tue, 04 Oct 2011 20:39:42 +0100, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> 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

I don't buy this. You make it sounds like the community cannot contribute with more than 1 focus concurrently. The fact is that, the GCC integration, making wrappers of C library and switching to non-global in std.getopt are done in parallel by different subgroup of interests. I doubt if GDC will be locked out of GCC or people will stop writing D wrappers just because 3 globals are proposed to be removed.
Oct 05 2011
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/05/11 16:37, kennytm wrote:
 I don't buy this. You make it sounds like the community cannot contribute
 with more than 1 focus concurrently. The fact is that, the GCC integration,
 making wrappers of C library and switching to non-global in std.getopt are
 done in parallel by different subgroup of interests. I doubt if GDC will be
 locked out of GCC or people will stop writing D wrappers just because 3
 globals are proposed to be removed.

I used to think the same, but unfortunately it is a fact of life that we don't have as much parallelism as we should. Andrei
Oct 05 2011
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
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
Sep 29 2011
parent "Nick Sabalausky" <a a.a> writes:
"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message 
news:mailman.290.1317291489.26225.digitalmars-d 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.

Sep 29 2011
prev sibling next sibling parent "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Thu, 29 Sep 2011 18:41:33 +0300, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> 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, Vladimir mailto:vladimir thecybershadow.net
Sep 29 2011
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
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
Sep 29 2011
prev sibling next sibling parent "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Thu, 29 Sep 2011 18:55:39 +0300, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> 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, Vladimir mailto:vladimir thecybershadow.net
Sep 29 2011
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
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
Sep 29 2011
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
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
Sep 29 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, September 30, 2011 13:07:55 Christophe wrote:
 foobar , dans le message (digitalmars.D:145799), a =C3=A9crit :
 Does getopt (btw, awful name)

getopt is the name of a Posix function to read option arguments in ma=

 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 fi= nd it.=20 std.getopt.getopt doesn't follow Phobos' naming convention, so that wou= ld be a=20 good reason to change the name to getOpt or getOptions. The fact that P= osix=20 has a function with the same name doesn't necessarily mean all that muc= h,=20 since Posix uses different naming conventions from Phobos, and our geto= pt does=20 not work the same way as Posix' getopt (as I understand it, it's closer= to=20 perl's). Now, there is some argument for leaving it as getopt because o= f the=20 fact that several languages use that name, but if we need to change the= =20 defaults for getopt (and it looks like it's probably going to be a good= idea=20 to do so), then we need to change the function's name to avoid silently= =20 breaking code, which makes it so that we need to rename the function an= yway.=20 So, it becomes the perfect opportunity to make the name match Phobos' n= aming=20 conventions. If there's no need to try and avoid code breakage by chang= ing the=20 name, then it's more debatable, but from the looks of it, at minimum, t= he new=20 enum value in the pull request, noSpaceOnlyForShortNumericOptions, look= s like=20 it should probably be the default. So, I expect that the defaults will = change=20 slightly. - Jonathan M Davis
Sep 30 2011
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
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
Sep 30 2011
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
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
Sep 30 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
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
Oct 03 2011
prev sibling next sibling parent "Regan Heath" <regan netmail.co.nz> writes:
On Tue, 04 Oct 2011 05:20:48 +0100, Walter Bright  
<newshound2 digitalmars.com> 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/
Oct 04 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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.
Oct 04 2011
prev sibling next sibling parent "Marco Leise" <Marco.Leise gmx.de> writes:
Am 04.10.2011, 22:41 Uhr, schrieb Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org>:

 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.
Oct 04 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Yeah I've never seen --abc used as -a -b -c before, it looks quite
strange to me. Is this common in unixland?
Oct 04 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
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
Oct 04 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
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
Oct 04 2011
prev sibling next sibling parent "Marco Leise" <Marco.Leise gmx.de> writes:
Am 05.10.2011, 03:28 Uhr, schrieb Jonathan M Davis <jmdavisProg gmx.com>:

 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.
Oct 04 2011
prev sibling next sibling parent "Regan Heath" <regan netmail.co.nz> writes:
On Tue, 04 Oct 2011 20:39:42 +0100, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> 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/
Oct 05 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 05 Oct 2011 07:53:25 -0400, Regan Heath <regan netmail.co.nz>  
wrote:

 On Tue, 04 Oct 2011 20:39:42 +0100, Andrei Alexandrescu  
 <SeeWebsiteForEmail erdani.org> 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
Oct 05 2011
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Christophe wrote:
 Andrei Alexandrescu , dans le message (digitalmars.D:146070), a =E9crit=

 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 =E9crit :
 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 =





 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 get=




 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.
=20
 What exactly in std.getopt does not fulfill your needs? Would assemblin=


 the three variables into a structure help?

=20 No, it wouldn't. =20 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=20
 I=A0want 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
Oct 05 2011
prev sibling next sibling parent reply Jens Mueller <jens.k.mueller gmx.de> writes:
Christophe wrote:
 Jens Mueller , dans le message (digitalmars.D:146111), a =E9crit=A0:
 Christophe wrote:
 Andrei Alexandrescu , dans le message (digitalmars.D:146070), a =E9cri=



 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 =E9cri=






 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 =







 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 =







 switch(args) statement.

I don't use getopt often either. That does not prevent me to wish =






 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 nonem=




 but said needs are not fulfilled by the current std.getopt.
=20
 What exactly in std.getopt does not fulfill your needs? Would assemb=




 the three variables into a structure help?

=20 No, it wouldn't. =20 The main reason why I don't want to use getopt is because the syntax "=



 output" (short-option, space, argument), and that is the main thing=20
 I=A0want 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. =20
 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=20 -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=20
 character for options ('-'), and I belive the string for long option is=

 twice the character for short option ("--"). I don't think this makes=20
 great sense. We could parametrize a long option string (that we could=20
 set to "-"), and a short option char (that may or may not be=20
 automatically set to longOptionString[0]). But no parametrization on the=

 shortOptionChar and on the longOptionString is fine too. Nobody would=20
 complain the call to getopt could be screwed up by another programmer=20
 modifiying the shortOptionChar behind your back if this could not be=20
 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=20
 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
Oct 05 2011
parent "Nick Sabalausky" <a a.a> writes:
"Jens Mueller" <jens.k.mueller gmx.de> wrote in message 
news:mailman.21.1317824685.28623.digitalmars-d puremagic.com...
I think we have failed, if a significant number of users rather write
their own command line parsing than using the built-in one.

I suspect that what often happens is what happened to me: The D user has an idea of how they want their cmd line to work, they look at getopt and see it won't work that way, so instead of changing their design to fit getopt they just implement their own solution that actually does what they wanted in the first place. (After all, it's not that hard to make a basic cmdline parser. If it were harder then maybe more people would be succesfully strongarmed into changing their design to match getopt's abilities.) And I'm sure there are cases where a program actually needs to match an existing program's command line for interoperability, in which case changing the design to match getopt would not have even been an option in the first place. Encouraging a "recommended" way is admirable, but doing it by providing a tool that allows the recommended way and then outright doesn't support other ways is very anti-D-philosophy (and at best is going to annoy the very same sorts of people who are attracted to D, and create more work for them). The D-way (and IMO, the *right* way), is to make the "recommended" way the default (and ideally even explain that it's recommended and why), and then allow easy configurability for "heretical"-but-concievable uses. Of course, it's also the D-way to have a one-person veto carved in stone... On a related note, does getopt support the ability to say "allow long options that begin with *either* -- or /"? Since I make stuff that's compiled natively to Windows (as opposed to being a clumbsy mingw-esque "port"), that was important to me way back when, and IIRC may have been one of the reasons I rolled my own cmdline parser a few years ago.
Oct 05 2011
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
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
Oct 05 2011
parent "Nick Sabalausky" <a a.a> writes:
"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message 
news:mailman.23.1317827712.28623.digitalmars-d puremagic.com...
 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.


FWIW, that would make it possible to parse the command line of programs like *ahem* DMD itself.
 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.

Not all programs are Posix programs, though (for better or worse). Though I don't have any real data to back this up, single dash long options seem to be common on Windows. And I don't think I've ever seen combined short options on Windows software that wasn't a GNU port. Again, FWIW.
Oct 05 2011
prev sibling next sibling parent "Regan Heath" <regan netmail.co.nz> writes:
On Wed, 05 Oct 2011 16:03:11 +0100, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 10/5/11 6:53 AM, Regan Heath wrote:
 On Tue, 04 Oct 2011 20:39:42 +0100, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> 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.

I understand the issue, and the point you're making below, and I agree completely. At the same time, this particular change being as simple as it is, and as obviously beneficial as I hope I have managed to show, would have taken less time to simply change than it has taken to argue about. I agree we should not spend too long worrying about the smaller details, nor should we simply make change for the sake of change without spending the requisite time considering those changes, but that should not stop us making small beneficial changes alongside the larger more important ones. <quote left for context..>
 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.

-- Using Opera's revolutionary email client: http://www.opera.com/mail/
Oct 05 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
The reality is apps use many different sorts of argument passing
styles. Saying that one or the other is wrong is silly. Here's some
various flavors:

Firefox: firefox.exe -safe-mode www.mozilla.com
Scite: SciTE "-import c:\os\web_work" SciTEDoc.html
AVG: avgscanx.exe /comp /qt /priority=high /pwdw /report=d:\avgreport.txt
uTorrent: utorrent.exe /AUTOUPDATE
CDBurnerXP: cdbxpcmd.exe --list-drives
Foxit: "Foxit Reader.exe" -displayinbrowser

But if getopt wants to keep posix-style, that's fine with me. Like
I've said, I can roll out my own and it's not that big of a deal. It's
easy to roll out your own in D compared to doing it in C or even C++.
Oct 05 2011
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Christophe wrote:
 Jens Mueller , dans le message (digitalmars.D:146114), a =E9crit=A0:
 Christophe wrote:
 Jens Mueller , dans le message (digitalmars.D:146111), a =E9crit=A0:
 Christophe wrote:
 Andrei Alexandrescu , dans le message (digitalmars.D:146070), a =E9=





 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 =E9=








 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, a=









 other tools. It's not a big deal thanks to D's fantastic
 string-manipulation abilities, so I just roll my own. All I ne=









 switch(args) statement.

I don't use getopt often either. That does not prevent me to wi=








 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 no=






 but said needs are not fulfilled by the current std.getopt.
=20
 What exactly in std.getopt does not fulfill your needs? Would ass=






 the three variables into a structure help?

=20 No, it wouldn't. =20 The main reason why I don't want to use getopt is because the synta=





 output" (short-option, space, argument), and that is the main thing=





 I=A0want 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. =20
 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 =




 important (because you want to save a single character), then you co=




 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. =20
 However, the current way to parametrise getopt is to change the=20
 character for options ('-'), and I belive the string for long option i=



 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=20
 automatically set to longOptionString[0]). But no parametrization on t=



 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. =20
 Well, too much parametrization is wrong. But the posix way has to be=



 supported, and it includes "-o output" (which is much more helpful tha=



 -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=20 options. =20 No parametrization by global parameters is really preferable to use=20 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=20
 confortable with global parameters, but I don't know if I would use=20
 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=20
 that, and my input line parsing is crap).
=20
 One think I don't know regarding getopt, and that I didn't find in the=20
 documentation (maybe because I didn't look close enough after having=20
 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 ?=20
 Shouldn't getopt return an array of the remaning arguments ?

By remaining arguments you mean unrecognized options, aren't you? These are left in the passed array if configured with passThrough. I.e. getopt removes an option iff it is recognized. What do you mean by sorted arguments? Jens
Oct 05 2011
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Nick Sabalausky wrote:
 "Jens Mueller" <jens.k.mueller gmx.de> wrote in message 
 news:mailman.21.1317824685.28623.digitalmars-d puremagic.com...
I think we have failed, if a significant number of users rather write
their own command line parsing than using the built-in one.

I suspect that what often happens is what happened to me: The D user has an idea of how they want their cmd line to work, they look at getopt and see it won't work that way, so instead of changing their design to fit getopt they just implement their own solution that actually does what they wanted in the first place. (After all, it's not that hard to make a basic cmdline parser. If it were harder then maybe more people would be succesfully strongarmed into changing their design to match getopt's abilities.) And I'm sure there are cases where a program actually needs to match an existing program's command line for interoperability, in which case changing the design to match getopt would not have even been an option in the first place. Encouraging a "recommended" way is admirable, but doing it by providing a tool that allows the recommended way and then outright doesn't support other ways is very anti-D-philosophy (and at best is going to annoy the very same sorts of people who are attracted to D, and create more work for them). The D-way (and IMO, the *right* way), is to make the "recommended" way the default (and ideally even explain that it's recommended and why), and then allow easy configurability for "heretical"-but-concievable uses.

And here it gets difficult. To support many different ways makes the code complex and also the configuration process. Then we end up with an extremely configurable solution that nobody uses because it's too difficult to configure. Just think of the more manual pages to explain it. Maybe things can be sorted out but after all it's just command line arguments. For the moment I believe the easiest solution is to support Posix and leave it to the user if they don't like it to implement their own. Even better encourage people to create pull requests that extend getopt.
 Of course, it's also the D-way to have a one-person veto carved in stone...
 
 On a related note, does getopt support the ability to say "allow long 
 options that begin with *either* -- or /"? Since I make stuff that's 
 compiled natively to Windows (as opposed to being a clumbsy mingw-esque 
 "port"), that was important to me way back when, and IIRC may have been one 
 of the reasons I rolled my own cmdline parser a few years ago.

No. / won't be recognized as a long option. Jens
Oct 05 2011
prev sibling next sibling parent "Regan Heath" <regan netmail.co.nz> writes:
On Wed, 05 Oct 2011 16:44:31 +0100, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 10/5/11 10:27 AM, Regan Heath wrote:
 I understand the issue, and the point you're making below, and I agree
 completely. At the same time, this particular change being as simple as
 it is, and as obviously beneficial as I hope I have managed to show,
 would have taken less time to simply change than it has taken to argue
 about.

There is the issue that every small change creates a precedent for similar or smaller changes. I spent this much time on this particular issue hoping that it would improve an entire trend going forward.

I think it may have backfired somewhat. Now people are going to think no change is possible and Andrei is an 'Ogre' when it comes to his own modules. In situations like this some sort of precedent or impression will always be created. The best you can do is take control of it, and clearly define it. In this case clearly define the conditions under which the change is allowed i.e. 1. The interface MUST not change (retaining the getopt free function for example) 2. The default behaviour MUST not change (retaining the current default values for the globals) and make that the precedent to enforce on future occasions. It should be like "common law", defined by the first instance, changed hesitantly and only for very good reasons. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Oct 06 2011
prev sibling next sibling parent "Regan Heath" <regan netmail.co.nz> writes:
On Thu, 06 Oct 2011 10:44:42 +0100, Regan Heath <regan netmail.co.nz>  
wrote:

 On Wed, 05 Oct 2011 16:44:31 +0100, Andrei Alexandrescu  
 <SeeWebsiteForEmail erdani.org> wrote:

 On 10/5/11 10:27 AM, Regan Heath wrote:
 I understand the issue, and the point you're making below, and I agree
 completely. At the same time, this particular change being as simple as
 it is, and as obviously beneficial as I hope I have managed to show,
 would have taken less time to simply change than it has taken to argue
 about.

There is the issue that every small change creates a precedent for similar or smaller changes. I spent this much time on this particular issue hoping that it would improve an entire trend going forward.

I think it may have backfired somewhat. Now people are going to think no change is possible and Andrei is an 'Ogre' when it comes to his own modules. In situations like this some sort of precedent or impression will always be created. The best you can do is take control of it, and clearly define it. In this case clearly define the conditions under which the change is allowed

.. or not allowed. :p It's obvious from my last post that I think a change should be allowed. I think you'd agree, were it not for the urgent need of other library components. I've been lurking and contributing to this news group on and off for years (since 2005/2006, maybe earlier). But, in all that time I have contributed nothing to Phobos. I have contributed a set of digest/hashing routines to Tango, because at the time Phobos wasn't taking submissions. I have been meaning to clean my originals of these up, get them properly documented, etc and submit them for review for Phobos, but I just haven't had the time, and/or inclination to do so (my free time is precious and I've just not been feeling the urge/itch to code.. blame minecraft :p) However, I am more than happy to hand them off in their current state to anyone who does have both time and inclination .. and I wonder how many other blocks of code are out there, just like mine, just waiting for the right person to take charge of them. Would this be useful do you think? Or would the time it takes someone to pick up new code, learn it, fine tune it and document it.. etc be more than if they just started again from scratch. It seems to me that sometimes, all that is needed to get a new module off the ground is a working prototype for the guts of it, which is what people like me who have some experience/knowledge but little time/energy could do, before handing it to someone who has a better idea of the D/Phobos 'way' and can organise the guts into a well formed module which complies with D style and Phobos guidelines etc. Part of what puts people off (I suspect) is the 'relative' complexity of submitting code (obtaining/learning GIT etc), the standard the code needs to be at (well organised, documented etc), and the implied promise/commitment that submitting code brings with it (that you'll hang around and maintain it). But, what if we were to create a system where people could submit code, no strings attached, in any state (they would define the state they believe it to be in) for the more dedicated contributors to pick up, clean up, and include as and when they could? It could be as simple as a web page, where code is pasted, files attached, and a license waiver agreed to. I know I have several pieces of code floating about the place which do useful things and would be motivated to create more if it would help the effort, and I could get a mention in the comments at the top of the finished module :p -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Oct 06 2011
prev sibling next sibling parent reply "Regan Heath" <regan netmail.co.nz> writes:
On Thu, 06 Oct 2011 15:47:03 +0100, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 10/6/11 5:25 AM, Regan Heath wrote:
 I've been lurking and contributing to this news group on and off for
 years (since 2005/2006, maybe earlier). But, in all that time I have
 contributed nothing to Phobos. I have contributed a set of
 digest/hashing routines to Tango, because at the time Phobos wasn't
 taking submissions. I have been meaning to clean my originals of these
 up, get them properly documented, etc and submit them for review for
 Phobos, but I just haven't had the time, and/or inclination to do so (my
 free time is precious and I've just not been feeling the urge/itch to
 code.. blame minecraft :p)

 However, I am more than happy to hand them off in their current state to
 anyone who does have both time and inclination .. and I wonder how many
 other blocks of code are out there, just like mine, just waiting for the
 right person to take charge of them. Would this be useful do you think?
 Or would the time it takes someone to pick up new code, learn it, fine
 tune it and document it.. etc be more than if they just started again
 from scratch. It seems to me that sometimes, all that is needed to get a
 new module off the ground is a working prototype for the guts of it,
 which is what people like me who have some experience/knowledge but
 little time/energy could do, before handing it to someone who has a
 better idea of the D/Phobos 'way' and can organise the guts into a well
 formed module which complies with D style and Phobos guidelines etc.

 Part of what puts people off (I suspect) is the 'relative' complexity of
 submitting code (obtaining/learning GIT etc), the standard the code
 needs to be at (well organised, documented etc), and the implied
 promise/commitment that submitting code brings with it (that you'll hang
 around and maintain it). But, what if we were to create a system where
 people could submit code, no strings attached, in any state (they would
 define the state they believe it to be in) for the more dedicated
 contributors to pick up, clean up, and include as and when they could?
 It could be as simple as a web page, where code is pasted, files
 attached, and a license waiver agreed to.

 I know I have several pieces of code floating about the place which do
 useful things and would be motivated to create more if it would help the
 effort, and I could get a mention in the comments at the top of the
 finished module :p

Thanks for your thoughts and generosity. It's great you are sharing your code in the hope it adds value to the community.

That's just it however, I am not generous enough with my time to be of use to you/D/phobos. I spend my free time doing other things, and not working on the code I have which could be of use. I suspect there are quite a number of people out there who are just like me. People who have some code which may be of use, in varying degrees of completeness from just an idea to a pretty much complete re-usable library which just needs the final touches etc. If we collect these pieces of code somewhere and make it searchable then anyone could pick up a piece and re-use it, or work on it, or .. well anything they want. That's all I'm suggesting, that we create a "well of lost code" and let people dump things there.
 Also, if past is indicative of future, it's possible but unlikely that  
 someone will take your code, bring it to perfection, and go through the  
 hurdles of submitting it to Phobos.

 Making a body of code into a reusable library is often comparable work  
 with writing the code itself. It's also seen by many as unpleasant work,  
 which means most people would be more motivated to do it for their own  
 work rather than others'.

You're probably right, people prefer their own code. And, doing the work required to get something to the level required for Phobos is not as pleasant as hacking away at more 'exciting' things, this is exactly why my code remains incomplete (from a Phobos submission point of view). But, they don't have to work on 'my' code, they might take it and tear it to pieces and only really take the ideas away to create something new. The point is, it's a starting point.
 Things have changed a lot in the way D is evolving. This includes  
 migration to git, opening the compiler, runtime, and standard library  
 for contributions, and a review process for adding to the standard  
 library. Focusing on the last aspect, this has been a big change from  
 the previous approach in which the standard library was closed, and from  
 an awkward stage in which we were inclined to accept somewhat random  
 contributions (encoding, xml, json) without much due process.

 By any measure I can think of, establishing a review process has been a  
 tremendous success, and everything else failed. We have std.datetime,  
 std.parallelism to show, and there are many more to come. The difficulty  
 in carrying through a Phobos submission also means establishing a strong  
 esprit de corps, a commitment to quality, and a sense of meaningfully  
 moving things forward together.

Sure, all this is true. The new model works and is great. I'm not suggesting a replacement for that, but rather a resource which might aid it.
 As far as I know many other open source projects follow a similar model.  
 There is essentially no evidence in this space to suggest that your  
 hypothetical model of development would work.

The size of a contribution for phobos is (one complete module) whereas in many open source projects you can contribute as little as a line of code/fix for a problem. The goal of this idea is to lower the bar for "contributions" and "contributors" to include more people and more code until even very small ideas/examples may eventually contribute to the whole if only indirectly. In any case, it's just an idea :p -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Oct 06 2011
parent reply Jesse Phillips <jessekphillips+D gmail.com> writes:
Regan Heath Wrote:

 That's just it however, I am not generous enough with my time to be of use  
 to you/D/phobos.  I spend my free time doing other things, and not working  
 on the code I have which could be of use.  I suspect there are quite a  
 number of people out there who are just like me.  People who have some  
 code which may be of use, in varying degrees of completeness from just an  
 idea to a pretty much complete re-usable library which just needs the  
 final touches etc.

The problem is as you say, there are many out there like you. Even if some people take the rule of getting these polished, they couldn't keep up. Finding these people his hard.
 The size of a contribution for phobos is (one complete module) whereas in  
 many open source projects you can contribute as little as a line of  
 code/fix for a problem.  The goal of this idea is to lower the bar for  
 "contributions" and "contributors" to include more people and more code  
 until even very small ideas/examples may eventually contribute to the  
 whole if only indirectly.

Contributions can be of any size. You don't even need to use Git/pull requests. Just attach a diff to a bug in BugZilla. And these changes don't go throw the formal review, just those with Phobos repo access. What you are looking for is Dsource, or Github, or any other source repository. You place your code up on the web and license it under Boost, someone can modify it for Phobos. But the problem is, organizing all of them. People don't have interest in placing projects on Dsource anymore because it can't be organized well and it is relies on one person to update the software. So people go else where, but they don't want to take the time to manage what their project does over on Wiki4D, so someone else does it but isn't informed when updates need made. So please keep writing software for yourself. Choose an appropriate license for how you feel it should be used and do what you do.
Oct 06 2011
parent Jacob Carlborg <doob me.com> writes:
On 2011-10-06 21:44, Jesse Phillips wrote:
 Regan Heath Wrote:

 That's just it however, I am not generous enough with my time to be of use
 to you/D/phobos.  I spend my free time doing other things, and not working
 on the code I have which could be of use.  I suspect there are quite a
 number of people out there who are just like me.  People who have some
 code which may be of use, in varying degrees of completeness from just an
 idea to a pretty much complete re-usable library which just needs the
 final touches etc.

The problem is as you say, there are many out there like you. Even if some people take the rule of getting these polished, they couldn't keep up. Finding these people his hard.

Even if we just get one contribution to Phobos through this method it would be better than nothing. -- /Jacob Carlborg
Oct 06 2011
prev sibling next sibling parent Russel Winder <russel russel.org.uk> writes:
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Fri, 2011-10-07 at 08:49 +0200, Jacob Carlborg wrote:
[ . . . ]
 I think it's important to support the range interface (or if it's=20
 simpler, the array interface). I think ActiveRecord has a good high=20
 level API which allows to lazily evaluate SQL queries.
=20
 persons =3D Person.all # no query is performed here
 persons =3D persons.where("name =3D 'Joe'") # or here
=20
 persons.each do |p| # The actual query is performed here
      # do something with each Person
 end
=20
 I don't think it would be strange to see something like this:
=20
 Person.where("age > 10").map{ |p| p.name } # using "map" on an SQL query

Not just Ruby an Rails with ActiveRecord. Groovy/Grails/GORM does what is basically the same. Python cannot do the same in the same way Ruby and Groovy can, but it has it equivalent (augmented with SQLAlchemy). Basically it comes down to constructing dynamic queries using the dynamic and MOP nature of the languages. The crucial keyword here is Builder. The trick is that what looks like function call is actually interpreted via the builder/MOP as the construction of a data structure, which then creates the query on demand -- with template placeholder filling as required. Does D have the reflection capabilities to do this in any way, shape or form similar tp the way the dynamic languages do it? --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel russel.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Oct 07 2011
prev sibling next sibling parent Russel Winder <russel russel.org.uk> writes:
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Fri, 2011-10-07 at 08:51 +0200, Jacob Carlborg wrote:
[ . . . ]
 I think it's important to have a solid low level database API which an=

 object oriented abstraction can be built upon.

Why object oriented? Why not functional? The lesson form ORMs is that object oriented and relational can be linked with an adaptor but the impedance mismatch is high. But if you want to use an ORM use one, of course. The computational model having issued a query is just data transformation which is nicely functional, albeit possibly with side effects. But then the FP crowd have given everyone monads. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel russel.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Oct 07 2011
prev sibling next sibling parent "Marco Leise" <Marco.Leise gmx.de> writes:
Am 07.10.2011, 09:26 Uhr, schrieb Russel Winder <russel russel.org.uk>:

 On Fri, 2011-10-07 at 08:49 +0200, Jacob Carlborg wrote:
 [ . . . ]
 I think it's important to support the range interface (or if it's
 simpler, the array interface). I think ActiveRecord has a good high
 level API which allows to lazily evaluate SQL queries.

 persons = Person.all # no query is performed here
 persons = persons.where("name = 'Joe'") # or here

 persons.each do |p| # The actual query is performed here
      # do something with each Person
 end

 I don't think it would be strange to see something like this:

 Person.where("age > 10").map{ |p| p.name } # using "map" on an SQL query

Not just Ruby an Rails with ActiveRecord. Groovy/Grails/GORM does what is basically the same. Python cannot do the same in the same way Ruby and Groovy can, but it has it equivalent (augmented with SQLAlchemy). Basically it comes down to constructing dynamic queries using the dynamic and MOP nature of the languages. The crucial keyword here is Builder. The trick is that what looks like function call is actually interpreted via the builder/MOP as the construction of a data structure, which then creates the query on demand -- with template placeholder filling as required. Does D have the reflection capabilities to do this in any way, shape or form similar tp the way the dynamic languages do it?

This has already been done in D. There is a nice library that assembles queries at compile time and fetches results lazily into structs. The name? Sorry, I forgot. But the author will probably show up here.
Oct 07 2011
prev sibling parent "Regan Heath" <regan netmail.co.nz> writes:
On Fri, 07 Oct 2011 07:40:01 +0100, Jacob Carlborg <doob me.com> wrote:

 On 2011-10-06 21:44, Jesse Phillips wrote:
 Regan Heath Wrote:

 That's just it however, I am not generous enough with my time to be of  
 use
 to you/D/phobos.  I spend my free time doing other things, and not  
 working
 on the code I have which could be of use.  I suspect there are quite a
 number of people out there who are just like me.  People who have some
 code which may be of use, in varying degrees of completeness from just  
 an
 idea to a pretty much complete re-usable library which just needs the
 final touches etc.

The problem is as you say, there are many out there like you. Even if some people take the rule of getting these polished, they couldn't keep up. Finding these people his hard.

Even if we just get one contribution to Phobos through this method it would be better than nothing.

Exactly. The people taking ideas from the pool don't have to keep up, they just need to be someone with the time/inclination to "complete" something/anything worthy of inclusion into phobos. All the pool does is give them a leg-up or provide the technical know-how/guts they might be missing. It would be something like dsource, but for code ranging from snippets to complete packages, and would have to be well organised, or at least searchable and rely on contributors including as much info about thier snippets etc as they can. But, that's a nice small investment for someone, especially if we make it easy to contribute the code, agree to a license and add info about it which is then searchable. I realise setting something like this up is no small amount of work, and that I'm in no position to do it, but it seems on the face of it to be a good idea. The pool would serve double duty, as it would supply code examples/snippets to people learning D also, or anyone looking for examples of how to do .. well, anything that gets contributed. Each of us probably has a collection of D code on our own HDDs somewhere which does interesting and useful things, but no-one else can see it, search it, or learn from it. I'm simply suggesting we put it somewhere to share. At it's most basic it could just be a wiki page, which we let google index for us. -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Oct 07 2011