A fair amount of code in std uses this idiom:
enum SomeOption { no, yes }
void someFunction(...parms..., SomeOption, ...more_parms...) { ... }
SomeOption is really a Boolean but replaces the unhelpful call syntax
someFunction(...args..., false, ...more_args...) with the
self-documenting ...args..., SomeOption,no, ...more_args...).
The liabilities of using Booleans for describing flags have been
documented in several places, including McConnell's Code Complete. I
think the idiom above is a good replacement.
One issue I have with it is that it requires separate definition and
documentation. Usually the documentation awkwardly states "This type is
really an option for someFunction, which you haven't seen yet. Skip this
for now, then get back, and you'll understand." Moving the enum to after
the function is possible but equally confusing.
So I was thinking of planting a simple template in std.typecons:
template YesOrNo(string name)
{
mixin("enum "~name~" : bool { no, yes }");
}
That way, the definition of the function needs no separately-defined is
self-documenting:
void someFunction(...parms..., YesOrNo!"SomeOption", ...) { ... }
The question is to what extent this would mark progress and fostering
structured use of this idiom, versus just confusing beginners and adding
deadweight to Phobos.
Andrei

It looks like an awkward workaround for that feature called named
arguments.

Named arguments aren't a part of standard D now, nor does it look
likely they will be for many years.
We've gotta look at the here and now to make decisions; focus
on what we have rather than what we don't have.

It looks like an awkward workaround for that feature called named
arguments.

Named arguments aren't a part of standard D now, nor does it look
likely they will be for many years.
We've gotta look at the here and now to make decisions; focus
on what we have rather than what we don't have.

Well the same argument was used to reject assertPred in favor of an
improved assert which we still don't have (issue 5547). (Though changing
assert's output doesn't change the D spec, while adding named arguments
do, and the D2 spec is frozen.)

A fair amount of code in std uses this idiom:
enum SomeOption { no, yes }
void someFunction(...parms..., SomeOption, ...more_parms...) { ... }
SomeOption is really a Boolean but replaces the unhelpful call syntax
someFunction(...args..., false, ...more_args...) with the
self-documenting ...args..., SomeOption,no, ...more_args...).
The liabilities of using Booleans for describing flags have been
documented in several places, including McConnell's Code Complete. I
think the idiom above is a good replacement.
One issue I have with it is that it requires separate definition and
documentation. Usually the documentation awkwardly states "This type is
really an option for someFunction, which you haven't seen yet. Skip this
for now, then get back, and you'll understand." Moving the enum to after
the function is possible but equally confusing.
So I was thinking of planting a simple template in std.typecons:
template YesOrNo(string name)
{
mixin("enum "~name~" : bool { no, yes }");
}
That way, the definition of the function needs no separately-defined is
self-documenting:
void someFunction(...parms..., YesOrNo!"SomeOption", ...) { ... }
The question is to what extent this would mark progress and fostering
structured use of this idiom, versus just confusing beginners and adding
deadweight to Phobos.
Andrei

Named parameters fix this without the need for workarounds.
someFunction(...parms..., someOption=>true, ...more parms....);

A fair amount of code in std uses this idiom:
enum SomeOption { no, yes }
void someFunction(...parms..., SomeOption, ...more_parms...) { ... }
SomeOption is really a Boolean but replaces the unhelpful call syntax
someFunction(...args..., false, ...more_args...) with the
self-documenting ...args..., SomeOption,no, ...more_args...).
The liabilities of using Booleans for describing flags have been
documented in several places, including McConnell's Code Complete. I
think the idiom above is a good replacement.
One issue I have with it is that it requires separate definition and
documentation. Usually the documentation awkwardly states "This type
is really an option for someFunction, which you haven't seen yet. Skip
this for now, then get back, and you'll understand." Moving the enum
to after the function is possible but equally confusing.
So I was thinking of planting a simple template in std.typecons:
template YesOrNo(string name)
{
mixin("enum "~name~" : bool { no, yes }");
}
That way, the definition of the function needs no separately-defined
is self-documenting:
void someFunction(...parms..., YesOrNo!"SomeOption", ...) { ... }
The question is to what extent this would mark progress and fostering
structured use of this idiom, versus just confusing beginners and
adding deadweight to Phobos.

I presume the user side remains intact and it's just enum declaration
that got inculcated into the someFunction declaration, right? (I suspect
some folks on the NG might be puzzled by it so I'll try to clarify some
points)
Like:
someFunction(...,SomeOption.yes,...);
Then yes it marks certain progress, and I like it. BTW double definition
is also nicely solved (i.e. it would be the same template instance).
YesOrNo!"Direction" would be the same for all function dealing with
"Direction" parameter.
Then to save lives of novices reading API docs, we should have some nice
short memo about this idiom on the language page or even in the Phobos
module listing "common idioms" if we have lots of them, plus links to it
everywhere applicable.
--
Dmitry Olshansky

I make out the idea to be that, at the module or class level, you write
mixin YesOrNo!("SomeOption");
and then declare functions as, e.g.
void doSomething(SomeOption someOption);
and so calls to this function become self-documenting with
doSomething(SomeOption.yes);
The disadvantage is that a user of the library needs to look up SomeOption in
order to
find out what the possible values are, whereas everybody knows what the
possible values of
a bool are.
It's really a workaround for two things:
- named arguments
- strong typedefs
Stewart.

Also, I would rather name this template "choice". Maybe if people got
used to this word they would understand it when they see it in the
documentation before a function definition. E.g.:
http://codepad.org/9mrL6MOG or if the site is down:
https://gist.github.com/913926
Otherwise I have no idea how you can put a new type definition inside
of a function parameter and make it public? I'm kind of confused
here..

Also, I would rather name this template "choice". Maybe if people got
used to this word they would understand it when they see it in the
documentation before a function definition. E.g.:
http://codepad.org/9mrL6MOG or if the site is down:
https://gist.github.com/913926
Otherwise I have no idea how you can put a new type definition inside
of a function parameter and make it public? I'm kind of confused
here..

The idea, IIUC, is to avoid documenting that extra enum type. So, for
example,
TRange topNCopy(alias less = "a< b", SRange, TRange)
(SRange source, TRange target,
YesOrNo!"SortOutput" sorted = false);
and then we can call it as
topNCopy([1,3,5,2,4], result, SortOutput.yes);

But how do you make `SortOutput` known at the calling site?

Right. Andrei's template can't do it. My approach above is simply
declare an undocumented enum, and use YesOrNo as a tag to statically
ensure that enum can take 'no' and 'yes'.
I feel this using type just for documentation is bad.

Are we talking about readability in a code editor or just the website?
Because without some form of syntax highlighting the function headers
are almost unreadable from the website:
http://i.imgur.com/B5M6u.png
It's a wall of text.

It looks like an awkward workaround for that feature called named arguments.

True, but only for the case of yes/no; in this case only, the bool type
provides proper *constants* which *meaning* is obvious. Else, you need an enum
anyway, even with named args.
f = File(path="f.txt", mode=2);
Denis
--
_________________
vita es estrany
spir.wikidot.com

True, but only for the case of yes/no; in this case only, the bool type
provides proper *constants* which *meaning* is obvious. Else, you need an enum
anyway, even with named args.
f = File(path="f.txt", mode=2);

Right, in some cases I prefer an enum and in some cases a named argument.
Bye,
bearophile

A fair amount of code in std uses this idiom:
enum SomeOption { no, yes }
void someFunction(...parms..., SomeOption, ...more_parms...) { ... }
SomeOption is really a Boolean but replaces the unhelpful call syntax
someFunction(...args..., false, ...more_args...) with the self-documenting
...args..., SomeOption,no, ...more_args...).
The liabilities of using Booleans for describing flags have been
documented in several places, including McConnell's Code Complete. I think
the idiom above is a good replacement.

Named args are much better for this. No boilerplate needed. Of course,
without named args, yea, this idiom needs to be used.

One issue I have with it is that it requires separate definition and
documentation. Usually the documentation awkwardly states "This type is
really an option for someFunction, which you haven't seen yet. Skip this
for now, then get back, and you'll understand." Moving the enum to after
the function is possible but equally confusing.

So I was thinking of planting a simple template in std.typecons:
template YesOrNo(string name)
{
mixin("enum "~name~" : bool { no, yes }");
}
That way, the definition of the function needs no separately-defined is
self-documenting:
void someFunction(...parms..., YesOrNo!"SomeOption", ...) { ... }
The question is to what extent this would mark progress and fostering
structured use of this idiom, versus just confusing beginners and adding
deadweight to Phobos.

Not sure what I think, really. Although, I do think the fact there seems to
be a need for someting that complex just for a mere two-option setting is
more indication that named args are just a better approach. But since we're
stuck without that, I really don't know how I feel about this template. Umm,
if you need to add a third setting, then you're right back to using a
straight enum and making sure it's documentated sensibly. You could
generalize YesOrNo further, but I don't think's possible without making it
really ugly to use. So maybe it's better to just make sure there's a good
way to handle the documentation. If that turns out to require some new DDoc
feature, then so be it.

A fair amount of code in std uses this idiom:
enum SomeOption { no, yes }
void someFunction(...parms..., SomeOption, ...more_parms...) { ... }
SomeOption is really a Boolean but replaces the unhelpful call syntax
someFunction(...args..., false, ...more_args...) with the self-documenting
...args..., SomeOption,no, ...more_args...).
The liabilities of using Booleans for describing flags have been
documented in several places, including McConnell's Code Complete. I think
the idiom above is a good replacement.

Named args are much better for this. No boilerplate needed. Of course,
without named args, yea, this idiom needs to be used.

One issue I have with it is that it requires separate definition and
documentation. Usually the documentation awkwardly states "This type is
really an option for someFunction, which you haven't seen yet. Skip this
for now, then get back, and you'll understand." Moving the enum to after
the function is possible but equally confusing.

So I was thinking of planting a simple template in std.typecons:
template YesOrNo(string name)
{
mixin("enum "~name~" : bool { no, yes }");
}
That way, the definition of the function needs no separately-defined is
self-documenting:
void someFunction(...parms..., YesOrNo!"SomeOption", ...) { ... }
The question is to what extent this would mark progress and fostering
structured use of this idiom, versus just confusing beginners and adding
deadweight to Phobos.

Not sure what I think, really. Although, I do think the fact there seems to
be a need for someting that complex just for a mere two-option setting is
more indication that named args are just a better approach. But since we're
stuck without that, I really don't know how I feel about this template. Umm,
if you need to add a third setting, then you're right back to using a
straight enum and making sure it's documentated sensibly. You could
generalize YesOrNo further, but I don't think's possible without making it
really ugly to use. So maybe it's better to just make sure there's a good
way to handle the documentation. If that turns out to require some new DDoc
feature, then so be it.

I now think the same way.
Denis
--
_________________
vita es estrany
spir.wikidot.com