Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
June 19, 2012 D: Unexpected output when using a delegate and EnumMembers | ||||
---|---|---|---|---|
| ||||
Attachments: | I have some rather odd behavior in my D program that I've narrowed down to this: import std.algorithm; import std.stdio; import std.traits; enum E { a, b, c }; struct S { E e; }; void main() { immutable(S)[] source = [ S(E.a), S(E.a), S(E.b) ]; foreach (e; EnumMembers!E) { size_t c = count!(x => x.e == e)(source); writeln(e, " -> ", c); } } I would expect the output of this program to be something along the lines of: a -> 2 b -> 1 c -> 0 But the actual result is: a -> 2 b -> 2 c -> 2 Curiously, changing the for loop to foreach (e; [ E.a, E.b, E.c ]) produces my expected output. Using foreach (e; [ EnumMembers!E ]) also produces my expected result, so clearly my use of the range from EnumMemebers is the problem here...I just don't know why. By moving the count call to a separate function: size_t counte(Range)(E e, Range src) { return count!(x => x.e == e)(src); } and changing c's initialization to size_t c = counte(e, source);, the program works as I would expect. I am clearly doing something wrong, but I have no idea what and would appreciate some insight. My compiler is DMD64 D Compiler v2.059 on Linux. |
June 19, 2012 Re: D: Unexpected output when using a delegate and EnumMembers | ||||
---|---|---|---|---|
| ||||
Posted in reply to Travis Gockel | On 06/19/12 16:44, Travis Gockel wrote: > import std.algorithm; > import std.stdio; > import std.traits; > > enum E { a, b, c }; > > struct S { E e; }; > > void main() > { > immutable(S)[] source = [ S(E.a), S(E.a), S(E.b) ]; > foreach (e; EnumMembers!E) > { > size_t c = count!(x => x.e == e)(source); > writeln(e, " -> ", c); > } > } > > I would expect the output of this program to be something along the lines of: > > a -> 2 > b -> 1 > c -> 0 > > But the actual result is: > > a -> 2 > b -> 2 > c -> 2 > > Curiously, changing the for loop to foreach (e; [ E.a, E.b, E.c ]) produces my expected output. Using foreach (e; [ EnumMembers!E ]) also produces my expected result, so clearly my use of the range from EnumMemebers is the problem here...I just don't know why. > > By moving the count call to a separate function: > > size_t counte(Range)(E e, Range src) > { > return count!(x => x.e == e)(src); > } > > and changing c's initialization to size_t c = counte(e, source);, the program works as I would expect. > > I am clearly doing something wrong, but I have no idea what and would appreciate some insight. Yes, it can be surprising, but I'm not convinced it's actually wrong behavior (the bug is http://d.puremagic.com/issues/show_bug.cgi?id=2043) Just do this: size_t c = count!(function(x, e) { return x.e == e;} )(source, e); and it will work. [1] artur [1] I don't do that new kinky lambda syntax, sorry. ;) |
June 19, 2012 Re: D: Unexpected output when using a delegate and EnumMembers | ||||
---|---|---|---|---|
| ||||
Posted in reply to Travis Gockel | On 06/19/2012 04:44 PM, Travis Gockel wrote: > > I am clearly doing something wrong, You are not. > but I have no idea what and would > appreciate some insight. > You have found a bug in DMD. Reduced test case that should compile: template Seq(T...){alias T Seq;} auto exec(alias a)(){return a();} void main(){ foreach(e; Seq!(0, 1)) static assert(exec!(()=>e)()==e); } You can report the bug here: http://d.puremagic.com/issues/ The 'exec' template is instantiated only once instead of two times. |
June 19, 2012 Re: D: Unexpected output when using a delegate and EnumMembers | ||||
---|---|---|---|---|
| ||||
Posted in reply to Artur Skawina | On 06/19/2012 05:08 PM, Artur Skawina wrote: > > Yes, it can be surprising, but I'm not convinced it's actually wrong > behavior (the bug is http://d.puremagic.com/issues/show_bug.cgi?id=2043) > It is not this bug. (And what is listed there is clearly wrong behaviour, because it can be used to break the type system.) > Just do this: > > size_t c = count!(function(x, e) { return x.e == e;} )(source, e); > > and it will work. [1] > > artur > > [1] I don't do that new kinky lambda syntax, sorry. ;) Your embarrassment about this issue is justifiable. |
June 19, 2012 Re: D: Unexpected output when using a delegate and EnumMembers | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | == Quote from Timon Gehr (timon.gehr@gmx.ch)'s article > You can report the bug here: http://d.puremagic.com/issues/ > The 'exec' template is instantiated only once instead of two times. Reported: http://d.puremagic.com/issues/show_bug.cgi?id=8267 |
June 19, 2012 Re: D: Unexpected output when using a delegate and EnumMembers | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 06/19/12 17:32, Timon Gehr wrote: > On 06/19/2012 05:08 PM, Artur Skawina wrote: >> >> Yes, it can be surprising, but I'm not convinced it's actually wrong behavior (the bug is http://d.puremagic.com/issues/show_bug.cgi?id=2043) >> > > It is not this bug. (And what is listed there is clearly wrong behaviour, because it can be used to break the type system.) It's not that simple. I remember considering the alternatives when I originally ran into this, and they have problems too. The "static foreach" case may be special, possibly. >> [1] I don't do that new kinky lambda syntax, sorry. ;) > > Your embarrassment about this issue is justifiable. > I'm proud of it. ;) But maybe it has something to do with the fact that my compiler doesn't support them... artur |
Copyright © 1999-2021 by the D Language Foundation