digitalmars.D - Bugs as enhancements
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (29/29) Dec 27 2020 This fails to compile:
- jmh530 (78/79) Dec 27 2020 For reference, this was also discussed recently here [1]. I'm not
This fails to compile: struct Foo(T) {} alias Bar(T) = Foo!T; void f(T)(Bar!T x) {} void main() { f(Bar!int()); } as the type resolution fails to unify the alias Bar with the type Foo. I think this is a basic type system failure, basic type unification should easily resolve this: https://www.google.com/search?q=implement+type+unification https://en.wikipedia.org/wiki/Unification_(computer_science) Bearophile reported it in 2013: https://issues.dlang.org/show_bug.cgi?id=10884 And it has been classified as a duplicate of a 2008 issue: https://issues.dlang.org/show_bug.cgi?id=1807 It has been misclassified as "enhancement", when it actually should be classified as a "critical type system failure". The problem (or related problems) has been discussed in a DIP and in a pull request and DIP: https://github.com/dlang/dmd/pull/9778 https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1023.md When will this issue get the love it deserves? Fixing such in-your-face type system failures ought to be much more important than adding new features, surely? 7-12 years to fix such basic type system functionality is quite a long time considering the many features that has been added in that time period. (Btw, this works perfectly fine in C++).
Dec 27 2020
On Sunday, 27 December 2020 at 13:36:44 UTC, Ola Fosheim Grøstad wrote:[snip]For reference, this was also discussed recently here [1]. I'm not sure if the tone on that thread was the best to push this idea forward, perhaps this one might be a bit better. ----- To the example you provide, the following does compile struct Foo(T) {} alias Bar(T) = Foo!T; void f(T)(Bar!T x) {} void main() { f!int(Bar!int()); } In other words, the problem is due to type deduction of alias templates. No type deduction, no problem. Here's another simple example of using this feature to facilitate the use of something like Concepts: enum bool check(T) = is(T == float); template Concept(T, alias U) { static assert(U!T); alias Concept = T; } void foo(T)(Concept!(T, check) x) { } void main() { Concept!(float, check) x; foo(x); //does not compile foo!float(x); //does compile } ideally you could also use it as in alias Check(T) = Concept!(T, check); void foo(T)(Check!(T) x) { } ----- Reading over the issue [2] again, one of the sticking points that is provided is (without including some of the BlasMatrix-related stuff) alias PackedUpperTriangularMatrix(T) = Slice!(StairsIterator!(T*, "-")); void composeLU(T)( PackedLowerTriangularMatrix!(const T) l, // First Slice type for Lower Matrix PackedUpperTriangularMatrix!(const T) u, // Second Slice type for Lower Matrix BlasMatrix!T lu, // Third Slice type for General Matrix ) if (is(T == float) && is(T == double)) { ... } with the alternative enum isPackedUpperTriangularMatrix(T) = is(T: Slice!(StairsIterator!(U*, "-")), U); void composeLU(L, U, LU)(L l, U u, LU lu) if(isPackedLowerTriangularMatrix!L && isPackedUpperTriangularMatrix!U && isBlasMatrix!LU && /* .. */ ) { } A point that Ilya makes is that you need to fill in the /* .. */, which makes the whole thing become something like void composeLU(L, U, LU)(L l, U u, LU lu) if(isPackedLowerTriangularMatrix!L && isPackedUpperTriangularMatrix!U && isBlasMatrix!LU && (is(Unqual!(ForeachType!L) == float) || is(Unqual!(ForeachType!L) == double))) && is(ForeachType!L == ForeachType!U) && is(ForeachType!LU == Unqual!(ForeachType!L)) ) { } It really does help make the case for the change when you have to write them all out yourself. [1] https://forum.dlang.org/post/yobmmccdvbmmbaolehbs forum.dlang.org [2] https://github.com/dlang/dmd/pull/9778
Dec 27 2020