More complexity creep in Phobos

Meta jared771 at gmail.com
Thu Mar 28 05:36:18 UTC 2019


On Thursday, 28 March 2019 at 04:20:55 UTC, Andrei Alexandrescu 
wrote:
> There's this nice notion of reasoning by first principles vs. 
> reasoning by analogy:
>
> https://fs.blog/2018/04/first-principles/
>
> A very nice essay - recommended outside this discussion's 
> context, too. The levenshteinDistance issue is a direct 
> application of the two kinds of reasoning. This is reasoning by 
> analogy:
>
> "DirEntry converts to string and is used by some people as 
> such. They pass it to functions, and some accept it but some 
> don't. It follows by analogy that the Levenshtein distance 
> algorithm should be worked out to accept it, too."
> In contrast, the reasoning from first principles should 
> powerfully override that:
>
> "Levenshtein distance operates on forward ranges. All that 
> stuff that changes the signature of levenshteinDistance to 
> accept other artifacts is nonsense. Whoever wants to use it 
> should carry the conversion to forward range themselves."
>
> It follows that the correct answer to this generalization 
> frenzy should be: "We work with ranges and character types. If 
> you've got enums and alias this and whatnot, more power to you 
> but to use the standard library you must convert those to the 
> stuff we support."

I agree with your first principles arguments, but not your 
conclusion. I believe you are starting with the faulty base 
assumption that DirEntry is not a range. DirEntry IS a range, by 
the rules of the current language.

DirEntry states that it is a subtype of `string` by declaring 
`alias name this`. It follows that a DirEntry may be 
transparently substituted wherever a string is accepted. As a 
string is a range, and DirEntry is a subtype of string, then 
DirEntry is also a range.

`levenshteinDistance` accepts two ranges as its arguments, either 
of which may be strings; therefore, either of its arguments may 
also be a DirEntry substituted in the place of a string. By writ, 
we must support passing a DirEntry to levenshteinDistance.



The real problem here is with `alias this`.

`alias this` claims to allow one type to become a subtype of 
another, but that's not true; this language feature violates the 
Liskov Substitution Principle (a fact that I have mentioned 
before, and likely others). `alias this` fails the 
substitutability test - this thread and the defect linked are 
proof of that.

Because `alias this` claims to allow one type A to subtype 
another type B, but does not actually make good on that promise 
and implements this subtyping improperly, it follows that any 
code working with type B that wants to also support type A has to 
use these ugly workarounds.

The code in question is working around a defect in the language, 
and would not be necessary if the language itself were fixed.



More information about the Digitalmars-d mailing list