Nick Sabalausky Wrote: > I'm bringing this over here from a couple separate threads over on "D.learn" > (My "D1: Overloading across modules" and bearophile's "Enum equality test"). > > Background summary: > > bearophile: > > I'm looking for D2 rough edges. I've found that this D2 code > > compiles and doesn't assert at runtime: > > > > enum Foo { V1 = 10 } > > void main() { > > assert(Foo.V1 == 10); > > } > > > > But I think enums and integers are not the same type, > > and I don't want to see D code that hard-codes comparisons > > between enum instances and number literals, so I think an > > equal between an enum and an int has to require a cast: > > > > assert(cast(int)(Foo.V1) == 10); // OK > > He goes on to mention C++0x's "enum class" that, smartly, gets rid of that > implicit conversion nonsense. > > To put it simply, I agree with this even on mere principle. I'm convinced > that the current D behavior is a blatant violation of strong-typing and > smacks way too much of C's so-called "type system". > > But here's another reason to get rid it that I, quite coincidentally, > stumbled upon right about the same time: > > Me: > > In D1, is there any reason I should be getting an error on this?: > > > > // module A: > > enum FooA { fooA }; > > void bar(FooA x) {} > > > > // module B: > > import A; > > enum FooB { fooB }; > > void bar(FooB x) {} > > > > bar(FooB.fooB); // Error: A.bar conflicts with B.bar (WTF?) > > In the resulting discussion (which included a really hackish workaround), it > was said that this is because of a rule (that I assume exists in D2 as well) > that basically goes "two functions from different modules are in conflict if > they have the same name." I assume (and very much hope) that the rule also > has a qualification "...but only if implicit conversion rules make it > possible for one to hijack the other". > > It was said that this is to prevent a function call from getting hijacked by > merely importing a module (or making a change in an imported module). That I > can completely agree with. But I couldn't understand why this would cause > conflicts involving enums until I thought about implicit enum-to-base-type > conversion and came up with this scenario: > > // Module Foo: > enum Foo { foo } > > // module A: > import Foo; > void bar(Foo x){} > > // module B version 1: > import Foo; // Note: A is not imported yet > void bar(int x){} > bar(Foo.foo); // Stupid crap that should never be allowed in the first place > > // module B version 2: > import Foo; > import A; // <- This line added > void bar(int x){} > bar(Foo.foo); // Now that conflict error *cough* "helps". > > So thanks to the useless and dangerous ability to implicitly convert an enum > to its base type, we can't have certain perfectly sensible cross-module > overloads. > > Although, frankly, I *still* don't see why "bar(SomeEnum)" and > "bar(SomeOtherEnum)" should ever be in conflict (unless that's only D1, or > if implicit base-type-to-enum conversions are allowed (which would make > things even worse)). > >
Hum... +1 What can I add, you said it all ;)