March 22, 2023

On Wednesday, 22 March 2023 at 10:43:15 UTC, Elfstone wrote:

>
template <typename T>
using Vector3 = Matrix<T, 3, 1>;

I declare an alias and I use it everywhere. It acts as a natural constraint. I never needed isVector3 with my old C++ code. I expected D could do the same, and was really frustrated when I found out it couldn't. Even more frustrated when I read Steven's reply, that the bug with is has been there for 16 years.

When you have questions, please file a bugzilla.
D is only for specific problems, please describe the problem carefully.

March 22, 2023

On Wednesday, 22 March 2023 at 10:43:15 UTC, Elfstone wrote:

>

I don't know how C++ compilers resolve template using just fine.

template <typename T>
using Vector3 = Matrix<T, 3, 1>;

I declare an alias and I use it everywhere. It acts as a natural constraint. I never needed isVector3 with my old C++ code. I expected D could do the same, and was really frustrated when I found out it couldn't. Even more frustrated when I read Steven's reply, that the bug with is has been there for 16 years.

When the compiler allows people to use template aliases as template function parameters, it should make it work, or reject it aloud. Maybe some future system can save the day, but does it mean the old alias will just be left bugged?

You can perfectly fine use alias Vector3(T) = Matrix!(T, 3, 1) in D. You cannot constrain a type to be Vector3 in D, but you cannot in C++ either. (I don't think so? I'm poking at C++20 concepts, but I don't see a way to do it.)

March 22, 2023

On Wednesday, 22 March 2023 at 12:30:46 UTC, FeepingCreature wrote:

>

On Wednesday, 22 March 2023 at 10:43:15 UTC, Elfstone wrote:

>

I don't know how C++ compilers resolve template using just fine.

template <typename T>
using Vector3 = Matrix<T, 3, 1>;

I declare an alias and I use it everywhere. It acts as a natural constraint. I never needed isVector3 with my old C++ code. I expected D could do the same, and was really frustrated when I found out it couldn't. Even more frustrated when I read Steven's reply, that the bug with is has been there for 16 years.

When the compiler allows people to use template aliases as template function parameters, it should make it work, or reject it aloud. Maybe some future system can save the day, but does it mean the old alias will just be left bugged?

You can perfectly fine use alias Vector3(T) = Matrix!(T, 3, 1) in D. You cannot constrain a type to be Vector3 in D, but you cannot in C++ either. (I don't think so? I'm poking at C++20 concepts, but I don't see a way to do it.)

Oh wait, correction: you can do it! Neat! I wonder how that works.

Probably it's because using is more syntactically constrained?

template <typename T, int M, int N>
struct Matrix {
};

template <typename T>
using Vector3 = Matrix<T, 3, 1>;

template<typename T>
void baz(Vector3<T>& vector)
{
}

int main() {
  auto v = Vector3<int>();
  baz(v);
}
March 22, 2023

On Wednesday, 22 March 2023 at 11:00:40 UTC, zjh wrote:

alias Vec3(S) = Matrix!(S, 3, 1);
void foo(U)(U v)
if (is(U == Matrix!(S,3,1), S)) { }

void foo2(U)(U v)
if (is(U == Vec3!S, S)) { }

Foo can compile, but foo2 cannot compile, which is very strange!
C++ has no problem.

March 22, 2023

On Wednesday, 22 March 2023 at 12:34:26 UTC, FeepingCreature wrote:

>

On Wednesday, 22 March 2023 at 12:30:46 UTC, FeepingCreature wrote:

>

On Wednesday, 22 March 2023 at 10:43:15 UTC, Elfstone wrote:

>

I don't know how C++ compilers resolve template using just fine.

template <typename T>
using Vector3 = Matrix<T, 3, 1>;

I declare an alias and I use it everywhere. It acts as a natural constraint. I never needed isVector3 with my old C++ code. I expected D could do the same, and was really frustrated when I found out it couldn't. Even more frustrated when I read Steven's reply, that the bug with is has been there for 16 years.

When the compiler allows people to use template aliases as template function parameters, it should make it work, or reject it aloud. Maybe some future system can save the day, but does it mean the old alias will just be left bugged?

You can perfectly fine use alias Vector3(T) = Matrix!(T, 3, 1) in D. You cannot constrain a type to be Vector3 in D, but you cannot in C++ either. (I don't think so? I'm poking at C++20 concepts, but I don't see a way to do it.)

Oh wait, correction: you can do it! Neat! I wonder how that works.

Probably it's because using is more syntactically constrained?

template <typename T, int M, int N>
struct Matrix {
};

template <typename T>
using Vector3 = Matrix<T, 3, 1>;

template<typename T>
void baz(Vector3<T>& vector)
{
}

int main() {
  auto v = Vector3<int>();
  baz(v);
}

Looks like it substitutes through simple cases but fails with more complex ones?

#include <type_traits>

template <typename T, int M, int N>
struct Matrix {
};

template <typename T>
using Vector3 = typename std::conditional<true, Matrix<T, 3, 1>, void>::type;

template<typename T>
void baz(Vector3<T>& vector)
{
}

int main() {
  auto v = Vector3<int>();
  /*
  test.cpp:17:6: error: no matching function for call to ‘baz(Matrix<int, 3, 1>&)’
     17 |   baz(v);
        |   ~~~^~~
  test.cpp:11:6: note: candidate: ‘template<class T> void baz(Vector3<T>&)’
     11 | void baz(Vector3<T>& vector)
        |      ^~~
  test.cpp:11:6: note:   template argument deduction/substitution failed:
  test.cpp:17:6: note:   couldn’t deduce template parameter ‘T’
  */
  baz(v);
}

That much we can probably implement in D, granted: specifically recognize trivial aliases in the template resolution code.

Do file a bug for that.

March 22, 2023

On Wednesday, 22 March 2023 at 11:00:40 UTC, zjh wrote:

>

On Wednesday, 22 March 2023 at 10:43:15 UTC, Elfstone wrote:

>
template <typename T>
using Vector3 = Matrix<T, 3, 1>;

I declare an alias and I use it everywhere. It acts as a natural constraint. I never needed isVector3 with my old C++ code. I expected D could do the same, and was really frustrated when I found out it couldn't. Even more frustrated when I read Steven's reply, that the bug with is has been there for 16 years.

When you have questions, please file a bugzilla.
D is only for specific problems, please describe the problem carefully.

What the OP is referring to is an old D bug [1]. In this thread, he's not really asking questions so much as highlighting that it is still an issue.

[1] https://issues.dlang.org/show_bug.cgi?id=1807

March 22, 2023

On Wednesday, 22 March 2023 at 12:54:52 UTC, jmh530 wrote:

>

What the OP is referring to is an old D bug [1]. In this thread, he's not really asking questions so much as highlighting that it is still an issue.

[1] https://issues.dlang.org/show_bug.cgi?id=1807

Ah, thank you! Yeah now that I see it's more about specifically recognizing and dissolving the alias usage on the callee side during type inference, it makes a lot more sense.

(Accidentally filed a dupe :) )

March 22, 2023

On Tuesday, 21 March 2023 at 07:51:50 UTC, FeepingCreature wrote:

>

[snip]
What you want needs a fundamentally new language feature; something like typeclasses. Now there's an argument to be made to add typeclasses to the language, they would make ranges a lot more swanky for instance, but it's just not a matter of making template inference marginally more powerful.

There are a lot of things that D's template aliases could do if resolution were a solved problem (I get that a big problem is that it is too powerful).

Below (taken from [1]) is a way to use something like concepts in D (b/c you can impose any constraint you want on the template or on static if's within the template). You can place requirements on T (in this case just that it is an int) and if it succeeds, then you have your alias. In a more complicated case, static if's could provide better error messages.

template Foo(T)
    if (is(T == int))
{
    alias Foo = T;
}

void foo(T)(Foo!T x) { }

void main() {
    Foo!int x;
    foo!int(x); //compiles
    foo(x);     //doesn't compile but ideally should
    foo(1.0);   //doesn't compile and shouldn't
}

Unfortunately, an alias this approach wouldn't be sufficient in this case since alias this requires creating a whole new type. That means if you want the functionality to work with the original type, then you need to have it be implicitly convertible to the original type and you're still stuck writing that type out.

struct Matrix(S, size_t M, size_t N) {}

struct Vec3(S) {
    Matrix!(S, 3, 1) data;
    alias data this;
}

void foo(U : Matrix!(V, 3, 1), V)(U u) {}
void bar(U)(Vec3!U v) {}

void main()
{
    import std.stdio;

    Matrix!(float, 3, 1) u;
    Vec3!float v;
    foo(u);
    foo(v);
    //bar(u); //fails to compile
    bar(v);
}

[1] https://forum.dlang.org/post/uzvxrqywxfqmoplurfcf@forum.dlang.org

March 22, 2023

On Wednesday, 22 March 2023 at 13:29:56 UTC, jmh530 wrote:

>

There are a lot of things that D's template aliases could do if resolution were a solved problem (I get that a big problem is that it is too powerful).

Right,template alias is very important!

March 23, 2023

On Wednesday, 22 March 2023 at 11:00:40 UTC, zjh wrote:

>

On Wednesday, 22 March 2023 at 10:43:15 UTC, Elfstone wrote:

>
template <typename T>
using Vector3 = Matrix<T, 3, 1>;

I declare an alias and I use it everywhere. It acts as a natural constraint. I never needed isVector3 with my old C++ code. I expected D could do the same, and was really frustrated when I found out it couldn't. Even more frustrated when I read Steven's reply, that the bug with is has been there for 16 years.

When you have questions, please file a bugzilla.
D is only for specific problems, please describe the problem carefully.

There are already a ton issues about this filed, including Steven's 16 years old one. It seems the community lacks the motivation to fix it. That's why I started this thread.