digitalmars.D.bugs - [Issue 9924] New: Handy enum accessors
- d-bugmail puremagic.com (64/64) Apr 11 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9924
- d-bugmail puremagic.com (13/13) Apr 11 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9924
- d-bugmail puremagic.com (15/21) Apr 11 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9924
- d-bugmail puremagic.com (20/20) Apr 11 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9924
- d-bugmail puremagic.com (7/8) Apr 11 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9924
- d-bugmail puremagic.com (16/16) Apr 11 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9924
- d-bugmail puremagic.com (13/14) Apr 12 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9924
- d-bugmail puremagic.com (12/14) Apr 12 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9924
- d-bugmail puremagic.com (8/8) Apr 12 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9924
- d-bugmail puremagic.com (8/8) Apr 12 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9924
http://d.puremagic.com/issues/show_bug.cgi?id=9924
Summary: Handy enum accessors
Product: D
Version: D2
Platform: All
OS/Version: All
Status: NEW
Severity: enhancement
Priority: P2
Component: Phobos
AssignedTo: nobody puremagic.com
ReportedBy: bearophile_hugs eml.cc
To better use enums I suggest to add to Phobos four small templates/functions
like this (similar things are builtins in Ada):
import std.conv: text;
import std.traits: EnumMembers;
template FirstMember(E) if (is(E == enum)) {
enum FirstMember = EnumMembers!E[0];
}
template LastMember(E) if (is(E == enum)) {
enum LastMember = EnumMembers!E[$ - 1];
}
E predMember(E)(E e) /*pure nothrow*/ if (is(E == enum))
in {
assert(e != FirstMember!E);
} body {
switch (e) {
foreach (i, e2; EnumMembers!E[1 .. $])
mixin("case E." ~ text(cast(E)e2) ~ ": return E."
~ text(cast(E)(EnumMembers!E[i])) ~ ";");
default: assert(0);
}
}
E nextMember(E)(E e) /*pure nothrow*/ if (is(E == enum))
in {
assert(e != LastMember!E);
} body {
switch (e) {
foreach (i, e2; EnumMembers!E[0 .. $ - 1])
mixin("case E." ~ text(cast(E)e2) ~ ": return E."
~ text(cast(E)(EnumMembers!E[i + 1])) ~ ";");
default: assert(0);
}
}
void main() { // Demo -----------------------
import std.stdio;
enum Choice { rock, paper, scissors }
static Choice whatBeats(in Choice ch) /*pure nothrow*/ {
if (ch == LastMember!Choice)
return FirstMember!Choice;
else
return nextMember(ch);
}
foreach (e; [EnumMembers!Choice])
writeln(e, " ", whatBeats(e));
writeln(predMember(Choice.paper));
writeln(predMember(Choice.scissors));
writeln(nextMember(Choice.rock));
writeln(nextMember(Choice.paper));
}
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 11 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9924
Walter Bright <bugzilla digitalmars.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |bugzilla digitalmars.com
18:04:42 PDT ---
I don't see much need for FirstMember and LastMember, just as I don't see a
need for:
E FirstElement(E)(E[] a) { return a[0]; }
I believe such functions are trivia.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 11 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9924
I don't see much need for FirstMember and LastMember, just as I don't see a
need for:
E FirstElement(E)(E[] a) { return a[0]; }
I believe such functions are trivia.
Maybe you are right, I am not sure.
But note FirstElement is present in Phobos, it's named std.array.front:
property ref T front(T)(T[] a)
if (!isNarrowString!(T[]) && !is(T[] == void[]))
{
assert(a.length, "Attempting to fetch the front of an empty array of " ~
T.stringof);
return a[0];
}
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 11 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9924
If you remove FirstMember and LastMember the whatBeats() function:
static Choice whatBeats(in Choice ch) /*pure nothrow*/ {
if (ch == LastMember!Choice)
return FirstMember!Choice;
else
return nextMember(ch);
}
Becomes:
static Choice whatBeats(in Choice ch) /*pure nothrow*/ {
if (ch == EnumMembers!Choice[$ - 1])
return EnumMembers!Choice[0];
else
return nextMember(ch);
}
It's more noisy, and visually it's a little less easy to tell it's correct.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 11 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9924 19:37:02 PDT ---But note FirstElement is present in Phobos, it's named std.array.front:front() is there to support ranges, it is not a shorthand for [0]. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 11 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9924 19:47:44 PDT --- For similar reasons, I don't see a compelling case for nextMember or prevMember, either. I expect that an algorithm needing the next or previous member would be looping over EnumMembers!E[i] anyway. Such functions do not make code clearer, they obfuscate it behind trivia. The user wastes time wondering "should I use first(), or [0]? Why are there both? Is there a difference?" The documentation fills up with this pointless ephemera. A well designed interface should have a *minimum* of concepts and methods. They should ideally all be orthogonal, with zero overlap. I don't know Ada, but I suspect it has these methods because it does not have the [i] way of getting at enum members. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 11 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9924front() is there to support ranges, it is not a shorthand for [0].I don't agree. In the last year and half I have written two times by mistake: return items[$]; instead of: return items[$ - 1]; Now I usully use this, and avoid the problem, and it works even if later items becomes a range: return items.back; -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 12 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9924
bearophile_hugs eml.cc changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |RESOLVED
Resolution| |FIXED
For similar reasons, I don't see a compelling case for nextMember or
prevMember, either.
OK, I close this ER down.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 12 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9924
bearophile_hugs eml.cc changed:
What |Removed |Added
----------------------------------------------------------------------------
Resolution|FIXED |WONTFIX
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 12 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9924
bearophile_hugs eml.cc changed:
What |Removed |Added
----------------------------------------------------------------------------
Resolution|WONTFIX |INVALID
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 12 2013









d-bugmail puremagic.com 