Thread overview
Typedef!int + Typedef!int => int? is this a typedef overlook, or it's a feature by design?
Jun 10, 2020
mw
Jun 11, 2020
RazvanN
Jun 11, 2020
RazvanN
Jun 11, 2020
mw
June 10, 2020
Hi,

I'm trying to follow this doc on typedef:

https://dlang.org/library/std/typecons/typedef.html

--------------------------------
import std.typecons;
import std.stdio;

alias MyInt = Typedef!int;

void f(MyInt mi) {}

void main() {
  MyInt a = 2;
  MyInt b = 3;
  f(a + b);
}
--------------------------------

td.d(14,4): Error: function td.f(Typedef!(int, 0, null) mi) is not callable using argument types (int)
td.d(14,4):        cannot pass argument a.opBinary(b) of type int to parameter Typedef!(int, 0, null) mi

Naturally I've expected `a + b` will have the same type as MyInt (not the underlying type int).

Is this a typedef overlook, or it's a feature by design?

If it's by design what's the reason behind?

Thanks.
June 11, 2020
On Wednesday, 10 June 2020 at 22:47:49 UTC, mw wrote:
> Hi,
>
> I'm trying to follow this doc on typedef:
>
> https://dlang.org/library/std/typecons/typedef.html
>
> --------------------------------
> import std.typecons;
> import std.stdio;
>
> alias MyInt = Typedef!int;
>
> void f(MyInt mi) {}
>
> void main() {
>   MyInt a = 2;
>   MyInt b = 3;
>   f(a + b);
> }
> --------------------------------
>
> td.d(14,4): Error: function td.f(Typedef!(int, 0, null) mi) is not callable using argument types (int)
> td.d(14,4):        cannot pass argument a.opBinary(b) of type int to parameter Typedef!(int, 0, null) mi
>
> Naturally I've expected `a + b` will have the same type as MyInt (not the underlying type int).
>
> Is this a typedef overlook, or it's a feature by design?
>
> If it's by design what's the reason behind?
>
> Thanks.

I think it is an overlook and therefore a bug. The spec says that the whole point of Typedef is to create a type that is different from the typedefed one (otherwise you would end up with a glorified alias). However the implementation simply mixins a generic implementation of opBinary that uses the underlying type [1]. The definition of opBinary has no idea that it should wrap the result in another type [2].

[1] https://github.com/dlang/phobos/blob/master/std/typecons.d#L7472
[2] https://github.com/dlang/phobos/blob/master/std/typecons.d#L6836
June 11, 2020
On Thursday, 11 June 2020 at 04:11:24 UTC, RazvanN wrote:

> I think it is an overlook and therefore a bug. The spec says that the whole point of Typedef is to create a type that is different from the typedefed one (otherwise you would end up with a glorified alias). However the implementation simply mixins a generic implementation of opBinary that uses the underlying type [1]. The definition of opBinary has no idea that it should wrap the result in another type [2].
>
> [1] https://github.com/dlang/phobos/blob/master/std/typecons.d#L7472
> [2] https://github.com/dlang/phobos/blob/master/std/typecons.d#L6836

The only solution I can come up with is to add an optional parameter called Wrapper to Proxy that defaults to the type of the first parameter. The opBinary function then will be modified to return Wrapper!ValueType if (is(Wrapper != ValueType)).
June 11, 2020
On Thursday, 11 June 2020 at 04:11:24 UTC, RazvanN wrote:
> I think it is an overlook and therefore a bug. The spec says that the whole point of Typedef is to create a type that is different from the typedefed one (otherwise you would end up with a glorified alias). However the implementation simply

That's my thought too, and on the doc page, the purpose of Typedef is:

Typedef allows the creation of a unique type which is based on an existing type. Unlike the alias feature, Typedef ensures the two types are not considered as equals.

https://dlang.org/library/std/typecons/typedef.html

bug filed:

https://issues.dlang.org/show_bug.cgi?id=20920


> mixins a generic implementation of opBinary that uses the underlying type [1]. The definition of opBinary has no idea that it should wrap the result in another type [2].