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