www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Flag proposal

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
https://github.com/D-Programming-Language/phobos/pull/94

Discuss!

Andrei
Jun 10 2011
next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
I like how your proposal is already a pull request.

I'm not too fond of this workaround:

bool state;
getopt(
    args,
    "state",      &state,
);
auto line = getLine(cast(Flag!"KeepTerminator")state);

Will getopt know how to use Flags? What about std.conv.to?

std.format/write will have to know how to print out a Flag too, or we
have to cast:
writeln(cast(bool)keepTerminator);

If the plan is to replace all boolean arguments in Phobos with Flags,
won't this break a lot of code? We'll have to switch to using this
template, and then if we finally get named arguments sometime down the
road we will have to convert everything back to bools again.
Jun 10 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/10/11 11:45 AM, Andrej Mitrovic wrote:
 I like how your proposal is already a pull request.

 I'm not too fond of this workaround:

 bool state;
 getopt(
      args,
      "state",&state,
 );
 auto line = getLine(cast(Flag!"KeepTerminator")state);

 Will getopt know how to use Flags? What about std.conv.to?

Yes, getopt should support any enum using bool as its base. std.conv already supports all enums.
 std.format/write will have to know how to print out a Flag too, or we
 have to cast:
 writeln(cast(bool)keepTerminator);

Without the cast, writeln prints "yes" or "no", which may be desirable. If you want to print the bool, you can say writeln(keepTerminator == Flag!"KeepTerminator".yes); or writeln(!!keepTerminator); etc. I find this array of options quite sensible.
 If the plan is to replace all boolean arguments in Phobos with Flags,
 won't this break a lot of code?

Migration can be done piecemeal with deprecation and all.
 We'll have to switch to using this
 template, and then if we finally get named arguments sometime down the
 road we will have to convert everything back to bools again.

If we convert back to bool the problem remains that people still can just pass "true" or whatever without specifying the name of the parameter. True, they could and should specify the name of the parameter, but by that argument they could and should insert a comment right now - and nobody does. Andrei
Jun 10 2011
parent KennyTM~ <kennytm gmail.com> writes:
On Jun 11, 11 01:41, Andrej Mitrovic wrote:
 On 6/10/11, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org>  wrote:
 Without the cast, writeln prints "yes" or "no", which may be desirable.
 If you want to print the bool, you can say

 writeln(keepTerminator == Flag!"KeepTerminator".yes);

 or

 writeln(!!keepTerminator);

Oh, maybe this was already incorporated into format but I didn't nocie, I just did a blunt copy/paste of the template code so it didn't work for me: D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\format.d(1624): Error: template std.format.formatValue(Writer,T,Char) if (is(const(T) == const(void[]))) formatValue(Writer,T,Char) if (is(const(T) == const(void[]))) matches more than one template declaration, D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\format.d(895):formatValue(Writer,T,Char) if (is(T == enum)) and D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\format.d(1104):formatValue(Writer,T,Char) if (is(T : bool))

Try to use the Phobos on git master. I have fixed this already (bug 5837) and the patch has been merged on June 3rd.
Jun 10 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 6/10/11, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:
 Without the cast, writeln prints "yes" or "no", which may be desirable.
 If you want to print the bool, you can say

 writeln(keepTerminator == Flag!"KeepTerminator".yes);

 or

 writeln(!!keepTerminator);

Oh, maybe this was already incorporated into format but I didn't nocie, I just did a blunt copy/paste of the template code so it didn't work for me: D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\format.d(1624): Error: template std.format.formatValue(Writer,T,Char) if (is(const(T) == const(void[]))) formatValue(Writer,T,Char) if (is(const(T) == const(void[]))) matches more than one template declaration, D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\format.d(895):formatValue(Writer,T,Char) if (is(T == enum)) and D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\format.d(1104):formatValue(Writer,T,Char) if (is(T : bool))
Jun 10 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
*notice
Jun 10 2011
prev sibling next sibling parent reply Robert Clipsham <robert octarineparrot.com> writes:
On 10/06/2011 17:15, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/phobos/pull/94

 Discuss!

 Andrei

I really *really* don't like this. It's ugly and verbose, and a pathetic work around for the lack of named parameters. Either support named parameters or not, don't have an ugly half-baked work-around. -- Robert http://octarineparrot.com/
Jun 10 2011
next sibling parent KennyTM~ <kennytm gmail.com> writes:
On Jun 11, 11 01:42, Robert Clipsham wrote:
 On 10/06/2011 17:15, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/phobos/pull/94

 Discuss!

 Andrei

I really *really* don't like this. It's ugly and verbose, and a pathetic work around for the lack of named parameters. Either support named parameters or not, don't have an ugly half-baked work-around.

Well I agree it is ugly, but at least it's better than having the same enum 7 times in Phobos (std.stdio.KeepTerminator, std.string.CaseSensitive, std.algorithm.OpenRight, std.algorithm.SortOutput, std.datetime.AllowDayOverflow, std.datetime.PopFirst, std.datetime.AutoStart). If named parameter is supported, those Flag!"foo" parameters can be reverted back to bool without breaking the caller as the enum is based on bool.
Jun 10 2011
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/10/11 12:42 PM, Robert Clipsham wrote:
 On 10/06/2011 17:15, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/phobos/pull/94

 Discuss!

 Andrei

I really *really* don't like this. It's ugly and verbose, and a pathetic work around for the lack of named parameters. Either support named parameters or not, don't have an ugly half-baked work-around.

This is not half-baked. It's pretty much it. Ugly is in the eye of the beholder, but I fail to see how the added punctuation makes Flag!"param".yes significantly more verbose than param : true. The problem that named parameters are still optional remains. Or we need to add one extra language feature to specify required named parameters. Andrei
Jun 10 2011
next sibling parent reply Robert Clipsham <robert octarineparrot.com> writes:
On 10/06/2011 19:06, Andrei Alexandrescu wrote:
 On 6/10/11 12:42 PM, Robert Clipsham wrote:
 On 10/06/2011 17:15, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/phobos/pull/94

 Discuss!

 Andrei

I really *really* don't like this. It's ugly and verbose, and a pathetic work around for the lack of named parameters. Either support named parameters or not, don't have an ugly half-baked work-around.

This is not half-baked. It's pretty much it.

My choice of wording was poor, sorry.
 Ugly is in the eye of the beholder, but I fail to see how the added
 punctuation makes Flag!"param".yes significantly more verbose than param
 : true.

foo(param: true, otherParam: false); foo(Flag!"param".yes, Flag!"otherParam".no); I don't know about you, but I find the former is far more legible. I'd hate to see my code littered with Flag!"something".
 The problem that named parameters are still optional remains. Or we need
 to add one extra language feature to specify required named parameters.

void foo(bool param, bool otherParam, bool thisOneIsntRequired = false); Call it with or without named parameters, two are required, one is not. foo(otherParam: true, param: false); foo(true, false); foo(otherParam: true, param: false, thisOneIsntRequired: true); Would all be valid.
 Andrei

-- Robert http://octarineparrot.com/
Jun 10 2011
next sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2011-06-10 14:52:53 -0400, Robert Clipsham <robert octarineparrot.com> said:

 On 10/06/2011 19:06, Andrei Alexandrescu wrote:
 Ugly is in the eye of the beholder, but I fail to see how the added
 punctuation makes Flag!"param".yes significantly more verbose than param
 : true.

foo(param: true, otherParam: false); foo(Flag!"param".yes, Flag!"otherParam".no); I don't know about you, but I find the former is far more legible. I'd hate to see my code littered with Flag!"something".

I have to say I totally agree with Robert. I agree with the need for a way to name parameters, but instantiating a pseudo-boolean type from a template for each function parameter is worse than the initial problem. Templates are already a difficult concept to grasp for most people (because they're so abstract), we really don't need to replace every boolean parameter with a template type.
 The problem that named parameters are still optional remains. Or we need
 to add one extra language feature to specify required named parameters.

void foo(bool param, bool otherParam, bool thisOneIsntRequired = false); Call it with or without named parameters, two are required, one is not. foo(otherParam: true, param: false); foo(true, false); foo(otherParam: true, param: false, thisOneIsntRequired: true);

And just try to think of the signature for the function above if it was using Flag! void foo(Flag!"param" param, Flag!"otherParam" otherParam, Flag!"thisOneIsntRequired" thisOneIsntRequired = Flag!"thisOneIsntRequired".no); Do we really want to expose that in the documentation? -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jun 10 2011
next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Michel Fortin" <michel.fortin michelf.com> wrote in message 
news:istqjn$2jld$1 digitalmars.com...
 On 2011-06-10 14:52:53 -0400, Robert Clipsham <robert octarineparrot.com> 
 said:

 On 10/06/2011 19:06, Andrei Alexandrescu wrote:
 Ugly is in the eye of the beholder, but I fail to see how the added
 punctuation makes Flag!"param".yes significantly more verbose than param
 : true.

foo(param: true, otherParam: false); foo(Flag!"param".yes, Flag!"otherParam".no); I don't know about you, but I find the former is far more legible. I'd hate to see my code littered with Flag!"something".

I have to say I totally agree with Robert. I agree with the need for a way to name parameters, but instantiating a pseudo-boolean type from a template for each function parameter is worse than the initial problem. Templates are already a difficult concept to grasp for most people (because they're so abstract), we really don't need to replace every boolean parameter with a template type.
 The problem that named parameters are still optional remains. Or we need
 to add one extra language feature to specify required named parameters.

void foo(bool param, bool otherParam, bool thisOneIsntRequired = false); Call it with or without named parameters, two are required, one is not. foo(otherParam: true, param: false); foo(true, false); foo(otherParam: true, param: false, thisOneIsntRequired: true);

And just try to think of the signature for the function above if it was using Flag! void foo(Flag!"param" param, Flag!"otherParam" otherParam, Flag!"thisOneIsntRequired" thisOneIsntRequired = Flag!"thisOneIsntRequired".no); Do we really want to expose that in the documentation?

I completely agree with Robert and Michel on all the points they've raised. Flag is admittedly a great example of the power of D's templates. And it's admittedly a very clever hack to get around *some* of the limitations of not having named parameters...*But* it's *still* just that: a hack to get around some of the limitations of not having named parameters. And yes, it is comparatively ugly, as Robert and Michel's examples have very clearly shown. Also:
 The problem that named parameters are still optional remains. Or we need
 to add one extra language feature to specify required named parameters.



If by that, you meant that the caller is allowed to call the function without naming the parameters, I really don't see that as a problem. Yea, *maybe* it would be better if the callee could optionally decide "caller must use named params", but even without that, it's a hell of a lot better than the current state, and it's also a lot better than Flag becase 1. It's *much* cleaner for both the caller and callee, and 2. It works for functions like foo(int, int, int, int), not just bools.
Jun 10 2011
parent David Nadlinger <see klickverbot.at> writes:
On 6/10/11 9:47 PM, Nick Sabalausky wrote:
 I completely agree with Robert and Michel on all the points they've raised.
 Flag is admittedly a great example of the power of D's templates. And it's
 admittedly a very clever hack to get around *some* of the limitations of not
 having named parameters...*But* it's *still* just that: a hack to get around
 some of the limitations of not having named parameters. And yes, it is
 comparatively ugly, as Robert and Michel's examples have very clearly shown.

 Also:

 The problem that named parameters are still optional remains. Or we need
 to add one extra language feature to specify required named parameters.



If by that, you meant that the caller is allowed to call the function without naming the parameters, I really don't see that as a problem. Yea, *maybe* it would be better if the callee could optionally decide "caller must use named params", but even without that, it's a hell of a lot better than the current state, and it's also a lot better than Flag becase 1. It's *much* cleaner for both the caller and callee, and 2. It works for functions like foo(int, int, int, int), not just bools.

That quite accurately summarizes the reason for my short »I'm not really sure what to think about this – […] named parameters would be the better solution« comment on the pull request; full ack. David
Jun 10 2011
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/10/11 2:12 PM, Michel Fortin wrote:
 On 2011-06-10 14:52:53 -0400, Robert Clipsham
 <robert octarineparrot.com> said:

 On 10/06/2011 19:06, Andrei Alexandrescu wrote:
 Ugly is in the eye of the beholder, but I fail to see how the added
 punctuation makes Flag!"param".yes significantly more verbose than param
 : true.

foo(param: true, otherParam: false); foo(Flag!"param".yes, Flag!"otherParam".no); I don't know about you, but I find the former is far more legible. I'd hate to see my code littered with Flag!"something".

I have to say I totally agree with Robert. I agree with the need for a way to name parameters, but instantiating a pseudo-boolean type from a template for each function parameter is worse than the initial problem. Templates are already a difficult concept to grasp for most people (because they're so abstract), we really don't need to replace every boolean parameter with a template type.

I disagree with the "templates are difficult" mantra. It is a meme from C++ much like "macros are evil" are one from C. It's a simple construct, you use it.
 The problem that named parameters are still optional remains. Or we need
 to add one extra language feature to specify required named parameters.

void foo(bool param, bool otherParam, bool thisOneIsntRequired = false); Call it with or without named parameters, two are required, one is not. foo(otherParam: true, param: false); foo(true, false); foo(otherParam: true, param: false, thisOneIsntRequired: true);

And just try to think of the signature for the function above if it was using Flag! void foo(Flag!"param" param, Flag!"otherParam" otherParam, Flag!"thisOneIsntRequired" thisOneIsntRequired = Flag!"thisOneIsntRequired".no); Do we really want to expose that in the documentation?

Yes, that's the whole point, though I agree the hiccup in the default initializer is annoying. The documentation doesn't need the names anymore; the user would just say: void foo( Flag!"compressed", Flag!"encrypted", Flag!"buffered" = Flag!"buffered".no); Save for the "ehm" default parameter this looks palatable to me. Andrei
Jun 10 2011
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2011-06-10 16:10:51 -0400, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 On 6/10/11 2:12 PM, Michel Fortin wrote:
 I have to say I totally agree with Robert.
 
 I agree with the need for a way to name parameters, but instantiating a
 pseudo-boolean type from a template for each function parameter is worse
 than the initial problem. Templates are already a difficult concept to
 grasp for most people (because they're so abstract), we really don't
 need to replace every boolean parameter with a template type.

I disagree with the "templates are difficult" mantra. It is a meme from C++ much like "macros are evil" are one from C. It's a simple construct, you use it.

Neither C macros nor C++ or D templates are very difficult by themselves. People trying to do unintuitive but clever things with them earned them this reputation. If you want something to be used everywhere and it is not an implementation detail, make it part of the language. Implementing what sounds should be a language feature through a template hack and putting it the standard library is not going to make people feel good about the language, it'll remind them of what the language is missing.
 And just try to think of the signature for the function above if it was
 using Flag!
 
 void foo(Flag!"param" param, Flag!"otherParam" otherParam,
 Flag!"thisOneIsntRequired" thisOneIsntRequired =
 Flag!"thisOneIsntRequired".no);
 
 Do we really want to expose that in the documentation?

Yes, that's the whole point, though I agree the hiccup in the default initializer is annoying.

I find it funny that you see a hiccup only in the default initializer when the name of all parameter is also duplicated in its type. Shouldn't that be 4 hiccups?
 The documentation doesn't need the names anymore; the user would just say:
 
 void foo(
    Flag!"compressed",
    Flag!"encrypted",
    Flag!"buffered" = Flag!"buffered".no);
 
 Save for the "ehm" default parameter this looks palatable to me.

Does that mean we now need a language feature to tell the documentation generator not to emit attribute names for parameters of type Flag!"" ? -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jun 10 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/10/11 3:34 PM, Michel Fortin wrote:
 On 2011-06-10 16:10:51 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> said:

 On 6/10/11 2:12 PM, Michel Fortin wrote:
 I have to say I totally agree with Robert.

 I agree with the need for a way to name parameters, but instantiating a
 pseudo-boolean type from a template for each function parameter is worse
 than the initial problem. Templates are already a difficult concept to
 grasp for most people (because they're so abstract), we really don't
 need to replace every boolean parameter with a template type.

I disagree with the "templates are difficult" mantra. It is a meme from C++ much like "macros are evil" are one from C. It's a simple construct, you use it.

Neither C macros nor C++ or D templates are very difficult by themselves. People trying to do unintuitive but clever things with them earned them this reputation.

See, here you're simply wrong. C macros are heinously complicated in definition, and heinously complicated to implement. C++ templates are very bulky in definition too. It's not worth your time you argue this further.
 If you want something to be used everywhere and it is not an
 implementation detail, make it part of the language. Implementing what
 sounds should be a language feature through a template hack and putting
 it the standard library is not going to make people feel good about the
 language, it'll remind them of what the language is missing.

The problem with the "hack" label is that it instantly decreases the level of the conversation. It's the "N" word of programming. I don't want a universal thing, I want to solve a simple problem: there are 7 yes/no enums in Phobos, and probably some more to come. Flag solves that problem in a reasonable way. This is pretty much it.
 And just try to think of the signature for the function above if it was
 using Flag!

 void foo(Flag!"param" param, Flag!"otherParam" otherParam,
 Flag!"thisOneIsntRequired" thisOneIsntRequired =
 Flag!"thisOneIsntRequired".no);

 Do we really want to expose that in the documentation?

Yes, that's the whole point, though I agree the hiccup in the default initializer is annoying.

I find it funny that you see a hiccup only in the default initializer when the name of all parameter is also duplicated in its type. Shouldn't that be 4 hiccups?

I don't think so, but I understand how you can frame that as an argument that supports your viewpoint.
 The documentation doesn't need the names anymore; the user would just
 say:

 void foo(
 Flag!"compressed",
 Flag!"encrypted",
 Flag!"buffered" = Flag!"buffered".no);

 Save for the "ehm" default parameter this looks palatable to me.

Does that mean we now need a language feature to tell the documentation generator not to emit attribute names for parameters of type Flag!"" ?

No, just version(ddoc) for select functions if you want them to. You have the needed means within the language. Andrei
Jun 10 2011
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Andrei:

 I don't want a universal thing, I want to solve a simple problem: there 
 are 7 yes/no enums in Phobos, and probably some more to come. Flag 
 solves that problem in a reasonable way. This is pretty much it.

I didn't understand this well at first. Thank you for explaining again. Bye, bearophile
Jun 10 2011
prev sibling next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message 
news:isu15s$30as$1 digitalmars.com...
 On 6/10/11 3:34 PM, Michel Fortin wrote:
 If you want something to be used everywhere and it is not an
 implementation detail, make it part of the language. Implementing what
 sounds should be a language feature through a template hack and putting
 it the standard library is not going to make people feel good about the
 language, it'll remind them of what the language is missing.

The problem with the "hack" label is that it instantly decreases the level of the conversation. It's the "N" word of programming. I don't want a universal thing, I want to solve a simple problem: there are 7 yes/no enums in Phobos, and probably some more to come. Flag solves that problem in a reasonable way. This is pretty much it.
 And just try to think of the signature for the function above if it was
 using Flag!

 void foo(Flag!"param" param, Flag!"otherParam" otherParam,
 Flag!"thisOneIsntRequired" thisOneIsntRequired =
 Flag!"thisOneIsntRequired".no);

 Do we really want to expose that in the documentation?

Yes, that's the whole point, though I agree the hiccup in the default initializer is annoying.

I find it funny that you see a hiccup only in the default initializer when the name of all parameter is also duplicated in its type. Shouldn't that be 4 hiccups?

I don't think so, but I understand how you can frame that as an argument that supports your viewpoint.
 The documentation doesn't need the names anymore; the user would just
 say:

 void foo(
 Flag!"compressed",
 Flag!"encrypted",
 Flag!"buffered" = Flag!"buffered".no);

 Save for the "ehm" default parameter this looks palatable to me.

Does that mean we now need a language feature to tell the documentation generator not to emit attribute names for parameters of type Flag!"" ?

No, just version(ddoc) for select functions if you want them to. You have the needed means within the language. Andrei

Jun 10 2011
parent "Nick Sabalausky" <a a.a> writes:
Ignore this: I went to reply, hit the wrong key, and it sent before I got to 
type anything... The *real* reply in another post...

"Nick Sabalausky" <a a.a> wrote in message 
news:isu4gg$5ff$1 digitalmars.com...
 "Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message 
 news:isu15s$30as$1 digitalmars.com...
 On 6/10/11 3:34 PM, Michel Fortin wrote:
 If you want something to be used everywhere and it is not an
 implementation detail, make it part of the language. Implementing what
 sounds should be a language feature through a template hack and putting
 it the standard library is not going to make people feel good about the
 language, it'll remind them of what the language is missing.

The problem with the "hack" label is that it instantly decreases the level of the conversation. It's the "N" word of programming. I don't want a universal thing, I want to solve a simple problem: there are 7 yes/no enums in Phobos, and probably some more to come. Flag solves that problem in a reasonable way. This is pretty much it.
 And just try to think of the signature for the function above if it 
 was
 using Flag!

 void foo(Flag!"param" param, Flag!"otherParam" otherParam,
 Flag!"thisOneIsntRequired" thisOneIsntRequired =
 Flag!"thisOneIsntRequired".no);

 Do we really want to expose that in the documentation?

Yes, that's the whole point, though I agree the hiccup in the default initializer is annoying.

I find it funny that you see a hiccup only in the default initializer when the name of all parameter is also duplicated in its type. Shouldn't that be 4 hiccups?

I don't think so, but I understand how you can frame that as an argument that supports your viewpoint.
 The documentation doesn't need the names anymore; the user would just
 say:

 void foo(
 Flag!"compressed",
 Flag!"encrypted",
 Flag!"buffered" = Flag!"buffered".no);

 Save for the "ehm" default parameter this looks palatable to me.

Does that mean we now need a language feature to tell the documentation generator not to emit attribute names for parameters of type Flag!"" ?

No, just version(ddoc) for select functions if you want them to. You have the needed means within the language. Andrei


Jun 10 2011
prev sibling next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message 
news:isu15s$30as$1 digitalmars.com...
 On 6/10/11 3:34 PM, Michel Fortin wrote:
 If you want something to be used everywhere and it is not an
 implementation detail, make it part of the language. Implementing what
 sounds should be a language feature through a template hack and putting
 it the standard library is not going to make people feel good about the
 language, it'll remind them of what the language is missing.

The problem with the "hack" label is that it instantly decreases the level of the conversation. It's the "N" word of programming.

You're assuming that we're choosing the word "hack" as an attempt to sway. Not so. We're calling it a hack because we genuinely see it as such. However, I can see how the accusation that our usage of "hack" was an attempt to sway with wordplay (or any other such resorting to meta-arguments) can be used to frame an argument that supports your viewpoint.
 I don't want a universal thing, I want to solve a simple problem: there 
 are 7 yes/no enums in Phobos, and probably some more to come. Flag solves 
 that problem in a reasonable way. This is pretty much it.

Others *do* want a more universal thing.
 And just try to think of the signature for the function above if it was
 using Flag!

 void foo(Flag!"param" param, Flag!"otherParam" otherParam,
 Flag!"thisOneIsntRequired" thisOneIsntRequired =
 Flag!"thisOneIsntRequired".no);

 Do we really want to expose that in the documentation?

Yes, that's the whole point, though I agree the hiccup in the default initializer is annoying.

I find it funny that you see a hiccup only in the default initializer when the name of all parameter is also duplicated in its type. Shouldn't that be 4 hiccups?

I don't think so, but I understand how you can frame that as an argument that supports your viewpoint.

Now who's digging their heels in and just being stubborn? You *really* don't see the problem with "Flag!"param" param"?
 The documentation doesn't need the names anymore; the user would just
 say:

 void foo(
 Flag!"compressed",
 Flag!"encrypted",
 Flag!"buffered" = Flag!"buffered".no);

 Save for the "ehm" default parameter this looks palatable to me.

Does that mean we now need a language feature to tell the documentation generator not to emit attribute names for parameters of type Flag!"" ?

No, just version(ddoc) for select functions if you want them to. You have the needed means within the language.

And with named arguments, you don't even need to bother with that. So, more verbosity (and likely an indentation increase) to support (minimally) "less" verbosity.
Jun 10 2011
parent "Nick Sabalausky" <a a.a> writes:
"Nick Sabalausky" <a a.a> wrote in message 
news:isu5aa$6t0$1 digitalmars.com...
 Now who's digging their heels in and just being stubborn? You *really* 
 don't see the problem with "Flag!"param" param"?

Erm, I mean "the hiccup with it".
Jun 10 2011
prev sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2011-06-10 17:04:42 -0400, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 On 6/10/11 3:34 PM, Michel Fortin wrote:
 If you want something to be used everywhere and it is not an
 implementation detail, make it part of the language. Implementing what
 sounds should be a language feature through a template hack and putting
 it the standard library is not going to make people feel good about the
 language, it'll remind them of what the language is missing.

The problem with the "hack" label is that it instantly decreases the level of the conversation. It's the "N" word of programming.

A hack is something that works even though it's ugly and generally cause people to call for something better. I'm not opposed to using hacks as long as they're well-encapsulated and not too fragile, but in this case I find the encapsulation is leaky since you need to litter your code with Flag!"" everywhere.
 I don't want a universal thing, I want to solve a simple problem: there 
 are 7 yes/no enums in Phobos, and probably some more to come. Flag 
 solves that problem in a reasonable way. This is pretty much it.

I disagree that Flag is a reasonable solution. It works, but it's ugly and verbose. I understand it's tiresome to create an enum for every parameter, but asking all users to write Flag!"" everywhere is going to be tiresome everywhere else, which is hardly an improvement. I also think you are narrowing the problem a little too much. The problem exists everywhere there is a boolean parameter. This includes phobos, druntime, and potentially any other D library. Should Flag!"" become the recommended way to make boolean parameters in D? And should creating a separate Ddoc version of the function signature become the recommended way to document boolean parameters? If so, I think it'll reflect badly on the language. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jun 10 2011
next sibling parent "Nick Sabalausky" <a a.a> writes:
"Michel Fortin" <michel.fortin michelf.com> wrote in message 
news:isu5tk$816$1 digitalmars.com...
 I understand it's tiresome to create an enum for every parameter, but 
 asking all users to write Flag!"" everywhere is going to be tiresome 
 everywhere else, which is hardly an improvement.

Excellent point.
 I also think you are narrowing the problem a little too much. The problem 
 exists everywhere there is a boolean parameter.

And not just bools, either. Graphics libraries typically have the same problem in spades, much more than Phobos. But with numbers, not bools. Even a Flag expanded to allow *any* enum is still insufficient for that. It seems like your design strategy here is (unintentionally, of course) focusing primarily on Phobos's own needs rather than really looking out much beyond Phobos.
 This includes phobos, druntime, and potentially any other D library. 
 Should Flag!"" become the recommended way to make boolean parameters in D? 
 And should creating a separate Ddoc version of the function signature 
 become the recommended way to document boolean parameters? If so, I think 
 it'll reflect badly on the language.

Jun 10 2011
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/10/11 5:25 PM, Michel Fortin wrote:
 On 2011-06-10 17:04:42 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> said:

 On 6/10/11 3:34 PM, Michel Fortin wrote:
 If you want something to be used everywhere and it is not an
 implementation detail, make it part of the language. Implementing what
 sounds should be a language feature through a template hack and putting
 it the standard library is not going to make people feel good about the
 language, it'll remind them of what the language is missing.

The problem with the "hack" label is that it instantly decreases the level of the conversation. It's the "N" word of programming.

A hack is something that works even though it's ugly and generally cause people to call for something better. I'm not opposed to using hacks as long as they're well-encapsulated and not too fragile, but in this case I find the encapsulation is leaky since you need to litter your code with Flag!"" everywhere.

https://github.com/andralex/phobos/commit/84c75336a4ef04b4c3b1924d7ac9329e744ab8e7 Andrei
Jun 10 2011
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2011-06-10 18:57:20 -0400, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 On 6/10/11 5:25 PM, Michel Fortin wrote:
 A hack is something that works even though it's ugly and generally cause
 people to call for something better. I'm not opposed to using hacks as
 long as they're well-encapsulated and not too fragile, but in this case
 I find the encapsulation is leaky since you need to litter your code
 with Flag!"" everywhere.

https://github.com/andralex/phobos/commit/84c75336a4ef04b4c3b1924d7ac9329e744ab8e7

It's
 

if you use yes!"abc" at the function call point. However, I still think it's a deterioration from the user's point of view compared to the current situation with hand-crafted enums: it still requires a string, and the documentation will say func(Flag!"abc" abc), repeating the parameter's name unless you hand-craft a special Ddoc version of the function declaration. It's better than Flag!"abc".yes, but it's worse than Abc.yes. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jun 10 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/10/11 8:08 PM, Michel Fortin wrote:
 On 2011-06-10 18:57:20 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> said:

 On 6/10/11 5:25 PM, Michel Fortin wrote:
 A hack is something that works even though it's ugly and generally cause
 people to call for something better. I'm not opposed to using hacks as
 long as they're well-encapsulated and not too fragile, but in this case
 I find the encapsulation is leaky since you need to litter your code
 with Flag!"" everywhere.

https://github.com/andralex/phobos/commit/84c75336a4ef04b4c3b1924d7ac9329e744ab8e7

It's

if you use yes!"abc" at the function call point. However, I still think it's a deterioration from the user's point of view compared to the current situation with hand-crafted enums: it still requires a string, and the documentation will say func(Flag!"abc" abc), repeating the parameter's name unless you hand-craft a special Ddoc version of the function declaration. It's better than Flag!"abc".yes, but it's worse than Abc.yes.

But the problem is the same today. enum Abc : bool { no, yes } void fun(Abc abc = Abc.no); No difference. In the function declaration, the word "abc" occurs three times. Andrei
Jun 10 2011
next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message 
news:isuivh$1a6v$1 digitalmars.com...
 On 6/10/11 8:08 PM, Michel Fortin wrote:
 On 2011-06-10 18:57:20 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> said:

 On 6/10/11 5:25 PM, Michel Fortin wrote:
 A hack is something that works even though it's ugly and generally 
 cause
 people to call for something better. I'm not opposed to using hacks as
 long as they're well-encapsulated and not too fragile, but in this case
 I find the encapsulation is leaky since you need to litter your code
 with Flag!"" everywhere.

https://github.com/andralex/phobos/commit/84c75336a4ef04b4c3b1924d7ac9329e744ab8e7

It's

if you use yes!"abc" at the function call point. However, I still think it's a deterioration from the user's point of view compared to the current situation with hand-crafted enums: it still requires a string, and the documentation will say func(Flag!"abc" abc), repeating the parameter's name unless you hand-craft a special Ddoc version of the function declaration. It's better than Flag!"abc".yes, but it's worse than Abc.yes.

But the problem is the same today. enum Abc : bool { no, yes } void fun(Abc abc = Abc.no); No difference. In the function declaration, the word "abc" occurs three times.

Which makes Flag even less of an improvement.
Jun 10 2011
next sibling parent reply Alix Pexton <alix.DOT.pexton gmail.DOT.com> writes:
On 11/06/2011 06:18, Andrej Mitrovic wrote:
 We should rename Yes and No to Yay and Nay to make them alignable, and
 even more importantly to make us appear as old Englishmen!

"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not actually a old English word :) A more correct alternative would be "Aye" (pronounced the same as "eye"), which (along with "Nay") is still used for some voting actions (such as councillors deciding where to go for lunch). I myself say it al least 20 times a day :) A...
Jun 11 2011
next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Alix Pexton" <alix.DOT.pexton gmail.DOT.com> wrote in message 
news:isvae3$2o51$1 digitalmars.com...
 On 11/06/2011 06:18, Andrej Mitrovic wrote:
 We should rename Yes and No to Yay and Nay to make them alignable, and
 even more importantly to make us appear as old Englishmen!

"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not actually a old English word :) A more correct alternative would be "Aye" (pronounced the same as "eye"), which (along with "Nay") is still used for some voting actions (such as councillors deciding where to go for lunch). I myself say it al least 20 times a day :)

Dost thou, verily?
Jun 11 2011
parent Alix Pexton <alix.DOT.pexton gmail.DOT.com> writes:
On 11/06/2011 11:56, Nick Sabalausky wrote:
 "Alix Pexton"<alix.DOT.pexton gmail.DOT.com>  wrote in message
 news:isvae3$2o51$1 digitalmars.com...
 On 11/06/2011 06:18, Andrej Mitrovic wrote:
 We should rename Yes and No to Yay and Nay to make them alignable, and
 even more importantly to make us appear as old Englishmen!

"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not actually a old English word :) A more correct alternative would be "Aye" (pronounced the same as "eye"), which (along with "Nay") is still used for some voting actions (such as councillors deciding where to go for lunch). I myself say it al least 20 times a day :)

Dost thou, verily?

Aye! A...
Jun 11 2011
prev sibling parent reply Alix Pexton <alix.DOT.pexton gmail.DOT.com> writes:
On 12/06/2011 02:40, Steven Schveighoffer wrote:
 On Sat, 11 Jun 2011 13:04:47 -0400, Andrej Mitrovic
 <andrej.mitrovich gmail.com> wrote:

 On 6/11/11, Alix Pexton <alix.DOT.pexton gmail.dot.com> wrote:
 On 11/06/2011 06:18, Andrej Mitrovic wrote:
 We should rename Yes and No to Yay and Nay to make them alignable, and
 even more importantly to make us appear as old Englishmen!

"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not actually a old English word :) A more correct alternative would be "Aye" (pronounced the same as "eye"), which (along with "Nay") is still used for some voting actions (such as councillors deciding where to go for lunch). I myself say it al least 20 times a day :) A...

Oh damn, yay is what teenage girls would say, not old Englishmen. My bad, it really is "Aye". :p

You were phonetically right :) It's yea or nay. http://dictionary.cambridge.org/dictionary/british/yea-or-nay My son's most recent birthday (3 years old) was a farm-themed birthday, and we asked people to RSVP yay or neigh :P So I guess there's all kinds of kooky fun you can have with flags... -Steve

Nope, its definitely Aye when used for voting, (at least it is round here) as in "all those in favour, say aye", "ayes to the right" and "the ayes have it". Maybe southerners say this "yea" word of which you speak, we don't hold with their strange customs in these parts ^^ A...
Jun 12 2011
parent reply Alix Pexton <alix.DOT.pexton gmail.DOT.com> writes:
On 12/06/2011 16:11, Steven Schveighoffer wrote:
 On Sun, 12 Jun 2011 04:36:55 -0400, Alix Pexton
 <alix.DOT.pexton gmail.dot.com> wrote:

 On 12/06/2011 02:40, Steven Schveighoffer wrote:
 On Sat, 11 Jun 2011 13:04:47 -0400, Andrej Mitrovic
 <andrej.mitrovich gmail.com> wrote:

 On 6/11/11, Alix Pexton <alix.DOT.pexton gmail.dot.com> wrote:
 On 11/06/2011 06:18, Andrej Mitrovic wrote:
 We should rename Yes and No to Yay and Nay to make them alignable,
 and
 even more importantly to make us appear as old Englishmen!

"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not actually a old English word :) A more correct alternative would be "Aye" (pronounced the same as "eye"), which (along with "Nay") is still used for some voting actions (such as councillors deciding where to go for lunch). I myself say it al least 20 times a day :) A...

Oh damn, yay is what teenage girls would say, not old Englishmen. My bad, it really is "Aye". :p

You were phonetically right :) It's yea or nay. http://dictionary.cambridge.org/dictionary/british/yea-or-nay My son's most recent birthday (3 years old) was a farm-themed birthday, and we asked people to RSVP yay or neigh :P So I guess there's all kinds of kooky fun you can have with flags... -Steve

Nope, its definitely Aye when used for voting, (at least it is round here) as in "all those in favour, say aye", "ayes to the right" and "the ayes have it". Maybe southerners say this "yea" word of which you speak, we don't hold with their strange customs in these parts ^^

I don't deny that aye is used frequently for voting. All I was saying is, the correct expression is yea or nay, not yay or nay. Andrej thought it was actually aye or nay, which I've never heard as an expression. I'm not sure it's used anymore, but it's definitely an expression that was used for voting (see my dictionary reference). -Steve

True, "yea-or-nay" is quite a common, if old fashioned phrase, but "yea" on its own is exceptionally rare (to the point where I doubt ever hearing anyone make such a noise and mean it to indicate the affirmative). A...
Jun 12 2011
parent reply Paul D. Anderson <paul.d.removethis.anderson comcast.andthis.net> writes:
Alix Pexton Wrote:

 On 12/06/2011 16:11, Steven Schveighoffer wrote:
 On Sun, 12 Jun 2011 04:36:55 -0400, Alix Pexton
 <alix.DOT.pexton gmail.dot.com> wrote:

 On 12/06/2011 02:40, Steven Schveighoffer wrote:
 On Sat, 11 Jun 2011 13:04:47 -0400, Andrej Mitrovic
 <andrej.mitrovich gmail.com> wrote:

 On 6/11/11, Alix Pexton <alix.DOT.pexton gmail.dot.com> wrote:
 On 11/06/2011 06:18, Andrej Mitrovic wrote:
 We should rename Yes and No to Yay and Nay to make them alignable,
 and
 even more importantly to make us appear as old Englishmen!

"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not actually a old English word :) A more correct alternative would be "Aye" (pronounced the same as "eye"), which (along with "Nay") is still used for some voting actions (such as councillors deciding where to go for lunch). I myself say it al least 20 times a day :) A...

Oh damn, yay is what teenage girls would say, not old Englishmen. My bad, it really is "Aye". :p

You were phonetically right :) It's yea or nay. http://dictionary.cambridge.org/dictionary/british/yea-or-nay My son's most recent birthday (3 years old) was a farm-themed birthday, and we asked people to RSVP yay or neigh :P So I guess there's all kinds of kooky fun you can have with flags... -Steve

Nope, its definitely Aye when used for voting, (at least it is round here) as in "all those in favour, say aye", "ayes to the right" and "the ayes have it". Maybe southerners say this "yea" word of which you speak, we don't hold with their strange customs in these parts ^^

I don't deny that aye is used frequently for voting. All I was saying is, the correct expression is yea or nay, not yay or nay. Andrej thought it was actually aye or nay, which I've never heard as an expression. I'm not sure it's used anymore, but it's definitely an expression that was used for voting (see my dictionary reference). -Steve

True, "yea-or-nay" is quite a common, if old fashioned phrase, but "yea" on its own is exceptionally rare (to the point where I doubt ever hearing anyone make such a noise and mean it to indicate the affirmative). A...

Then you must not have heard the King James Version of the Bible read aloud, or been to a Shakespeare play. Admittedly the KJV and Shakespeare's works don't count as modern English, but I doubt you've never "heard such a noise"! :-) p.s. The word appears 209 times in Shakespeare's plays. There's a website for everything!
Jun 12 2011
parent Alix Pexton <alix.DOT.pexton gmail.DOT.com> writes:
On 13/06/2011 02:31, Paul D. Anderson wrote:
 Alix Pexton Wrote:

 On 12/06/2011 16:11, Steven Schveighoffer wrote:
 On Sun, 12 Jun 2011 04:36:55 -0400, Alix Pexton
 <alix.DOT.pexton gmail.dot.com>  wrote:

 On 12/06/2011 02:40, Steven Schveighoffer wrote:
 On Sat, 11 Jun 2011 13:04:47 -0400, Andrej Mitrovic
 <andrej.mitrovich gmail.com>  wrote:

 On 6/11/11, Alix Pexton<alix.DOT.pexton gmail.dot.com>  wrote:
 On 11/06/2011 06:18, Andrej Mitrovic wrote:
 We should rename Yes and No to Yay and Nay to make them alignable,
 and
 even more importantly to make us appear as old Englishmen!

"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not actually a old English word :) A more correct alternative would be "Aye" (pronounced the same as "eye"), which (along with "Nay") is still used for some voting actions (such as councillors deciding where to go for lunch). I myself say it al least 20 times a day :) A...

Oh damn, yay is what teenage girls would say, not old Englishmen. My bad, it really is "Aye". :p

You were phonetically right :) It's yea or nay. http://dictionary.cambridge.org/dictionary/british/yea-or-nay My son's most recent birthday (3 years old) was a farm-themed birthday, and we asked people to RSVP yay or neigh :P So I guess there's all kinds of kooky fun you can have with flags... -Steve

Nope, its definitely Aye when used for voting, (at least it is round here) as in "all those in favour, say aye", "ayes to the right" and "the ayes have it". Maybe southerners say this "yea" word of which you speak, we don't hold with their strange customs in these parts ^^

I don't deny that aye is used frequently for voting. All I was saying is, the correct expression is yea or nay, not yay or nay. Andrej thought it was actually aye or nay, which I've never heard as an expression. I'm not sure it's used anymore, but it's definitely an expression that was used for voting (see my dictionary reference). -Steve

True, "yea-or-nay" is quite a common, if old fashioned phrase, but "yea" on its own is exceptionally rare (to the point where I doubt ever hearing anyone make such a noise and mean it to indicate the affirmative). A...

Then you must not have heard the King James Version of the Bible read aloud, or been to a Shakespeare play. Admittedly the KJV and Shakespeare's works don't count as modern English, but I doubt you've never "heard such a noise"! :-) p.s. The word appears 209 times in Shakespeare's plays. There's a website for everything!

Aye, I did mean people using their own words and not someone else's. for such a prolific writer, 209 doesn't seem like a lot, and I can't help wondering how many times the bard used "aye". Mind you, he was a southerner! A...
Jun 13 2011
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/10/11 11:55 PM, Nick Sabalausky wrote:
 However, I still think it's a deterioration from the user's point of
 view compared to the current situation with hand-crafted enums: it still
 requires a string, and the documentation will say func(Flag!"abc" abc),
 repeating the parameter's name unless you hand-craft a special Ddoc
 version of the function declaration. It's better than Flag!"abc".yes,
 but it's worse than Abc.yes.

But the problem is the same today. enum Abc : bool { no, yes } void fun(Abc abc = Abc.no); No difference. In the function declaration, the word "abc" occurs three times.

Which makes Flag even less of an improvement.

I'm not sure I figure the reasoning. You can't penalize twice for the same reason. This makes the existing situation less desirable, not Flag less of an improvement over it. Andrei
Jun 11 2011
prev sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2011-06-10 22:08:31 -0400, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 On 6/10/11 8:08 PM, Michel Fortin wrote:
 On 2011-06-10 18:57:20 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> said:
 
 https://github.com/andralex/phobos/commit/84c75336a4ef04b4c3b1924d7ac9329e744ab8e7



It's still
 

if you use yes!"abc" at the function call point. However, I still think it's a deterioration from the user's point of view compared to the current situation with hand-crafted enums: it still requires a string, and the documentation will say func(Flag!"abc" abc), repeating the parameter's name unless you hand-craft a special Ddoc version of the function declaration. It's better than Flag!"abc".yes, but it's worse than Abc.yes.

But the problem is the same today. enum Abc : bool { no, yes } void fun(Abc abc = Abc.no); No difference. In the function declaration, the word "abc" occurs three times.

I actually didn't meant to post the above. I wrote it, then thought I should sleep on it before deciding whether I'd post it or not since I was a little to tired. Then I hit a bad key combo and the message reached the server before I could unplug my network cable. I'm not surprised you could find some inconsistencies in it. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jun 11 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"Michel Fortin" <michel.fortin michelf.com> wrote in message 
news:isvhkr$3s4$1 digitalmars.com...
 I actually didn't meant to post the above. I wrote it, then thought I 
 should sleep on it before deciding whether I'd post it or not since I was 
 a little to tired. Then I hit a bad key combo and the message reached the 
 server before I could unplug my network cable. I'm not surprised you could 
 find some inconsistencies in it.

That dang "Send Message" keyboard combo gets me now and then, too. In fact, last time was just yesterday. I'm all for keyboard accessability for everything, but I'd love to see the keyboard access for "Send Message" be a bit less easy. On my mail client, it's Ctrl-Enter, which of course is just begging for it to be accidentally hit while editing text.
Jun 11 2011
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2011-06-11 07:01:13 -0400, "Nick Sabalausky" <a a.a> said:

 "Michel Fortin" <michel.fortin michelf.com> wrote in message
 news:isvhkr$3s4$1 digitalmars.com...
 
 I actually didn't meant to post the above. I wrote it, then thought I
 should sleep on it before deciding whether I'd post it or not since I was
 a little to tired. Then I hit a bad key combo and the message reached the
 server before I could unplug my network cable. I'm not surprised you could
 find some inconsistencies in it.

That dang "Send Message" keyboard combo gets me now and then, too. In fact, last time was just yesterday. I'm all for keyboard accessability for everything, but I'd love to see the keyboard access for "Send Message" be a bit less easy. On my mail client, it's Ctrl-Enter, which of course is just begging for it to be accidentally hit while editing text.

Just after sending this message, I changed the combo in my newsreader from command-option-D to command-option-control-shift-D, like I did for my mail client a while ago. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jun 11 2011
parent reply Daniel Gibson <metalcaedes gmail.com> writes:
Am 11.06.2011 13:09, schrieb Michel Fortin:
 On 2011-06-11 07:01:13 -0400, "Nick Sabalausky" <a a.a> said:
 
 "Michel Fortin" <michel.fortin michelf.com> wrote in message
 news:isvhkr$3s4$1 digitalmars.com...
 I actually didn't meant to post the above. I wrote it, then thought I
 should sleep on it before deciding whether I'd post it or not since I
 was
 a little to tired. Then I hit a bad key combo and the message reached
 the
 server before I could unplug my network cable. I'm not surprised you
 could
 find some inconsistencies in it.

That dang "Send Message" keyboard combo gets me now and then, too. In fact, last time was just yesterday. I'm all for keyboard accessability for everything, but I'd love to see the keyboard access for "Send Message" be a bit less easy. On my mail client, it's Ctrl-Enter, which of course is just begging for it to be accidentally hit while editing text.

Just after sending this message, I changed the combo in my newsreader from command-option-D to command-option-control-shift-D, like I did for my mail client a while ago.

When using a newsreader you should be able to retract a message, at least in Thunderbird you can just delete your own message to remove it from the server.
Jun 11 2011
parent Michel Fortin <michel.fortin michelf.com> writes:
On 2011-06-11 07:11:19 -0400, Daniel Gibson <metalcaedes gmail.com> said:

 When using a newsreader you should be able to retract a message, at
 least in Thunderbird you can just delete your own message to remove it
 from the server.

I know, but Unison doesn't have that option. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jun 11 2011
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/10/11 1:52 PM, Robert Clipsham wrote:
 On 10/06/2011 19:06, Andrei Alexandrescu wrote:
 On 6/10/11 12:42 PM, Robert Clipsham wrote:
 On 10/06/2011 17:15, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/phobos/pull/94

 Discuss!

 Andrei

I really *really* don't like this. It's ugly and verbose, and a pathetic work around for the lack of named parameters. Either support named parameters or not, don't have an ugly half-baked work-around.

This is not half-baked. It's pretty much it.

My choice of wording was poor, sorry.
 Ugly is in the eye of the beholder, but I fail to see how the added
 punctuation makes Flag!"param".yes significantly more verbose than param
 : true.

foo(param: true, otherParam: false); foo(Flag!"param".yes, Flag!"otherParam".no); I don't know about you, but I find the former is far more legible. I'd hate to see my code littered with Flag!"something".

I agree it's more legible. The crucial question is whether the added legibility warrants adding a new feature to the language.
 The problem that named parameters are still optional remains. Or we need
 to add one extra language feature to specify required named parameters.

void foo(bool param, bool otherParam, bool thisOneIsntRequired = false); Call it with or without named parameters, two are required, one is not. foo(otherParam: true, param: false); foo(true, false); foo(otherParam: true, param: false, thisOneIsntRequired: true); Would all be valid.

The second call is problematic because it still allows bad style in calls. Andrei
Jun 10 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message 
news:isttf6$2oub$1 digitalmars.com...
 On 6/10/11 1:52 PM, Robert Clipsham wrote:
 On 10/06/2011 19:06, Andrei Alexandrescu wrote:
 On 6/10/11 12:42 PM, Robert Clipsham wrote:
 On 10/06/2011 17:15, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/phobos/pull/94

 Discuss!

 Andrei

I really *really* don't like this. It's ugly and verbose, and a pathetic work around for the lack of named parameters. Either support named parameters or not, don't have an ugly half-baked work-around.

This is not half-baked. It's pretty much it.

My choice of wording was poor, sorry.
 Ugly is in the eye of the beholder, but I fail to see how the added
 punctuation makes Flag!"param".yes significantly more verbose than param
 : true.

foo(param: true, otherParam: false); foo(Flag!"param".yes, Flag!"otherParam".no); I don't know about you, but I find the former is far more legible. I'd hate to see my code littered with Flag!"something".

I agree it's more legible. The crucial question is whether the added legibility warrants adding a new feature to the language.

I really see Flag more as a way to try to rationalize avoiding adding named parameters to the language. And yes, the legibility of "foo(Flag!"param".yes, Flag!"otherParam".no);", combined with the frequency of need for such a thing, and the complete inability of Flag to address the problem for anything but bool, the inability to document it separately (as Jonathan Davis pointed out), is all definitely much much more than enough to warrant adding a tried-and-proven feature that's become standard in damn near every other modern language.
Jun 10 2011
next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Nick Sabalausky" <a a.a> wrote in message 
news:istv62$2skn$1 digitalmars.com...
 "Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message 
 news:isttf6$2oub$1 digitalmars.com...
 On 6/10/11 1:52 PM, Robert Clipsham wrote:
 foo(param: true, otherParam: false);
 foo(Flag!"param".yes, Flag!"otherParam".no);

 I don't know about you, but I find the former is far more legible. I'd
 hate to see my code littered with Flag!"something".

I agree it's more legible. The crucial question is whether the added legibility warrants adding a new feature to the language.

I really see Flag more as a way to try to rationalize avoiding adding named parameters to the language. And yes, the legibility of "foo(Flag!"param".yes, Flag!"otherParam".no);", combined with the frequency of need for such a thing, and the complete inability of Flag to address the problem for anything but bool, the inability to document it separately (as Jonathan Davis pointed out), is all definitely much much more than enough to warrant adding a tried-and-proven feature that's become standard in damn near every other modern language.

Regarding "the complete inability of Flag to address the problem for anything but bool", how are we going to wind up papering over that? Like: box(Int!"x"(3), Int!"y"(4), Int!"width"(100), Int!"height"(150), Int!"depth"(1), UInt!"color"(0xFFAA77)); ?
Jun 10 2011
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/10/11 3:36 PM, Nick Sabalausky wrote:
 "Nick Sabalausky"<a a.a>  wrote in message
 news:istv62$2skn$1 digitalmars.com...
 "Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org>  wrote in message
 news:isttf6$2oub$1 digitalmars.com...
 On 6/10/11 1:52 PM, Robert Clipsham wrote:
 foo(param: true, otherParam: false);
 foo(Flag!"param".yes, Flag!"otherParam".no);

 I don't know about you, but I find the former is far more legible. I'd
 hate to see my code littered with Flag!"something".

I agree it's more legible. The crucial question is whether the added legibility warrants adding a new feature to the language.

I really see Flag more as a way to try to rationalize avoiding adding named parameters to the language. And yes, the legibility of "foo(Flag!"param".yes, Flag!"otherParam".no);", combined with the frequency of need for such a thing, and the complete inability of Flag to address the problem for anything but bool, the inability to document it separately (as Jonathan Davis pointed out), is all definitely much much more than enough to warrant adding a tried-and-proven feature that's become standard in damn near every other modern language.

Regarding "the complete inability of Flag to address the problem for anything but bool", how are we going to wind up papering over that? Like: box(Int!"x"(3), Int!"y"(4), Int!"width"(100), Int!"height"(150), Int!"depth"(1), UInt!"color"(0xFFAA77)); ?

I don't find it entirely fair to demean the suggestion as a tool to sustain your viewpoint. Flag supporting only yes and no is not a "complete inability" - it is its charter. The plan is not to have Flag be a replacement for named arguments, but instead to have it support good practices for Boolean settings and replace a number of awkward enum definitions in Phobos. As I mentioned, in the future it's possible to have Flag (or a related abstraction) support categorical features beyond yes and no, but it is not meant, and does not attempt, to cover named arguments. Andrei
Jun 10 2011
prev sibling parent reply Lutger Blijdestijn <lutger.blijdestijn gmail.com> writes:
Nick Sabalausky wrote:

 "Nick Sabalausky" <a a.a> wrote in message
 news:istv62$2skn$1 digitalmars.com...
 "Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message
 news:isttf6$2oub$1 digitalmars.com...
 On 6/10/11 1:52 PM, Robert Clipsham wrote:
 foo(param: true, otherParam: false);
 foo(Flag!"param".yes, Flag!"otherParam".no);

 I don't know about you, but I find the former is far more legible. I'd
 hate to see my code littered with Flag!"something".

I agree it's more legible. The crucial question is whether the added legibility warrants adding a new feature to the language.

I really see Flag more as a way to try to rationalize avoiding adding named parameters to the language.


I don't, even though I like named parameters. boolean parameters for binary options are kind of an exception imho, because they decrease readability at the call site much more often than other types do. Somebody one this newsgroup - maybe it was Don Clugston, also made a good point against named parameters: it introduces inflexibility because now the names of the parameters of a function become part of the public api. Changing a name will now break client code. I'd still probably welcome named parameters though.
 And yes, the legibility of "foo(Flag!"param".yes,
 Flag!"otherParam".no);", combined with the frequency of need for such a
 thing, and the complete inability of Flag to address the problem for
 anything but bool, the inability to document it separately (as Jonathan
 Davis pointed out), is all definitely much much more than enough to
 warrant adding a tried-and-proven feature that's become standard in damn
 near every other modern language.

Regarding "the complete inability of Flag to address the problem for anything but bool", how are we going to wind up papering over that? Like: box(Int!"x"(3), Int!"y"(4), Int!"width"(100), Int!"height"(150), Int!"depth"(1), UInt!"color"(0xFFAA77)); ?

Jun 10 2011
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/10/11 4:28 PM, Andrej Mitrovic wrote:
 On 6/10/11, Lutger Blijdestijn<lutger.blijdestijn gmail.com>  wrote:
 Changing a name will now break client code.

The flag template suffers from the same issue.

Actually, not. The name used with Flag is part of its type. Even in a separate compilation approach, the type names must match, which is not the case for parameter names. Andrei
Jun 10 2011
prev sibling next sibling parent reply Lutger Blijdestijn <lutger.blijdestijn gmail.com> writes:
Andrej Mitrovic wrote:

 On 6/10/11, Lutger Blijdestijn <lutger.blijdestijn gmail.com> wrote:
 Changing a name will now break client code.

The flag template suffers from the same issue.

Not strictly, but practically yes. It's also the point of them, exposing this name in the api. But its *only* for those parameters, which I understand are right now just 7 functions in the whole of phobos. With named parameters, the issue affects every function, including those already written without this dependency issue in mind.
Jun 10 2011
next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Lutger Blijdestijn" <lutger.blijdestijn gmail.com> wrote in message 
news:isu365$2ao$1 digitalmars.com...
 Andrej Mitrovic wrote:

 On 6/10/11, Lutger Blijdestijn <lutger.blijdestijn gmail.com> wrote:
 Changing a name will now break client code.

The flag template suffers from the same issue.

Not strictly, but practically yes. It's also the point of them, exposing this name in the api. But its *only* for those parameters, which I understand are right now just 7 functions in the whole of phobos. With named parameters, the issue affects every function, including those already written without this dependency issue in mind.

That's hardly an issue though. Updating callers to use a changed function name is trivial. I see no reason why this would be any less trivial.
Jun 10 2011
parent KennyTM~ <kennytm gmail.com> writes:
On Jun 11, 11 05:59, Jonathan M Davis wrote:
 On 2011-06-10 14:44, Nick Sabalausky wrote:
 "Lutger Blijdestijn"<lutger.blijdestijn gmail.com>  wrote in message
 news:isu365$2ao$1 digitalmars.com...

 Andrej Mitrovic wrote:
 On 6/10/11, Lutger Blijdestijn<lutger.blijdestijn gmail.com>  wrote:
 Changing a name will now break client code.

The flag template suffers from the same issue.

Not strictly, but practically yes. It's also the point of them, exposing this name in the api. But its *only* for those parameters, which I understand are right now just 7 functions in the whole of phobos. With named parameters, the issue affects every function, including those already written without this dependency issue in mind.

That's hardly an issue though. Updating callers to use a changed function name is trivial. I see no reason why this would be any less trivial.

The problem is that there is no way to provide a deprecation path without renaming functions. When changing the types that a function takes or the number of its parameters, you can overload it. The old version gets scheduled for deprecation, then deprecated, and finally, it's removed. People have time to migrate their code. However, you _can't_ overload on parameter names. So, the only way that you can change a parameter's name without breaking any and all code that used it as a named argument is to create a _new_ function with a _new_ name. So, we'd have to rename entire functions just to be able to rename a single parameter. That's way worse than just having to deal with some parameter type changes or a changes in the number of arguments. Suddenly, you have a whole new function to remember. And currently, you can rename a parameter's name without breaking any code at all. So, named arguments _drastically_ increase the pain of renaming function parameters. - Jonathan M Davis

Why do you need to rename parameter name of a stable API?
Jun 10 2011
prev sibling next sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On 2011-06-10 14:44, Nick Sabalausky wrote:
 "Lutger Blijdestijn" <lutger.blijdestijn gmail.com> wrote in message
 news:isu365$2ao$1 digitalmars.com...
 
 Andrej Mitrovic wrote:
 On 6/10/11, Lutger Blijdestijn <lutger.blijdestijn gmail.com> wrote:
 Changing a name will now break client code.

The flag template suffers from the same issue.

Not strictly, but practically yes. It's also the point of them, exposing this name in the api. But its *only* for those parameters, which I understand are right now just 7 functions in the whole of phobos. With named parameters, the issue affects every function, including those already written without this dependency issue in mind.

That's hardly an issue though. Updating callers to use a changed function name is trivial. I see no reason why this would be any less trivial.

The problem is that there is no way to provide a deprecation path without renaming functions. When changing the types that a function takes or the number of its parameters, you can overload it. The old version gets scheduled for deprecation, then deprecated, and finally, it's removed. People have time to migrate their code. However, you _can't_ overload on parameter names. So, the only way that you can change a parameter's name without breaking any and all code that used it as a named argument is to create a _new_ function with a _new_ name. So, we'd have to rename entire functions just to be able to rename a single parameter. That's way worse than just having to deal with some parameter type changes or a changes in the number of arguments. Suddenly, you have a whole new function to remember. And currently, you can rename a parameter's name without breaking any code at all. So, named arguments _drastically_ increase the pain of renaming function parameters. - Jonathan M Davis
Jun 10 2011
parent "Nick Sabalausky" <a a.a> writes:
"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message 
news:mailman.793.1307743181.14074.digitalmars-d puremagic.com...
 On 2011-06-10 14:44, Nick Sabalausky wrote:
 "Lutger Blijdestijn" <lutger.blijdestijn gmail.com> wrote in message
 news:isu365$2ao$1 digitalmars.com...

 Andrej Mitrovic wrote:
 On 6/10/11, Lutger Blijdestijn <lutger.blijdestijn gmail.com> wrote:
 Changing a name will now break client code.

The flag template suffers from the same issue.

Not strictly, but practically yes. It's also the point of them, exposing this name in the api. But its *only* for those parameters, which I understand are right now just 7 functions in the whole of phobos. With named parameters, the issue affects every function, including those already written without this dependency issue in mind.

That's hardly an issue though. Updating callers to use a changed function name is trivial. I see no reason why this would be any less trivial.

The problem is that there is no way to provide a deprecation path without renaming functions.

What I don't see is a compelling need to provide a deprecation path when the names change. What's so hard about "Recompiling...Oh, 'foo' doesn't work and the new name is 'bar', and it's on this file/line? Ok, done." And even that isn't needed much in a stable API anyway.
Jun 10 2011
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 10 Jun 2011 17:59:30 -0400, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 On 2011-06-10 14:44, Nick Sabalausky wrote:
 "Lutger Blijdestijn" <lutger.blijdestijn gmail.com> wrote in message
 news:isu365$2ao$1 digitalmars.com...

 Andrej Mitrovic wrote:
 On 6/10/11, Lutger Blijdestijn <lutger.blijdestijn gmail.com> wrote:
 Changing a name will now break client code.

The flag template suffers from the same issue.

Not strictly, but practically yes. It's also the point of them,

 this name in the api. But its *only* for those parameters, which I
 understand are right now just 7 functions in the whole of phobos.

 With named parameters, the issue affects every function, including  

 already written without this dependency issue in mind.

That's hardly an issue though. Updating callers to use a changed function name is trivial. I see no reason why this would be any less trivial.

The problem is that there is no way to provide a deprecation path without renaming functions. When changing the types that a function takes or the number of its parameters, you can overload it. The old version gets scheduled for deprecation, then deprecated, and finally, it's removed. People have time to migrate their code. However, you _can't_ overload on parameter names. So, the only way that you can change a parameter's name without breaking any and all code that used it as a named argument is to create a _new_ function with a _new_ name. So, we'd have to rename entire functions just to be able to rename a single parameter. That's way worse than just having to deal with some parameter type changes or a changes in the number of arguments. Suddenly, you have a whole new function to remember. And currently, you can rename a parameter's name without breaking any code at all. So, named arguments _drastically_ increase the pain of renaming function parameters.

This assumes everyone calls every function with named parameters. In reality the number of named parameter calls will be low. There are also possible ways to implement this properly: void foo(bool KeepTerminator) { } void foo(bool OldName); // mark as deprecated? Should be feasible. -Steve
Jun 10 2011
prev sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On 2011-06-10 14:28, Andrej Mitrovic wrote:
 On 6/10/11, Lutger Blijdestijn <lutger.blijdestijn gmail.com> wrote:
 Changing a name will now break client code.

The flag template suffers from the same issue.

Not really. There's a big difference between changing the type name and changing the parameter name. You can freely change the parameter name without changing the type name. Also, you can overload on type names, allowing you to deprecate the old name and replace it with a new one gradually. You _can't_ overload on parameter names, so you _can't_ have a deprecation path with named arguments without renaming the function itself, which is _way_ worse. The difference between the two isn't even comparable. - Jonathan M Davis
Jun 10 2011
parent "Nick Sabalausky" <a a.a> writes:
"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message 
news:mailman.791.1307742081.14074.digitalmars-d puremagic.com...
 On 2011-06-10 14:28, Andrej Mitrovic wrote:
 On 6/10/11, Lutger Blijdestijn <lutger.blijdestijn gmail.com> wrote:
 Changing a name will now break client code.

The flag template suffers from the same issue.

Not really. There's a big difference between changing the type name and changing the parameter name. You can freely change the parameter name without changing the type name. Also, you can overload on type names, allowing you to deprecate the old name and replace it with a new one gradually. You _can't_ overload on parameter names, so you _can't_ have a deprecation path with named arguments without renaming the function itself, which is _way_ worse. The difference between the two isn't even comparable. - Jonathan M Davis

I *really* think that whole issue is a complete triviality, but: 1. Maybe you *could* allow overloading on name, forcing at least that particular param to be named: void foo(int oldName); void foo(int newName); foo(oldName:7); // Ok foo(newName:7); // Ok foo(7); // Error void bar(int num); bar(num:7); // Ok bar(7); // Ok 2. This: void foo(int newName); deprecated void foo(int oldName); foo(oldName:7); // Error: Deprecated foo(newName:7); // Ok foo(7); // Ok
Jun 10 2011
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/10/11 3:30 PM, Nick Sabalausky wrote:
 I really see Flag more as a way to try to rationalize avoiding adding named
 parameters to the language.

There are fights that I believe are important and others that I think are less so. I find name parameters nice to have but more in the second category. There's just so much stuff that's more important.
 And yes, the legibility of "foo(Flag!"param".yes, Flag!"otherParam".no);",

Fair point. I figured this should be easier: foo(yes!"param", no!"otherParam"); See https://github.com/andralex/phobos/commit/84c75336a4ef04b4c3b1924d7ac9329e744ab8e7
 combined with the frequency of need for such a thing,

People have found 7 uses of the yes/no enum pattern in Phobos plus a couple others where it should - in 135KLoC.
 and the complete
 inability of Flag to address the problem for anything but bool,

Flag can be made to incorporate arbitrary categorical types, I just haven't done that yet so as to not complicate implementation too early.
 the
 inability to document it separately (as Jonathan Davis pointed out),

This is an issue shared by named parameters, and for such stuff the current enums work just fine. Now who is rationalizing? :o)
 is all
 definitely much much more than enough to warrant adding a tried-and-proven
 feature that's become standard in damn near every other modern language.

I'm actually less convinced than before having read your arguments. Andrei
Jun 10 2011
parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 11.06.2011 0:58, Andrei Alexandrescu wrote:
 On 6/10/11 3:30 PM, Nick Sabalausky wrote:
 I really see Flag more as a way to try to rationalize avoiding adding 
 named
 parameters to the language.

There are fights that I believe are important and others that I think are less so. I find name parameters nice to have but more in the second category. There's just so much stuff that's more important.
 And yes, the legibility of "foo(Flag!"param".yes, 
 Flag!"otherParam".no);",

Fair point. I figured this should be easier: foo(yes!"param", no!"otherParam");

I think this looks not half bad and does not require change in the language. Still yes.param and no.param might be easier on the eyes, though IMO it should look more like just param and no.param. e.g. StopWatch(autoStart); StopWatch(no!autoStart); // or no.autoStart -- Dmitry Olshansky
Jun 10 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/10/11 6:03 PM, Dmitry Olshansky wrote:
 On 11.06.2011 0:58, Andrei Alexandrescu wrote:
 On 6/10/11 3:30 PM, Nick Sabalausky wrote:
 I really see Flag more as a way to try to rationalize avoiding adding
 named
 parameters to the language.

There are fights that I believe are important and others that I think are less so. I find name parameters nice to have but more in the second category. There's just so much stuff that's more important.
 And yes, the legibility of "foo(Flag!"param".yes,
 Flag!"otherParam".no);",

Fair point. I figured this should be easier: foo(yes!"param", no!"otherParam");

I think this looks not half bad and does not require change in the language. Still yes.param and no.param might be easier on the eyes, though IMO it should look more like just param and no.param. e.g. StopWatch(autoStart); StopWatch(no!autoStart); // or no.autoStart

Ask, and ye shall receive. https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0b608895269bdccba4330 Andrei
Jun 10 2011
next sibling parent reply Mafi <mafi example.org> writes:
Am 11.06.2011 01:16, schrieb Andrei Alexandrescu:
 Ask, and ye shall receive.

 https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0b608895269bdccba4330

I like this version much more but shouldn't it also be flag.KeepTerminator for consistency? Mafi
Jun 11 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/11/11 4:58 AM, Mafi wrote:
 Am 11.06.2011 01:16, schrieb Andrei Alexandrescu:
 Ask, and ye shall receive.

 https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0b608895269bdccba4330

I like this version much more but shouldn't it also be flag.KeepTerminator for consistency? Mafi

Not sure I understand. How do you mean that? Andrei
Jun 11 2011
parent Mafi <mafi example.org> writes:
Am 11.06.2011 14:07, schrieb Andrei Alexandrescu:
 On 6/11/11 4:58 AM, Mafi wrote:
 Am 11.06.2011 01:16, schrieb Andrei Alexandrescu:
 Ask, and ye shall receive.

 https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0b608895269bdccba4330

I like this version much more but shouldn't it also be flag.KeepTerminator for consistency? Mafi

Not sure I understand. How do you mean that? Andrei

I meant something like this: template FlagImpl(string name) { enum FlagImpl : bool { yes = true, no = false } } //usage Flag.xy as alias for FlagImpl!"xy" //to be consistent with yes.xy and no.xy struct Flag { template opDispatch(string name) { alias FlagImpl!name opDispatch; } } Now, opDispatch cannot currently be a type, can it.
Jun 11 2011
prev sibling next sibling parent Mike Parker <aldacron gmail.com> writes:
On 6/11/2011 8:16 AM, Andrei Alexandrescu wrote:
 On 6/10/11 6:03 PM, Dmitry Olshansky wrote:
 On 11.06.2011 0:58, Andrei Alexandrescu wrote:
 On 6/10/11 3:30 PM, Nick Sabalausky wrote:
 I really see Flag more as a way to try to rationalize avoiding adding
 named
 parameters to the language.

There are fights that I believe are important and others that I think are less so. I find name parameters nice to have but more in the second category. There's just so much stuff that's more important.
 And yes, the legibility of "foo(Flag!"param".yes,
 Flag!"otherParam".no);",

Fair point. I figured this should be easier: foo(yes!"param", no!"otherParam");

I think this looks not half bad and does not require change in the language. Still yes.param and no.param might be easier on the eyes, though IMO it should look more like just param and no.param. e.g. StopWatch(autoStart); StopWatch(no!autoStart); // or no.autoStart

Ask, and ye shall receive. https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0b608895269bdccba4330 Andrei

I was going to add my voice against this proposal until I saw this. Nice one!
Jun 11 2011
prev sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2011-06-11 09:05:52 -0400, "Steven Schveighoffer" 
<schveiguy yahoo.com> said:

 As far as the negation, I think we need one more layer of type:
 
 struct FlagParam(string pname)
 {
     Flag!pname value;
     alias value this;
     this(Flag!pname x) { this.value = x }
     FlagParam op???() const { return FlagParam(cast(Flag!pname)!value); }
 }
 
 BTW, is there a way to hook "!"?  Maybe this won't work...  The idea is 
 to  have Yes.abc return FlagParam!"abc"(Flag!"abc".yes).

If you need to convert a bool to a Flag!"abc", you can do any of these: func(expression ? Yes.abc : No.abc); or func(cast(Flag!"abc")expression); or, with your proposal: func(FlagParam!"abc"(expression)); None of this is very appealing, but I find the first is the most readable. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jun 11 2011
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/11/11 8:25 AM, Michel Fortin wrote:
 On 2011-06-11 09:05:52 -0400, "Steven Schveighoffer"
 <schveiguy yahoo.com> said:

 As far as the negation, I think we need one more layer of type:

 struct FlagParam(string pname)
 {
 Flag!pname value;
 alias value this;
 this(Flag!pname x) { this.value = x }
 FlagParam op???() const { return FlagParam(cast(Flag!pname)!value); }
 }

 BTW, is there a way to hook "!"? Maybe this won't work... The idea is
 to have Yes.abc return FlagParam!"abc"(Flag!"abc".yes).

If you need to convert a bool to a Flag!"abc", you can do any of these: func(expression ? Yes.abc : No.abc); or func(cast(Flag!"abc")expression); or, with your proposal: func(FlagParam!"abc"(expression)); None of this is very appealing, but I find the first is the most readable.

Agreed. I'll venture to add that I find the first also more desirable than an implicit conversion from func(expression). Andrei
Jun 11 2011
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/11/11 9:30 AM, Steven Schveighoffer wrote:
 On Sat, 11 Jun 2011 09:25:19 -0400, Michel Fortin
 <michel.fortin michelf.com> wrote:

 On 2011-06-11 09:05:52 -0400, "Steven Schveighoffer"
 <schveiguy yahoo.com> said:

 As far as the negation, I think we need one more layer of type:
 struct FlagParam(string pname)
 {
 Flag!pname value;
 alias value this;
 this(Flag!pname x) { this.value = x }
 FlagParam op???() const { return FlagParam(cast(Flag!pname)!value); }
 }
 BTW, is there a way to hook "!"? Maybe this won't work... The idea is
 to have Yes.abc return FlagParam!"abc"(Flag!"abc".yes).

If you need to convert a bool to a Flag!"abc", you can do any of these: func(expression ? Yes.abc : No.abc); or func(cast(Flag!"abc")expression); or, with your proposal: func(FlagParam!"abc"(expression)); None of this is very appealing, but I find the first is the most readable.

We need another struct besides Yes and No that allows creation with another opDispatch: Foo.abc(expression); The best name for Foo is Flag, but that's taken... But still, is there a way to override the type returned by !flag? I think there isn't... That's kind of sucky. Flipping of a flag is a very common feature, I would expect to be able to do it easily.

I agree that's a drawback. I couldn't find a reasonable workaround. Andrei
Jun 11 2011
prev sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On 2011-06-10 13:36, Nick Sabalausky wrote:
 "Nick Sabalausky" <a a.a> wrote in message
 news:istv62$2skn$1 digitalmars.com...
 
 "Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message
 news:isttf6$2oub$1 digitalmars.com...
 
 On 6/10/11 1:52 PM, Robert Clipsham wrote:
 foo(param: true, otherParam: false);
 foo(Flag!"param".yes, Flag!"otherParam".no);
 
 I don't know about you, but I find the former is far more legible. I'd
 hate to see my code littered with Flag!"something".

I agree it's more legible. The crucial question is whether the added legibility warrants adding a new feature to the language.

I really see Flag more as a way to try to rationalize avoiding adding named parameters to the language. And yes, the legibility of "foo(Flag!"param".yes, Flag!"otherParam".no);", combined with the frequency of need for such a thing, and the complete inability of Flag to address the problem for anything but bool, the inability to document it separately (as Jonathan Davis pointed out), is all definitely much much more than enough to warrant adding a tried-and-proven feature that's become standard in damn near every other modern language.

Regarding "the complete inability of Flag to address the problem for anything but bool", how are we going to wind up papering over that? Like: box(Int!"x"(3), Int!"y"(4), Int!"width"(100), Int!"height"(150), Int!"depth"(1), UInt!"color"(0xFFAA77));

These yes/no enums _aren't_ named arguments. They're an attempt at creating new types where the values say what they are. The goal is primarily clarity, which named arguments arguably help with, but it's not quite the same thing. Without typedef (which is on its way out), you can't really do something like that with anything other than bool. Int!"y"(4) has to generate an int (unless you want to be forcing that all of these arguments be structs, which would be hideous), at which point it's purely documentation which the compiler has to optimize out. It's not doing the same thing as Flag at all. Andrei isn't trying to create general named arguments here. He's simply trying to create a cleaner way of generating enums with yes and no values and thus reduce boilerplate code. Having named arguments would create a similar effect, but the goal of this enum has nothing to do with named arguments beyond the fact that they have a similar effect. Its goal is to reduce boilerplate code. The net result of having the enums and Flag _is_ similar to named arguments for bool, but I don't believe that Andrei ever set down this path with the idea of creating named arguments. He effectively wanted a typedef for bool which was self-documenting. So, your suggestions of Int!"height(150) and the like are trying to do something very different (albeit somewhat related) to what Flag is trying to do. - Jonathan M Davis
Jun 10 2011
prev sibling parent KennyTM~ <kennytm gmail.com> writes:
On Jun 11, 11 02:06, Andrei Alexandrescu wrote:
 On 6/10/11 12:42 PM, Robert Clipsham wrote:
 On 10/06/2011 17:15, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/phobos/pull/94

 Discuss!

 Andrei

I really *really* don't like this. It's ugly and verbose, and a pathetic work around for the lack of named parameters. Either support named parameters or not, don't have an ugly half-baked work-around.

This is not half-baked. It's pretty much it. Ugly is in the eye of the beholder, but I fail to see how the added punctuation makes Flag!"param".yes significantly more verbose than param : true. The problem that named parameters are still optional remains. Or we need to add one extra language feature to specify required named parameters. Andrei

Making the compulsory enum name as a feature means http://www.digitalmars.com/d/archives/digitalmars/D/8524.html will never be addressed, I suppose.
Jun 10 2011
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On 2011-06-10 10:57, KennyTM~ wrote:
 On Jun 11, 11 01:42, Robert Clipsham wrote:
 On 10/06/2011 17:15, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/phobos/pull/94
 
 Discuss!
 
 Andrei

I really *really* don't like this. It's ugly and verbose, and a pathetic work around for the lack of named parameters. Either support named parameters or not, don't have an ugly half-baked work-around.

Well I agree it is ugly, but at least it's better than having the same enum 7 times in Phobos (std.stdio.KeepTerminator, std.string.CaseSensitive, std.algorithm.OpenRight, std.algorithm.SortOutput, std.datetime.AllowDayOverflow, std.datetime.PopFirst, std.datetime.AutoStart). If named parameter is supported, those Flag!"foo" parameters can be reverted back to bool without breaking the caller as the enum is based on bool.

And there are places in Phobos which _should_ be using enums like this but aren't (e.g. std.file.dirEntries' followSymlinks bool), so the number is only going to go up as such things are fixed, even without adding new code to Phobos. And of course, we're going to be adding new code, so the amount of duplication for this type of enum is only going to go up. - Jonathan M Davis
Jun 10 2011
prev sibling next sibling parent Torarin <torarind gmail.com> writes:
2011/6/10 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:
 On 6/10/11 1:52 PM, Robert Clipsham wrote:
 On 10/06/2011 19:06, Andrei Alexandrescu wrote:
 On 6/10/11 12:42 PM, Robert Clipsham wrote:
 On 10/06/2011 17:15, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/phobos/pull/94

 Discuss!

 Andrei

I really *really* don't like this. It's ugly and verbose, and a pathetic work around for the lack of named parameters. Either support named parameters or not, don't have an ugly half-baked work-around.

This is not half-baked. It's pretty much it.

My choice of wording was poor, sorry.
 Ugly is in the eye of the beholder, but I fail to see how the added
 punctuation makes Flag!"param".yes significantly more verbose than param
 : true.

foo(param: true, otherParam: false); foo(Flag!"param".yes, Flag!"otherParam".no); I don't know about you, but I find the former is far more legible. I'd hate to see my code littered with Flag!"something".

I agree it's more legible. The crucial question is whether the added legibility warrants adding a new feature to the language.
 The problem that named parameters are still optional remains. Or we need
 to add one extra language feature to specify required named parameters.

void foo(bool param, bool otherParam, bool thisOneIsntRequired = false); Call it with or without named parameters, two are required, one is not. foo(otherParam: true, param: false); foo(true, false); foo(otherParam: true, param: false, thisOneIsntRequired: true); Would all be valid.

The second call is problematic because it still allows bad style in calls. Andrei

I agree, introducing a syntax for required named parameters sounds like it would entail baggage of similar weight. Torarin
Jun 10 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 6/10/11, Lutger Blijdestijn <lutger.blijdestijn gmail.com> wrote:
 Changing a name will now break client code.

The flag template suffers from the same issue.
Jun 10 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 10 Jun 2011 17:34:34 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 6/10/11 4:28 PM, Andrej Mitrovic wrote:
 On 6/10/11, Lutger Blijdestijn<lutger.blijdestijn gmail.com>  wrote:
 Changing a name will now break client code.

The flag template suffers from the same issue.

Actually, not. The name used with Flag is part of its type. Even in a separate compilation approach, the type names must match, which is not the case for parameter names.

No, it's not the same, which actually can be viewed as a plus for named parameters. A named parameter call reduces to a normal call with boolean args, which is binary compatible, even if you change the name of the parameter. A Flag! requires a recompile as well as a source change. For things like fixing typos, the binary compatibility might be good. For example, if you have a typo in the name of a Flag parameter in library version 1, you can never change the name and be backwards compatible with someone who has an old version of the library they are compiling against. The Flag makes it *more* a part of the API than named parameters. -Steve
Jun 10 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 6/10/11, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:
 On 6/10/11 4:28 PM, Andrej Mitrovic wrote:
 On 6/10/11, Lutger Blijdestijn<lutger.blijdestijn gmail.com>  wrote:
 Changing a name will now break client code.

The flag template suffers from the same issue.

Actually, not. The name used with Flag is part of its type. Even in a separate compilation approach, the type names must match, which is not the case for parameter names. Andrei

I've either misread what Lutger said or I haven't stated my intentions more clearly. Most probably both.. :) By "breaking code", I'm referring to breaking compilation of existing code, not breaking the runtime semantics. You're doing this now: Flag!"KeepTerminator" keepTerminator You can change the variable name and the client code still compiles. But are you going to keep the name "KeepTerminator" in sync with the new variable name? It sure seems that's how this Flag template is used. If you do, that means client code has to change as well. Named arguments have the same problem. That's what I was referring to.
Jun 10 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 6/11/11, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:
 Ask, and ye shall receive.

 https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0b608895269bdccba4330

That's much more like it. This whole bikeshedding issue for me was avoiding the nasty bang quote string unquote shenanigans that look ugly in code. Keeping No and Yes at the beginning kind of goes in hand with the not operator. Now that I mention it, you can't negate a Flag variable: Flag!"KeepTerminator" state; auto line = getLine(!state); But maybe that's a good thing?
Jun 10 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
We should rename Yes and No to Yay and Nay to make them alignable, and
even more importantly to make us appear as old Englishmen!

Kidding. I do welcome the proposal with the prefixed Yes/No template
though, it has my vote.
Jun 10 2011
prev sibling next sibling parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
On Fri, 10 Jun 2011 18:16:14 -0500, Andrei Alexandrescu wrote:

 On 6/10/11 6:03 PM, Dmitry Olshansky wrote:
 On 11.06.2011 0:58, Andrei Alexandrescu wrote:
 On 6/10/11 3:30 PM, Nick Sabalausky wrote:
 I really see Flag more as a way to try to rationalize avoiding adding
 named
 parameters to the language.

There are fights that I believe are important and others that I think are less so. I find name parameters nice to have but more in the second category. There's just so much stuff that's more important.
 And yes, the legibility of "foo(Flag!"param".yes,
 Flag!"otherParam".no);",

Fair point. I figured this should be easier: foo(yes!"param", no!"otherParam");

I think this looks not half bad and does not require change in the language. Still yes.param and no.param might be easier on the eyes, though IMO it should look more like just param and no.param. e.g. StopWatch(autoStart); StopWatch(no!autoStart); // or no.autoStart

Ask, and ye shall receive. https://github.com/andralex/phobos/

I'm sold. :) To add my 2 cents to the "named arguments" debate, I can't believe people are still asking for this. At this point in D's development, adding such would be a major language change, and there really shouldn't be any more of those. I mean, D2 supposedly went stable almost a year ago! If/when work starts on D3, we can get back to it. In the mean time, I think Flag!"param" with the new Yes/No types nicely solves a common case of code duplication in Phobos. It is not, nor do I think Andrei intended it to be, a general attempt to emulate named parameters. -Lars
Jun 10 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 10 Jun 2011 19:16:14 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 6/10/11 6:03 PM, Dmitry Olshansky wrote:
 On 11.06.2011 0:58, Andrei Alexandrescu wrote:
 On 6/10/11 3:30 PM, Nick Sabalausky wrote:
 I really see Flag more as a way to try to rationalize avoiding adding
 named
 parameters to the language.

There are fights that I believe are important and others that I think are less so. I find name parameters nice to have but more in the second category. There's just so much stuff that's more important.
 And yes, the legibility of "foo(Flag!"param".yes,
 Flag!"otherParam".no);",

Fair point. I figured this should be easier: foo(yes!"param", no!"otherParam");

I think this looks not half bad and does not require change in the language. Still yes.param and no.param might be easier on the eyes, though IMO it should look more like just param and no.param. e.g. StopWatch(autoStart); StopWatch(no!autoStart); // or no.autoStart

Ask, and ye shall receive. https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0b608895269bdccba4330

This is better. Does the definition of the function still require repetition? i.e. getLine(Flag!"KeepTerminator" keepTerminator = Yes.KeepTerminator). I suppose we can live with that. Still reads weird to me with the value coming before the category, but I suppose the names can be adjusted accordingly. As far as the negation, I think we need one more layer of type: struct FlagParam(string pname) { Flag!pname value; alias value this; this(Flag!pname x) { this.value = x } FlagParam op???() const { return FlagParam(cast(Flag!pname)!value); } } BTW, is there a way to hook "!"? Maybe this won't work... The idea is to have Yes.abc return FlagParam!"abc"(Flag!"abc".yes). -Steve
Jun 11 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sat, 11 Jun 2011 09:25:19 -0400, Michel Fortin  
<michel.fortin michelf.com> wrote:

 On 2011-06-11 09:05:52 -0400, "Steven Schveighoffer"  
 <schveiguy yahoo.com> said:

 As far as the negation, I think we need one more layer of type:
  struct FlagParam(string pname)
 {
     Flag!pname value;
     alias value this;
     this(Flag!pname x) { this.value = x }
     FlagParam op???() const { return FlagParam(cast(Flag!pname)!value);  
 }
 }
  BTW, is there a way to hook "!"?  Maybe this won't work...  The idea  
 is to  have Yes.abc return FlagParam!"abc"(Flag!"abc".yes).

If you need to convert a bool to a Flag!"abc", you can do any of these: func(expression ? Yes.abc : No.abc); or func(cast(Flag!"abc")expression); or, with your proposal: func(FlagParam!"abc"(expression)); None of this is very appealing, but I find the first is the most readable.

We need another struct besides Yes and No that allows creation with another opDispatch: Foo.abc(expression); The best name for Foo is Flag, but that's taken... But still, is there a way to override the type returned by !flag? I think there isn't... That's kind of sucky. Flipping of a flag is a very common feature, I would expect to be able to do it easily. Hm... what if opCast!bool() returns something other than bool? does that actually work? That *would* be a hack :) We could also possibly use unary - to denote flipping a flag. That's very hacky too, but I think it would work. -Steve
Jun 11 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 6/11/11, Alix Pexton <alix.DOT.pexton gmail.dot.com> wrote:
 On 11/06/2011 06:18, Andrej Mitrovic wrote:
 We should rename Yes and No to Yay and Nay to make them alignable, and
 even more importantly to make us appear as old Englishmen!

"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not actually a old English word :) A more correct alternative would be "Aye" (pronounced the same as "eye"), which (along with "Nay") is still used for some voting actions (such as councillors deciding where to go for lunch). I myself say it al least 20 times a day :) A...

Oh damn, yay is what teenage girls would say, not old Englishmen. My bad, it really is "Aye". :p
Jun 11 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sat, 11 Jun 2011 13:04:47 -0400, Andrej Mitrovic  
<andrej.mitrovich gmail.com> wrote:

 On 6/11/11, Alix Pexton <alix.DOT.pexton gmail.dot.com> wrote:
 On 11/06/2011 06:18, Andrej Mitrovic wrote:
 We should rename Yes and No to Yay and Nay to make them alignable, and
 even more importantly to make us appear as old Englishmen!

"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not actually a old English word :) A more correct alternative would be "Aye" (pronounced the same as "eye"), which (along with "Nay") is still used for some voting actions (such as councillors deciding where to go for lunch). I myself say it al least 20 times a day :) A...

Oh damn, yay is what teenage girls would say, not old Englishmen. My bad, it really is "Aye". :p

You were phonetically right :) It's yea or nay. http://dictionary.cambridge.org/dictionary/british/yea-or-nay My son's most recent birthday (3 years old) was a farm-themed birthday, and we asked people to RSVP yay or neigh :P So I guess there's all kinds of kooky fun you can have with flags... -Steve
Jun 11 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sun, 12 Jun 2011 04:36:55 -0400, Alix Pexton  
<alix.DOT.pexton gmail.dot.com> wrote:

 On 12/06/2011 02:40, Steven Schveighoffer wrote:
 On Sat, 11 Jun 2011 13:04:47 -0400, Andrej Mitrovic
 <andrej.mitrovich gmail.com> wrote:

 On 6/11/11, Alix Pexton <alix.DOT.pexton gmail.dot.com> wrote:
 On 11/06/2011 06:18, Andrej Mitrovic wrote:
 We should rename Yes and No to Yay and Nay to make them alignable,  
 and
 even more importantly to make us appear as old Englishmen!

"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not actually a old English word :) A more correct alternative would be "Aye" (pronounced the same as "eye"), which (along with "Nay") is still used for some voting actions (such as councillors deciding where to go for lunch). I myself say it al least 20 times a day :) A...

Oh damn, yay is what teenage girls would say, not old Englishmen. My bad, it really is "Aye". :p

You were phonetically right :) It's yea or nay. http://dictionary.cambridge.org/dictionary/british/yea-or-nay My son's most recent birthday (3 years old) was a farm-themed birthday, and we asked people to RSVP yay or neigh :P So I guess there's all kinds of kooky fun you can have with flags... -Steve

Nope, its definitely Aye when used for voting, (at least it is round here) as in "all those in favour, say aye", "ayes to the right" and "the ayes have it". Maybe southerners say this "yea" word of which you speak, we don't hold with their strange customs in these parts ^^

I don't deny that aye is used frequently for voting. All I was saying is, the correct expression is yea or nay, not yay or nay. Andrej thought it was actually aye or nay, which I've never heard as an expression. I'm not sure it's used anymore, but it's definitely an expression that was used for voting (see my dictionary reference). -Steve
Jun 12 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
TBH I've only ever heard it used in Ali G Indahouse, so what do I know.. :p
Jun 12 2011
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-06-10 09:15, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/phobos/pull/94
 
 Discuss!

I do have to admit that as much as I hate the idea of named parameters, this particular proposal certainly seems to be an argument in favor of adding them, which would tend to argue against making these changes. After thinking about it, I'd argue that it would be better to create a string mixin which created the enums for you instead of using the template as part of the arguments. e.g. mixin(YesNoEnum!"KeepTerminator")); Then all of the rest of the code is the same. You'd still use KeepTerminator.yes and KeepTerminator.no, but we avoided having to create duplicate enums by hand every time that we want this kind of variable. So, you still reduce the boilerplate code, but the usage is much less ugly. - Jonathan M Davis
Jun 10 2011
next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
On Jun 11, 11 03:30, Jonathan M Davis wrote:
 On 2011-06-10 09:15, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/phobos/pull/94

 Discuss!

I do have to admit that as much as I hate the idea of named parameters, this particular proposal certainly seems to be an argument in favor of adding them, which would tend to argue against making these changes. After thinking about it, I'd argue that it would be better to create a string mixin which created the enums for you instead of using the template as part of the arguments. e.g. mixin(YesNoEnum!"KeepTerminator")); Then all of the rest of the code is the same. You'd still use KeepTerminator.yes and KeepTerminator.no, but we avoided having to create duplicate enums by hand every time that we want this kind of variable. So, you still reduce the boilerplate code, but the usage is much less ugly. - Jonathan M Davis

The problem is the 'YesNoEnum!"KeepTerminator"' will not be shown along with the DDoc of 'getLine'.
Jun 10 2011
parent KennyTM~ <kennytm gmail.com> writes:
On Jun 11, 11 03:40, Jonathan M Davis wrote:
 On 2011-06-10 12:33, KennyTM~ wrote:
 On Jun 11, 11 03:30, Jonathan M Davis wrote:
 On 2011-06-10 09:15, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/phobos/pull/94

 Discuss!

I do have to admit that as much as I hate the idea of named parameters, this particular proposal certainly seems to be an argument in favor of adding them, which would tend to argue against making these changes. After thinking about it, I'd argue that it would be better to create a string mixin which created the enums for you instead of using the template as part of the arguments. e.g. mixin(YesNoEnum!"KeepTerminator")); Then all of the rest of the code is the same. You'd still use KeepTerminator.yes and KeepTerminator.no, but we avoided having to create duplicate enums by hand every time that we want this kind of variable. So, you still reduce the boilerplate code, but the usage is much less ugly. - Jonathan M Davis

The problem is the 'YesNoEnum!"KeepTerminator"' will not be shown along with the DDoc of 'getLine'.

Why would it be? You generally want documentation specific to the enum anyway, so that isn't exactly boilerplate. You'd just stick the documentation above the mixin. And if you don't want to do that but want it in the documentation for the function that uses it (particularly if there's only one - though that's often not the case), then just put the documentation in the function's documentation. Andrei's current solution does nothing for documentation, and arguably makes it worse, because there's no place to put documentation on the enum directly if you need to. - Jonathan M Davis

Please review the previous discussion of why Flag (was YesOrNo) was proposed. http://www.digitalmars.com/d/archives/digitalmars/D/YesOrNo_useful_idiom_helper_or_wanking_134392.html
Jun 10 2011
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/10/11 2:30 PM, Jonathan M Davis wrote:
 On 2011-06-10 09:15, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/phobos/pull/94

 Discuss!

I do have to admit that as much as I hate the idea of named parameters, this particular proposal certainly seems to be an argument in favor of adding them, which would tend to argue against making these changes.

There is general agreement (which includes myself) that a language feature is nicer than Flag, and that Flag is nicer than the current state of affairs. This is no surprise because a specialized language feature will _always_ be better than one built from tools offered within the language. It's like God vs. human. So the crucial question is whether a language change is warranted. We should be much more restrained than this discussion suggests. Any and all programming languages have limitations. This, coupled with the former point, leads to the fact that at some point you MUST look into doing within the language something that could be done nicer if you got to play God. Doing the latter does not scale. So, does Flag work around a limitation in the language? Sure. Would a language-changing solution work better? Absolutely. Is the necessity of changing the language a foregone conclusion? I don't think so. Andrei
Jun 10 2011
next sibling parent "Nick Sabalausky" <a a.a> writes:
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message 
news:istulq$2rjc$1 digitalmars.com...
 On 6/10/11 2:30 PM, Jonathan M Davis wrote:
 On 2011-06-10 09:15, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/phobos/pull/94

 Discuss!

I do have to admit that as much as I hate the idea of named parameters, this particular proposal certainly seems to be an argument in favor of adding them, which would tend to argue against making these changes.

There is general agreement (which includes myself) that a language feature is nicer than Flag,

Much
 and that Flag is nicer than the current state of affairs.

Only *barely*.
 This is no surprise because a specialized language feature will _always_ 
 be better than one built from tools offered within the language. It's like 
 God vs. human.

 So the crucial question is whether a language change is warranted. We 
 should be much more restrained than this discussion suggests. Any and all 
 programming languages have limitations. This, coupled with the former 
 point, leads to the fact that at some point you MUST look into doing 
 within the language something that could be done nicer if you got to play 
 God. Doing the latter does not scale.

 So, does Flag work around a limitation in the language? Sure. Would a 
 language-changing solution work better? Absolutely. Is the necessity of 
 changing the language a foregone conclusion? I don't think so.

In general, I would agree with this. I completely understand the desire, and even the need, to avoid extra language features when reasonable to do so. I really do. But the idea of using Flag over named parameters just stretches it to a rediculous extreme. This seriously reminds me of Sun's infamous whitepaper that desperately tried to rationalize Java's lack of delegates/anon-funcs ("But you can use functors!!!" Fuck functors.) Is adding the feature of named parameters worthwhile in light of Flag? *YES*, *ABSOLUTELY*, *CLEARLY*, *DEFINITELY*, *YES*, *YES*, *YES*.
Jun 10 2011
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Andrei:

 We should be much more restrained than this discussion suggests. Any and 
 all programming languages have limitations. This, coupled with the 
 former point, leads to the fact that at some point you MUST look into 
 doing within the language something that could be done nicer if you got 
 to play God. Doing the latter does not scale.

This use of word "scale" assumes there is a larger and larger group of basic features that we'll desire in the language. But I have experience both of "normal" languages and of languages with macros as Scheme, and I don't think this is true. In the next few years we will not want to add a large and growing number of basic features to D2/D3. And currently in D there are features much less generally useful than named arguments or tuple unpacking syntax sugar, as Delimited Strings, Lazy Variadic Functions and more.
 So, does Flag work around a limitation in the language? Sure. Would a 
 language-changing solution work better? Absolutely. Is the necessity of 
 changing the language a foregone conclusion? I don't think so.

Named arguments offer a more general solution than Flags, useful for all kinds of arguments, with a more readable syntax. I don't think you need a sub-feature to _require_ the argument name at the call point (on the other hand you may desire a sub-feature Scala has, to support deprecation of argument names. This helps solve a problem Don too has with named arguments). Bye, bearophile
Jun 10 2011
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/10/11 5:14 PM, Steven Schveighoffer wrote:
 On Fri, 10 Jun 2011 16:21:59 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 There is general agreement (which includes myself) that a language
 feature is nicer than Flag,

Yes.
 and that Flag is nicer than the current state of affairs.

No. Flag!"KeepTerminator".yes is much worse than KeepTerminator.yes. And Flag!"KeepTerminator" keepTerminator is just, horrendous, in documentation *or* source.

https://github.com/andralex/phobos/commit/84c75336a4ef04b4c3b1924d7ac9329e744ab8e7
 If the rote creation of boolean enums is a problem, why not a mixin?

 template Flag(string name)
 {
 mixin("enum " ~ name ~ " : bool { no = false, yes = true }");
 }

 mixin Flag!"KeepTerminator";

Because you still need to define it separately from use.
 This is no surprise because a specialized language feature will
 _always_ be better than one built from tools offered within the
 language. It's like God vs. human.

I think the debate is more about how this solution is a step in the wrong direction more than it's not as good as a real solution.
 So the crucial question is whether a language change is warranted.

If the options are Flag or a language solution, the answer is yes. I'd much rather keep things as they are than have Flag!string.

Keeping things as they are fosters awkward duplication or coupling. Andrei
Jun 10 2011
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/10/11 7:09 PM, Jonathan M Davis wrote:
 What I want to know is what you want to do with such enums where it's actually
 _desirable_ that they be defined separately from use.

I guess if you want such you either define the flag separately or make it an alias and document the alias. I mean there's nothing new here just because Flag came about. Andrei
Jun 10 2011
prev sibling parent "Nick Sabalausky" <a a.a> writes:
"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message 
news:mailman.781.1307734245.14074.digitalmars-d puremagic.com...
 On 2011-06-10 09:15, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/phobos/pull/94

 Discuss!

I do have to admit that as much as I hate the idea of named parameters, this particular proposal certainly seems to be an argument in favor of adding them, which would tend to argue against making these changes. After thinking about it, I'd argue that it would be better to create a string mixin which created the enums for you instead of using the template as part of the arguments. e.g. mixin(YesNoEnum!"KeepTerminator")); Then all of the rest of the code is the same. You'd still use KeepTerminator.yes and KeepTerminator.no, but we avoided having to create duplicate enums by hand every time that we want this kind of variable. So, you still reduce the boilerplate code, but the usage is much less ugly.

I'd support this *as long as* it's existence didn't get used as rationalization for avoiding the inclusion of named arguments.
Jun 10 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-06-10 12:33, KennyTM~ wrote:
 On Jun 11, 11 03:30, Jonathan M Davis wrote:
 On 2011-06-10 09:15, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/phobos/pull/94
 
 Discuss!

I do have to admit that as much as I hate the idea of named parameters, this particular proposal certainly seems to be an argument in favor of adding them, which would tend to argue against making these changes. After thinking about it, I'd argue that it would be better to create a string mixin which created the enums for you instead of using the template as part of the arguments. e.g. mixin(YesNoEnum!"KeepTerminator")); Then all of the rest of the code is the same. You'd still use KeepTerminator.yes and KeepTerminator.no, but we avoided having to create duplicate enums by hand every time that we want this kind of variable. So, you still reduce the boilerplate code, but the usage is much less ugly. - Jonathan M Davis

The problem is the 'YesNoEnum!"KeepTerminator"' will not be shown along with the DDoc of 'getLine'.

Why would it be? You generally want documentation specific to the enum anyway, so that isn't exactly boilerplate. You'd just stick the documentation above the mixin. And if you don't want to do that but want it in the documentation for the function that uses it (particularly if there's only one - though that's often not the case), then just put the documentation in the function's documentation. Andrei's current solution does nothing for documentation, and arguably makes it worse, because there's no place to put documentation on the enum directly if you need to. - Jonathan M Davis
Jun 10 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-06-10 12:47, KennyTM~ wrote:
 On Jun 11, 11 03:40, Jonathan M Davis wrote:
 On 2011-06-10 12:33, KennyTM~ wrote:
 On Jun 11, 11 03:30, Jonathan M Davis wrote:
 On 2011-06-10 09:15, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/phobos/pull/94
 
 Discuss!

I do have to admit that as much as I hate the idea of named parameters, this particular proposal certainly seems to be an argument in favor of adding them, which would tend to argue against making these changes. After thinking about it, I'd argue that it would be better to create a string mixin which created the enums for you instead of using the template as part of the arguments. e.g. mixin(YesNoEnum!"KeepTerminator")); Then all of the rest of the code is the same. You'd still use KeepTerminator.yes and KeepTerminator.no, but we avoided having to create duplicate enums by hand every time that we want this kind of variable. So, you still reduce the boilerplate code, but the usage is much less ugly. - Jonathan M Davis

The problem is the 'YesNoEnum!"KeepTerminator"' will not be shown along with the DDoc of 'getLine'.

Why would it be? You generally want documentation specific to the enum anyway, so that isn't exactly boilerplate. You'd just stick the documentation above the mixin. And if you don't want to do that but want it in the documentation for the function that uses it (particularly if there's only one - though that's often not the case), then just put the documentation in the function's documentation. Andrei's current solution does nothing for documentation, and arguably makes it worse, because there's no place to put documentation on the enum directly if you need to. - Jonathan M Davis

Please review the previous discussion of why Flag (was YesOrNo) was proposed. http://www.digitalmars.com/d/archives/digitalmars/D/YesOrNo_useful_idiom_he lper_or_wanking_134392.html

In many cases, I very much think that the documentation should be separate. A prime example would be std.datetime.AllowDayOverflow. It's use in several places in std.datetime, and having one place to read up on it is definitely beneficial. Not having a place where the enum is defined separately would definitely be worse in that case. The area where it's more debatable is when there's only _one_ function which uses the enum. Then Andrei's proposed solution is more reasonable. But worse comes to worst, you can _still_ put the documentation with the function in the current solution. Andrei's solution adds _nothing_ to that. It just makes it so that there isn't actually a separate enum somewhere which can be documented. It removes the possibility of documenting it. I'd rather have the one line mixin which you can either document directly or skip documenting and put its documentation with the function that uses it rather than one where you _can't_ document it separately. std.datetime will _not_ switch to this even if it gets checked in simply because it will make the documentation worse. And I'm not sure that we want to have some enums using this solution and some not, since that would be inconsistent. I'm not entirely against Andrei's solution (it does reduce boilerplate code), but I think that a string mixin solution makes more sense. It's less verbose, and you can choose where to put its documentation. - Jonathan M Davis
Jun 10 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 10 Jun 2011 16:21:59 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 6/10/11 2:30 PM, Jonathan M Davis wrote:
 On 2011-06-10 09:15, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/phobos/pull/94

 Discuss!

I do have to admit that as much as I hate the idea of named parameters, this particular proposal certainly seems to be an argument in favor of adding them, which would tend to argue against making these changes.

There is general agreement (which includes myself) that a language feature is nicer than Flag,

Yes.
 and that Flag is nicer than the current state of affairs.

No. Flag!"KeepTerminator".yes is much worse than KeepTerminator.yes. And Flag!"KeepTerminator" keepTerminator is just, horrendous, in documentation *or* source. If the rote creation of boolean enums is a problem, why not a mixin? template Flag(string name) { mixin("enum " ~ name ~ " : bool { no = false, yes = true }"); } mixin Flag!"KeepTerminator";
 This is no surprise because a specialized language feature will _always_  
 be better than one built from tools offered within the language. It's  
 like God vs. human.

I think the debate is more about how this solution is a step in the wrong direction more than it's not as good as a real solution.
 So the crucial question is whether a language change is warranted.

If the options are Flag or a language solution, the answer is yes. I'd much rather keep things as they are than have Flag!string. -Steve
Jun 10 2011
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On 2011-06-10 15:54, Andrei Alexandrescu wrote:
 On 6/10/11 5:14 PM, Steven Schveighoffer wrote:
 On Fri, 10 Jun 2011 16:21:59 -0400, Andrei Alexandrescu
 
 <SeeWebsiteForEmail erdani.org> wrote:
 There is general agreement (which includes myself) that a language
 feature is nicer than Flag,

Yes.
 and that Flag is nicer than the current state of affairs.

No. Flag!"KeepTerminator".yes is much worse than KeepTerminator.yes. And Flag!"KeepTerminator" keepTerminator is just, horrendous, in documentation *or* source.

https://github.com/andralex/phobos/commit/84c75336a4ef04b4c3b1924d7ac9329e7 44ab8e7
 If the rote creation of boolean enums is a problem, why not a mixin?
 
 template Flag(string name)
 {
 mixin("enum " ~ name ~ " : bool { no = false, yes = true }");
 }
 
 mixin Flag!"KeepTerminator";

Because you still need to define it separately from use.

What I want to know is what you want to do with such enums where it's actually _desirable_ that they be defined separately from use. A prime example of this is std.datetime's AllowDayOverflow. It's used by several functions, and by having it explicitly defined separately, it can be appropriately documented in one place rather than having to explain it for every function that uses it. I really think that it _should_ be defined separately. But if it is defined separately, then I don't see how it could work with the Flag template. Even if we go with the improved yes and no templates that you just added (which are definitely an improvement over naked Flag), they don't work with a yes/no enum which is defined separately. This means that you'll have AllowDayOverflow.yes and AllowDayOverflow.no instead of yes!"AllowDayOverflow" and no!"AllowDayOverflow". That's not necessarily a bad thing, since the enum _is_ defined differently, but if the common idiom is to use yes!"enumName" and no!"enumName", then the yes/no enums which are actually defined separately won't match. Is that acceptable, or is there actually a reasonable way to make the yes and no templates work with non-Flag enums (perhaps by having it first check whether enumName.yes compiles before trying Flag!"enumName")? - Jonathan M Davis
Jun 10 2011
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-06-10 09:15, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/phobos/pull/94
 
 Discuss!

Okay. Let's see if I can summarize this. Andrei thinks that have a categorized boolean type which is explicit about what it's used for is valuable. So, for instance, std.algorithm.until takes OpenRight.yes and OpenRight.no rather than bool so that it's explicit to the caller what the boolean value indicates and so that you don't accidentally pass a bool which means something else entirely to until. This currently requires declaring a separate enum with yes and no values for every function that does this with the occasional function which can reuse such an enum from another function, because it needs a boolean value for exactly the same thing. Andrei therefore have 2 problems with the status quo: 1. Programmers following this idiom (including the Phobos devs) end up creating enums with yes and no values and are effectively identical to other enums except for their names. So, we end up with a fair bit of boilerplate code just to pass a strict boolean value. 2. The documentation for these yes/no enums generally really should be with the function that they're using but ends up on the enum itself or in both places. Ideally, it would just go with the function. So, Andrei created the Flag template in an attempt to do 3 things: 1. Be able to create the yes/no enum just by declaring the type of the function parameter - you eliminate boilerplate code. 2. The documentation is then clearly with the function that the yes/no enum goes with (it has nowhere else to go). 3. It promotes the yes/no idiom in a manner than seeing Flag!"enumName" as the type makes it immediately clear what the type in question is trying to do, and no one feels the need to go looking for the documentation for the enum because the use of the Flag idiom makes it clear what the type is. The complaints about this generally seem to be one of these: 1. Dislike of the yes/no enum idiom in the first place. Regardless of how Flag does it, it's a problem, because it's promoting an idiom that the poster dislikes in the first place. 2. Flag!"enumName".yes and Flag!"enumName".no are ugly. 3. The use of a template such as Flag results in ugly error messages when it's mistyped. EnumName.yes gets _much_ better errors when mistyped than Flag!"enumName".yes. 4. Flag is seen as a narrow attempt at named arguments which would be far better served by actually implementing named arguments. Andrei's response to each of these in turn is: 1. He argues for the yes/no enum idiom, citing issues with naked bool values and lack of clarity in code - how it saves you from having to look at the documentation to figure out what a particular boolean value means. It's essentially the same arguments he's made for the idiom ever since it was introduced into Phobos. 2. He proposed a template wrapper which would allow you to type yes!"enumName" and no!"enumName" instead of the full Flag!"enumName".yes and Flag!"enumName".no. Some people feel that this resolves complaint #2. Others think that it's still quite ugly. 3. He essentially says that the compiler's error messages for templates need to be improved. It's an inherent problem with templates. 4. He's not trying to solve anything with named arguments. He's trying to solve a much narrower problem of naked bool values being relatively meaningless for many function arguments and error-prone when you pass a boolean value which meant something else entirely. yes/no enums solve that specific problem. Named arguments would be a change to the language at a time when we should be looking at doing as much with the language as possible rather than looking to add new features to it. Features which solve restrictions and intrinsic problems in the language need to be looked at, but those which could be solved by using the existing language and creating a library-based solution should be first explored as library solutions. Would you say that this is a fair summary of this debate so far? - Jonathan M Davis
Jun 11 2011
next sibling parent reply David Nadlinger <see klickverbot.at> writes:
On 6/11/11 11:20 PM, Jonathan M Davis wrote:
 1. Programmers following this idiom (including the Phobos devs) end up
 creating enums with yes and no values and are effectively identical to other
 enums except for their names. So, we end up with a fair bit of boilerplate
 code just to pass a strict boolean value.

s/fair/tiny/, imho: --- /// ditto. enum SomeFlag { enable, disable } --- David
Jun 11 2011
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 06/11/2011 04:42 PM, Jonathan M Davis wrote:
 On 2011-06-11 14:32, David Nadlinger wrote:
 On 6/11/11 11:20 PM, Jonathan M Davis wrote:
 1. Programmers following this idiom (including the Phobos devs) end up
 creating enums with yes and no values and are effectively identical to
 other enums except for their names. So, we end up with a fair bit of
 boilerplate code just to pass a strict boolean value.

s/fair/tiny/, imho: --- /// ditto. enum SomeFlag { enable, disable } ---

It's a fair bit only insomuch as the same code is duplicated in several places. The code itself in each instance is small. But if you do that enough times, it adds up. Whether it's enough to matter is debatable, but there is definitely boilerplate code there which could be reduced. - Jonathan M Davis

It's the namespace pollution and the non-self-containedness of the function that's most troublesome. Also see Steve's point about methods. It's just untenable - to use the idiom with a class/struct method, you need to go all the way _outside_ of it an plant a symbol there. What I find most interesting is that the lack of strong counterarguments has not stood in the way of a strong emotional response. This mood has made it difficult for exchange of rational arguments. Funny thing is, the change is tiny. "Here, I'll add a handful of yes/no enums here and there in the standard library, just to help some algorithms. More to come." "Yeah, sure, whatevs." "Here, there's a way to define them once so we don't need to define them everywhere." "Gaaaaaaaaaaaaaa!!!" Andrei
Jun 11 2011
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-06-11 20:50, Jonathan M Davis wrote:
 On 2011-06-11 20:44, Andrei Alexandrescu wrote:
 On 06/11/2011 04:42 PM, Jonathan M Davis wrote:
 On 2011-06-11 14:32, David Nadlinger wrote:
 On 6/11/11 11:20 PM, Jonathan M Davis wrote:
 1. Programmers following this idiom (including the Phobos devs) end
 up creating enums with yes and no values and are effectively
 identical to other enums except for their names. So, we end up with
 a fair bit of boilerplate code just to pass a strict boolean value.

s/fair/tiny/, imho: --- /// ditto. enum SomeFlag { enable, disable } ---

It's a fair bit only insomuch as the same code is duplicated in several places. The code itself in each instance is small. But if you do that enough times, it adds up. Whether it's enough to matter is debatable, but there is definitely boilerplate code there which could be reduced. - Jonathan M Davis

It's the namespace pollution and the non-self-containedness of the function that's most troublesome. Also see Steve's point about methods. It's just untenable - to use the idiom with a class/struct method, you need to go all the way _outside_ of it an plant a symbol there. What I find most interesting is that the lack of strong counterarguments has not stood in the way of a strong emotional response. This mood has made it difficult for exchange of rational arguments. Funny thing is, the change is tiny. "Here, I'll add a handful of yes/no enums here and there in the standard library, just to help some algorithms. More to come." "Yeah, sure, whatevs." "Here, there's a way to define them once so we don't need to define them everywhere." "Gaaaaaaaaaaaaaa!!!"

Honestly, at this point, I think that your proposal is pretty good, but I'm not sure that it's worth the degradation in error messages that the added templatization causes. But for a lot of people, I think that it's simply a combination of them not liking the yes/no enum idiom in the first place and/or feeling like what they really want is named parameters and that this really should be solved by named parameters. So, they don't like it. Personally, I'm a bit ambivalent towards yes/no enums, but I'm fine with having them. At this point, I'm just concerned about the worse error messages that the use of Flag will create and whether that pain is worth the added benefit that Flag brings.

Yikes! How did that get posted three times?! I wonder if my mail client is on the fritz... - Jonathan M Davis
Jun 11 2011
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message 
news:it1cvf$21d4$1 digitalmars.com...
 It's the namespace pollution and the non-self-containedness of the 
 function that's most troublesome. Also see Steve's point about methods. 
 It's just untenable - to use the idiom with a class/struct method, you 
 need to go all the way _outside_ of it an plant a symbol there.

You can't put an enum in a class/struct?
 What I find most interesting is that the lack of strong counterarguments 
 has not stood in the way of a strong emotional response.

Correction: Andrei's staunch dismissal of all counterarguments has not stood in the way of a strong emotional response.
 This mood has made it difficult for exchange of rational arguments. Funny 
 thing is, the change is tiny.

 "Here, I'll add a handful of yes/no enums here and there in the standard 
 library, just to help some algorithms. More to come."

 "Yeah, sure, whatevs."

 "Here, there's a way to define them once so we don't need to define them 
 everywhere."

Correction: "Here, there's a way to solve a barely-existant problem by botching up syntax (and error messages) for the user."
 "Gaaaaaaaaaaaaaa!!!"

Jun 12 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/12/11 1:59 PM, Nick Sabalausky wrote:
 "Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org>  wrote in message
 news:it1cvf$21d4$1 digitalmars.com...
 It's the namespace pollution and the non-self-containedness of the
 function that's most troublesome. Also see Steve's point about methods.
 It's just untenable - to use the idiom with a class/struct method, you
 need to go all the way _outside_ of it an plant a symbol there.

You can't put an enum in a class/struct?
 What I find most interesting is that the lack of strong counterarguments
 has not stood in the way of a strong emotional response.

Correction: Andrei's staunch dismissal of all counterarguments has not stood in the way of a strong emotional response.
 This mood has made it difficult for exchange of rational arguments. Funny
 thing is, the change is tiny.

 "Here, I'll add a handful of yes/no enums here and there in the standard
 library, just to help some algorithms. More to come."

 "Yeah, sure, whatevs."

 "Here, there's a way to define them once so we don't need to define them
 everywhere."

Correction: "Here, there's a way to solve a barely-existant problem by botching up syntax (and error messages) for the user."
 "Gaaaaaaaaaaaaaa!!!"


I'm not sure, but I think I see a sarcasm in there. Andrei
Jun 12 2011
parent "Nick Sabalausky" <a a.a> writes:
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message 
news:it32kq$2gfq$2 digitalmars.com...
 On 6/12/11 1:59 PM, Nick Sabalausky wrote:
 "Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org>  wrote in message
 news:it1cvf$21d4$1 digitalmars.com...
 It's the namespace pollution and the non-self-containedness of the
 function that's most troublesome. Also see Steve's point about methods.
 It's just untenable - to use the idiom with a class/struct method, you
 need to go all the way _outside_ of it an plant a symbol there.

You can't put an enum in a class/struct?
 What I find most interesting is that the lack of strong counterarguments
 has not stood in the way of a strong emotional response.

Correction: Andrei's staunch dismissal of all counterarguments has not stood in the way of a strong emotional response.
 This mood has made it difficult for exchange of rational arguments. 
 Funny
 thing is, the change is tiny.

 "Here, I'll add a handful of yes/no enums here and there in the standard
 library, just to help some algorithms. More to come."

 "Yeah, sure, whatevs."

 "Here, there's a way to define them once so we don't need to define them
 everywhere."

Correction: "Here, there's a way to solve a barely-existant problem by botching up syntax (and error messages) for the user."
 "Gaaaaaaaaaaaaaa!!!"


I'm not sure, but I think I see a sarcasm in there.

I guess it could be taken that way, but it wasn't really my point to be sarcastic. My intent was just to summarize the way I see the situation.
Jun 12 2011
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/11/11 8:49 PM, Steven Schveighoffer wrote:
 On Sat, 11 Jun 2011 17:32:56 -0400, David Nadlinger <see klickverbot.at>
 wrote:

 On 6/11/11 11:20 PM, Jonathan M Davis wrote:
 1. Programmers following this idiom (including the Phobos devs) end up
 creating enums with yes and no values and are effectively identical
 to other
 enums except for their names. So, we end up with a fair bit of
 boilerplate
 code just to pass a strict boolean value.

s/fair/tiny/, imho: --- /// ditto. enum SomeFlag { enable, disable } ---

A big problem with this (and enums in general), what if your flag function is defined inside a struct or class? struct MyStruct { /// This function ROCKS! void someKickAssFunction(MoreBitchin moreBitchin) {} /// ditto enum MoreBitchin { yes, no } } // the call, not so much. s.someKickAssFunction(MyStruct.MoreBitchin.yes); In other words, in order for your doc trick to work, member functions have to require an additional namespace to the enum. IMO, however, we need a better way to access the enum values without specifying the entire namespace. The difficult part is to do it in a way which doesn't conflict with normal symbols. Of course, such an improvement would pull the rug from this Flag proposal... -Steve

Thanks, Steve, this is an excellent point - as are all you made in this discussion (pro and con)! Andrei
Jun 12 2011
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
Jonathan M Davis wrote:
 ...
 The complaints about this generally seem to be one of these:

 1. Dislike of the yes/no enum idiom in the first place. Regardless of how Flag
 does it, it's a problem, because it's promoting an idiom that the poster
 dislikes in the first place.

 2. Flag!"enumName".yes and Flag!"enumName".no are ugly.

 3. The use of a template such as Flag results in ugly error messages when it's
 mistyped. EnumName.yes gets _much_ better errors when mistyped than
 Flag!"enumName".yes.

 4. Flag is seen as a narrow attempt at named arguments which would be far
 better served by actually implementing named arguments.
 [snip.]

5. The approach is too sophisticated and does not pull its own weight. Imagine what you would have to explain to somebody new to the language who wondered how Yes.sortOutput works... instant turn-off! What about allowing anonymous enums in parameter lists? Unfortunately that would be a language feature. :) T someAlgorithm(..., enum {unsorted, sorted} sortOutput); To call: someAlgorithm(..., sorted); / someAlgorithm(..., unsorted); Timon
Jun 11 2011
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 06/11/2011 04:58 PM, Timon Gehr wrote:
 Jonathan M Davis wrote:
 ...
 The complaints about this generally seem to be one of these:

 1. Dislike of the yes/no enum idiom in the first place. Regardless of how Flag
 does it, it's a problem, because it's promoting an idiom that the poster
 dislikes in the first place.

 2. Flag!"enumName".yes and Flag!"enumName".no are ugly.

 3. The use of a template such as Flag results in ugly error messages when it's
 mistyped. EnumName.yes gets _much_ better errors when mistyped than
 Flag!"enumName".yes.

 4. Flag is seen as a narrow attempt at named arguments which would be far
 better served by actually implementing named arguments.
 [snip.]

5. The approach is too sophisticated and does not pull its own weight. Imagine what you would have to explain to somebody new to the language who wondered how Yes.sortOutput works... instant turn-off! What about allowing anonymous enums in parameter lists? Unfortunately that would be a language feature. :) T someAlgorithm(..., enum {unsorted, sorted} sortOutput); To call: someAlgorithm(..., sorted); / someAlgorithm(..., unsorted);

I proposed this to Walter some years ago, around the time I was anticipating the nascent yes/no enum proliferation. The problem with this is it defines a type in a function parameter specification, which is unprecedented and therefore surprising. There's a closely related slide in our D 2007 conference talk. Andrei
Jun 11 2011
parent "Nick Sabalausky" <a a.a> writes:
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message 
news:it1cd7$1vv2$1 digitalmars.com...
 On 06/11/2011 04:58 PM, Timon Gehr wrote:
 Jonathan M Davis wrote:
 ...
 The complaints about this generally seem to be one of these:

 1. Dislike of the yes/no enum idiom in the first place. Regardless of 
 how Flag
 does it, it's a problem, because it's promoting an idiom that the poster
 dislikes in the first place.

 2. Flag!"enumName".yes and Flag!"enumName".no are ugly.

 3. The use of a template such as Flag results in ugly error messages 
 when it's
 mistyped. EnumName.yes gets _much_ better errors when mistyped than
 Flag!"enumName".yes.

 4. Flag is seen as a narrow attempt at named arguments which would be 
 far
 better served by actually implementing named arguments.
 [snip.]

5. The approach is too sophisticated and does not pull its own weight. Imagine what you would have to explain to somebody new to the language who wondered how Yes.sortOutput works... instant turn-off! What about allowing anonymous enums in parameter lists? Unfortunately that would be a language feature. :) T someAlgorithm(..., enum {unsorted, sorted} sortOutput); To call: someAlgorithm(..., sorted); / someAlgorithm(..., unsorted);


I like the basic idea, and it's a change that falls into the "removing restrictions" category. But the issue "so" brought up with this about not being able to pass in a variable would need to be solved for the general case. It's trivial in the case of two options: bool useSorted = ...; someAlgorithm(..., useSorted? sorted : unsorted); Although, really, that just shifts the boilerplate from the callee to the caller, so it's really a net loss. You could maybe do: T someAlgorithm(..., enum Sorted {yes, no} sortOutput); Which would be equivalent to: enum Sorted {yes, no} T someAlgorithm(..., Sorted sortOutput); But I don't now if Andrei would like that (it makes the func signature kinda verbose, too).
 I proposed this to Walter some years ago, around the time I was 
 anticipating the nascent yes/no enum proliferation. The problem with this 
 is it defines a type in a function parameter specification, which is 
 unprecedented and therefore surprising.

Your Flag idiom essentially defines a type in a function parameter specification.
Jun 12 2011
prev sibling next sibling parent "Daniel Murphy" <yebblies nospamgmail.com> writes:
"Timon Gehr" <timon.gehr gmx.ch> wrote in message 
news:it0oee$ehu$1 digitalmars.com...
 What about allowing anonymous enums in parameter lists? Unfortunately that 
 would
 be a language feature. :)

 T someAlgorithm(..., enum {unsorted, sorted} sortOutput);

 To call: someAlgorithm(..., sorted); / someAlgorithm(..., unsorted);

Wow - I actually really like this! It would provide an even _better_ solution than named arguments for this type of thing! The best part is that it could degrade to the enum's base type when taking a function pointer, mangling the function's name and even inside the function's body! void myfunction(enum : int { option1, option2, option3 } options) { static assert(is(typeof(options) == int)); } static assert(is(typeof(&myfunction) == void function(int)); myfunction(option2);
Jun 12 2011
prev sibling parent "Nick Sabalausky" <a a.a> writes:
"Timon Gehr" <timon.gehr gmx.ch> wrote in message 
news:it0oee$ehu$1 digitalmars.com...
 Jonathan M Davis wrote:
 ...
 The complaints about this generally seem to be one of these:

 1. Dislike of the yes/no enum idiom in the first place. Regardless of how 
 Flag
 does it, it's a problem, because it's promoting an idiom that the poster
 dislikes in the first place.

 2. Flag!"enumName".yes and Flag!"enumName".no are ugly.

 3. The use of a template such as Flag results in ugly error messages when 
 it's
 mistyped. EnumName.yes gets _much_ better errors when mistyped than
 Flag!"enumName".yes.

 4. Flag is seen as a narrow attempt at named arguments which would be far
 better served by actually implementing named arguments.
 [snip.]

5. The approach is too sophisticated and does not pull its own weight. Imagine what you would have to explain to somebody new to the language who wondered how Yes.sortOutput works... instant turn-off!

Not only that, but just simply trying to explain why you sometimes do "enumName.value" and sometimes do "value.enumName". It introduces a big inconsistency for callers, just for the sake of a trivial decrease in boilerplate for the callee. Also, one thing I'm unclear on: If you do: void foo(Flag!"bar" a) {} Can the caller do something like this?: bar barValue = yes.bar; foo(barValue);
Jun 12 2011
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 06/11/2011 04:20 PM, Jonathan M Davis wrote:
 2. He proposed a template wrapper which would allow you to type yes!"enumName"
 and no!"enumName" instead of the full Flag!"enumName".yes and
 Flag!"enumName".no. Some people feel that this resolves complaint #2. Others
 think that it's still quite ugly.

Those were since replaced with No.enumName and Yes.enumName by Dmitry's idea: https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0b608895269bdccba4330 Andrei
Jun 11 2011
parent reply KennyTM~ <kennytm gmail.com> writes:
On Jun 12, 11 11:18, Andrei Alexandrescu wrote:
 On 06/11/2011 04:20 PM, Jonathan M Davis wrote:
 2. He proposed a template wrapper which would allow you to type
 yes!"enumName"
 and no!"enumName" instead of the full Flag!"enumName".yes and
 Flag!"enumName".no. Some people feel that this resolves complaint #2.
 Others
 think that it's still quite ugly.

Those were since replaced with No.enumName and Yes.enumName by Dmitry's idea: https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0b608895269bdccba4330 Andrei

Yes.X and No.X looks grammatically wrong. In D you usually have 'Aggregate.member', not 'Member.aggregate'.
Jun 11 2011
parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 12.06.2011 10:31, KennyTM~ wrote:
 On Jun 12, 11 11:18, Andrei Alexandrescu wrote:
 On 06/11/2011 04:20 PM, Jonathan M Davis wrote:
 2. He proposed a template wrapper which would allow you to type
 yes!"enumName"
 and no!"enumName" instead of the full Flag!"enumName".yes and
 Flag!"enumName".no. Some people feel that this resolves complaint #2.
 Others
 think that it's still quite ugly.

Those were since replaced with No.enumName and Yes.enumName by Dmitry's idea: https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0 608895269bdccba4330 Andrei

Yes.X and No.X looks grammatically wrong. In D you usually have 'Aggregate.member', not 'Member.aggregate'.

Personally, I think the biggest stumbling block is error messages, maybe we can do something about them. Like make Flag struct with alias this and provide this(Flag!s) constructor, opAssign etc. that static assert something sensible on mismatch. -- Dmitry Olshansky
Jun 12 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-06-11 14:32, David Nadlinger wrote:
 On 6/11/11 11:20 PM, Jonathan M Davis wrote:
 1. Programmers following this idiom (including the Phobos devs) end up
 creating enums with yes and no values and are effectively identical to
 other enums except for their names. So, we end up with a fair bit of
 boilerplate code just to pass a strict boolean value.

s/fair/tiny/, imho: --- /// ditto. enum SomeFlag { enable, disable } ---

It's a fair bit only insomuch as the same code is duplicated in several places. The code itself in each instance is small. But if you do that enough times, it adds up. Whether it's enough to matter is debatable, but there is definitely boilerplate code there which could be reduced. - Jonathan M Davis
Jun 11 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sat, 11 Jun 2011 17:32:56 -0400, David Nadlinger <see klickverbot.at>  
wrote:

 On 6/11/11 11:20 PM, Jonathan M Davis wrote:
 1. Programmers following this idiom (including the Phobos devs) end up
 creating enums with yes and no values and are effectively identical to  
 other
 enums except for their names. So, we end up with a fair bit of  
 boilerplate
 code just to pass a strict boolean value.

s/fair/tiny/, imho: --- /// ditto. enum SomeFlag { enable, disable } ---

A big problem with this (and enums in general), what if your flag function is defined inside a struct or class? struct MyStruct { /// This function ROCKS! void someKickAssFunction(MoreBitchin moreBitchin) {} /// ditto enum MoreBitchin { yes, no } } // the call, not so much. s.someKickAssFunction(MyStruct.MoreBitchin.yes); In other words, in order for your doc trick to work, member functions have to require an additional namespace to the enum. IMO, however, we need a better way to access the enum values without specifying the entire namespace. The difficult part is to do it in a way which doesn't conflict with normal symbols. Of course, such an improvement would pull the rug from this Flag proposal... -Steve
Jun 11 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-06-11 20:44, Andrei Alexandrescu wrote:
 On 06/11/2011 04:42 PM, Jonathan M Davis wrote:
 On 2011-06-11 14:32, David Nadlinger wrote:
 On 6/11/11 11:20 PM, Jonathan M Davis wrote:
 1. Programmers following this idiom (including the Phobos devs) end up
 creating enums with yes and no values and are effectively identical to
 other enums except for their names. So, we end up with a fair bit of
 boilerplate code just to pass a strict boolean value.

s/fair/tiny/, imho: --- /// ditto. enum SomeFlag { enable, disable } ---

It's a fair bit only insomuch as the same code is duplicated in several places. The code itself in each instance is small. But if you do that enough times, it adds up. Whether it's enough to matter is debatable, but there is definitely boilerplate code there which could be reduced. - Jonathan M Davis

It's the namespace pollution and the non-self-containedness of the function that's most troublesome. Also see Steve's point about methods. It's just untenable - to use the idiom with a class/struct method, you need to go all the way _outside_ of it an plant a symbol there. What I find most interesting is that the lack of strong counterarguments has not stood in the way of a strong emotional response. This mood has made it difficult for exchange of rational arguments. Funny thing is, the change is tiny. "Here, I'll add a handful of yes/no enums here and there in the standard library, just to help some algorithms. More to come." "Yeah, sure, whatevs." "Here, there's a way to define them once so we don't need to define them everywhere." "Gaaaaaaaaaaaaaa!!!"

Honestly, at this point, I think that your proposal is pretty good, but I'm not sure that it's worth the degradation in error messages that the added templatization causes. But for a lot of people, I think that it's simply a combination of them not liking the yes/no enum idiom in the first place and/or feeling like what they really want is named parameters and that this really should be solved by named parameters. So, they don't like it. Personally, I'm a bit ambivalent towards yes/no enums, but I'm fine with having them. At this point, I'm just concerned about the worse error messages that the use of Flag will create and whether that pain is worth the added benefit that Flag brings. - Jonathan M Davis
Jun 11 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 6/12/11, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:
 Funny thing is,
 the change is tiny.

You seem to be forgetting that there are library writers and then there are library *users*. :) Seeing Flag!"foo".yes in the calling code scared people. So naturally people wanted to nuke it from orbit. If the proposal was yes.foo from the beginning things would much quieter around here, methinks.
Jun 11 2011
prev sibling next sibling parent so <so so.so> writes:
 It's the namespace pollution and the non-self-containedness of the  
 function that's most troublesome. Also see Steve's point about methods.  
 It's just untenable - to use the idiom with a class/struct method, you  
 need to go all the way _outside_ of it an plant a symbol there.

 What I find most interesting is that the lack of strong counterarguments  
 has not stood in the way of a strong emotional response. This mood has  
 made it difficult for exchange of rational arguments. Funny thing is,  
 the change is tiny.

 "Here, I'll add a handful of yes/no enums here and there in the standard  
 library, just to help some algorithms. More to come."

 "Yeah, sure, whatevs."

 "Here, there's a way to define them once so we don't need to define them  
 everywhere."

 "Gaaaaaaaaaaaaaa!!!"


 Andrei

(Trying the 3rd time, something wrong with newsreader) As you might know i prefer library solutions to language changes any day even the change is additive, yet this one i don't like. Library solutions, especially those affect user must be IMO both elegant and generic, this one is not. I think we are agree on this. There might be 7 in only std.algorithm but it is after all belongs to the std library, with the importance of phobos we can't change anything that is not accepted by majority. These are i think pretty strong arguments, though i believe it is you that needs to come up with strong arguments and i can't see any from you either :) Introducing an idiom to phobos means it is the D way, there should be many other frameworks that would use such a solution much more frequently. They will either dismiss this solution (most likely) or populate it. The former means the failure of the change, the latter is ugly code (again, when it is used more frequently). Named arguments both clean and generic. On one drawback (?) that variable names being part of library definition, i don't see how it is a drawback.
Jun 12 2011
prev sibling next sibling parent so <so so.so> writes:
On Sun, 12 Jun 2011 15:33:00 +0300, Daniel Murphy  
<yebblies nospamgmail.com> wrote:

 "Timon Gehr" <timon.gehr gmx.ch> wrote in message
 news:it0oee$ehu$1 digitalmars.com...
 What about allowing anonymous enums in parameter lists? Unfortunately  
 that
 would
 be a language feature. :)

 T someAlgorithm(..., enum {unsorted, sorted} sortOutput);

 To call: someAlgorithm(..., sorted); / someAlgorithm(..., unsorted);

Wow - I actually really like this! It would provide an even _better_ solution than named arguments for this type of thing! The best part is that it could degrade to the enum's base type when taking a function pointer, mangling the function's name and even inside the function's body! void myfunction(enum : int { option1, option2, option3 } options) { static assert(is(typeof(options) == int)); } static assert(is(typeof(&myfunction) == void function(int)); myfunction(option2);

This also means you can use it only once. Not knowing the type, you can't pass as a variable either. The loss is too big compared to the gain. fun_step_one(enum whatever) fun_step_two(enum?) enum type? val fun(val)
Jun 12 2011
prev sibling parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
On Sun, 12 Jun 2011 14:59:57 -0400, Nick Sabalausky wrote:

 "Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message
 news:it1cvf$21d4$1 digitalmars.com...
 It's the namespace pollution and the non-self-containedness of the
 function that's most troublesome. Also see Steve's point about methods.
 It's just untenable - to use the idiom with a class/struct method, you
 need to go all the way _outside_ of it an plant a symbol there.


Yes, but then you have to qualify it with the name of the class/struct when using it. See Steve's post: http://www.digitalmars.com/webnews/newsgroups.php? art_group=digitalmars.D&article_id=138281 -Lars
Jun 13 2011