www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Bugs as enhancements

reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
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
parent jmh530 <john.michael.hall gmail.com> writes:
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