More complexity creep in Phobos

Meta jared771 at gmail.com
Thu Mar 28 03:22:07 UTC 2019


On Thursday, 28 March 2019 at 02:17:35 UTC, Andrei Alexandrescu 
wrote:
> I started an alphabetical search through std modules, and as 
> luck would have it I got as far as the first module: 
> std/algorithm/comparison.d. In there, there's these overloads:
>
> size_t levenshteinDistance(alias equals = (a,b) => a == b, 
> Range1, Range2)
>     (Range1 s, Range2 t)
> if (isForwardRange!(Range1) && isForwardRange!(Range2));
>
> size_t levenshteinDistance(alias equals = (a,b) => a == b, 
> Range1, Range2)
>     (auto ref Range1 s, auto ref Range2 t)
> if (isConvertibleToString!Range1 || 
> isConvertibleToString!Range2)
>
> (similar for levenshteinDistanceAndPath)
>
> What's with the second overload nonsense? The Levenshtein 
> algorithm works on forward ranges. And that's about it, in a 
> profound sense: Platonically what the algorithm needs is two 
> forward ranges to operate. (We ought to be pretty proud of it, 
> too: in all other languages I looked at, it's misimplemented to 
> require random access.)
>
> The second overload comes from a warped sense of DWIM: well if 
> this type converts to a string, we commit to support that too. 
> Really. How about a struct that converts to an array? Should we 
> put in a pull request to that, too? Where do we even stop?
>
> I hope there's not much more of this nonsense, because it all 
> should be deprecated with fire.

Maybe the implementation of the fix is not ideal, but the reason 
it was added in the first place is valid, IMO. Looking at the 
original issue[1], the minimized example is as follows:

void popFront(T)(ref T[] a) { a = a[1..$]; }

enum bool isInputRange(R) = is(typeof(
{
     R r;
     r.popFront();
}));

struct DirEntry
{
     @property string name() { return ""; }
     alias name this;
}
pragma(msg, isInputRange!DirEntry); // prints 'false'
pragma(msg, isInputRange!(typeof(DirEntry.init.name))); // prints 
'true'

bool isDir(R)(R r) if (isInputRange!R) { return true; }

void main()
{
     DirEntry de;
     bool c = isDir(de); // Error: isDir cannot deduce function 
from argument types !()(DirEntry)
}

And trying this code out on dmd-nightly[2], it still fails today. 
Personally, I think it would be a bad thing if code that uses a 
DirEntry like above stopped compiling, but I agree that the fix 
could be implemented differently.

It seems like if you see some weird code in Phobos but you don't 
understand why it was written that way, there are 3 main reasons 
that account for 99% of these cases:

- string (autodecoding)
- alias this
- enums

1. https://issues.dlang.org/show_bug.cgi?id=15027
2. https://run.dlang.io/is/zMtHs0


More information about the Digitalmars-d mailing list