On Friday, March 17, 2017 10:25:22 Andrei Alexandrescu via Digitalmars-d wrote: > On 3/17/17 12:42 AM, Jonathan M Davis via Digitalmars-d wrote: > > And > > checking isSomeString with an enum is perfectly valid. It's just that > > we'd like it to be false, whereas right now it's true. > > That hasn't been the case for long, and there can't be many designs > relying on that. I think this is one of those places where we can break > compatibility if there's enough reason. -- Andrei
Actually, it's been that way for years (since at least 2012), and I suspect that it's been that way since the beginning, since it would need to explicitly check for enums to not work with enums thanks to the fact that it checks for implicit conversion and then disallows the implicit conversions that we don't want (like for static arrays and user-defined types). And sadly, when Kenji tried to fix it, I argued against it, because I didn't understand the issue well enough: https://issues.dlang.org/show_bug.cgi?id=8508 At the time, I thought that we needed isSomeString to be true for enums in order to be able to templatize functions that took string, whereas that's actually a bad idea, because then you didn't actually convert the enum to a string, and the function is in serious risk of doing the wrong thing with enums (either by not compiling or by resulting in a value that's not a valid enum value but still has the enum's type), though it will work in some cases. Also, templatizing the function and checking isSomeString breaks code anyway, because then it doesn't accept static arrays or user-defined types that implicitly convert to string, whereas it did before. And as discussed in this thread, as far as I can tell, in the general case, the only way to safely templatize a function that took a string is to include an overload that templatizes on the character type so that the implicit conversion is done at the call site. Given all of that, it was ignorant and ultimately detrimental of me to argue to that isSomeString needed to be true for enums, and it's been that way for several years at least. If I'd been smarter at the time, this would have been fixed years ago. However, in most cases, I would expect that fixing isSomeString to be false for enums would simply work. Anything range-based wouldn't care, because enums don't pass isInputRange anyway, and a decent chunk of the time, using an enum in place of a string would result in a compilation error, which means that that code wouldn't be broken but would instead catch the enum at the template constraint instead of not compiling when the template is instantiated. Really, the only code that we'd be at risk of breaking would be code that was written with the full understanding that enums passed isSomeString and did something like auto foo(S)(S str) if(isSomeString!S) { static if(is(T == enum)) return foo!(StringTypeOf!T)(str); else { ... } } or that just so happens to use the subset of string transformations or function calls which work with enums. So, if we don't fix isSomeString, and we want our code to be fully correct, we're left with the need to check is(T == enum) in non-range-based code in order to correctly handle enums (as in the example above or by disallowing enums) or risk code not compiling or being subtly incorrect when enums are used with it. And if we do fix isSomeString, then we'll probably have an occasional function call that happened to work with enums in spite of the problems and would then break - though the breakage would then be easy to fix. So, I would love to fix isSomeString, and I think that the resulting breakage would be minimal, but I don't expect it to be zero. So, if you think that that presumably small amount of code breakage is acceptable, I would gladly create a PR to fix isSomeString and isNarrowString to be false for enums. I think that it's clear that in the long run, we'll be better off for it. It's just that we have no way to make this change and guarantee that we're not breaking anyone's code, much as in many (most?) cases, I would expect the code to be wrong anyway. - Jonathan M Davis
