Thread overview
[Issue 12461] Typedef and opOpAssign
Apr 23, 2014
Andrej Mitrovic
Apr 23, 2014
Andrej Mitrovic
Dec 30, 2019
Dlang Bot
Dec 31, 2019
Dlang Bot
April 23, 2014
https://issues.dlang.org/show_bug.cgi?id=12461

Andrej Mitrovic <andrej.mitrovich@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrej.mitrovich@gmail.com,
                   |                            |k.hara.pg@gmail.com

--- Comment #1 from Andrej Mitrovic <andrej.mitrovich@gmail.com> ---
This seems to be a Proxy issue. Kenji, if I add the following to Proxy:

-----
private enum getField(T) = is(T == typeof(this))
    ? ("." ~ __traits(identifier, a)) : "";

auto ref opOpAssign(string op, this X, V)(auto ref V v)
{
    return mixin("a " ~ op ~ "= v" ~ getField!V);
}
-----

Then the OP code will work. But I'm not sure if this is the appropriate fix. Do you have a better idea?

--
April 23, 2014
https://issues.dlang.org/show_bug.cgi?id=12461

bearophile_hugs@eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs@eml.cc

--- Comment #2 from bearophile_hugs@eml.cc ---
(In reply to Andrej Mitrovic from comment #1)

> But I'm not sure if this is the appropriate fix.
> Do you have a better idea?

In Haskell this doesn't compile (newtype is a built-in that is similar to
Typedef):


newtype T = T Int

main = do
    let a = 10 :: T
    let b = 20 :: T
    let c = a + b :: T
    print c




You have to ask the compiler to activate the arithmetic operations between two newtypes:


{-# LANGUAGE GeneralizedNewtypeDeriving #-}

newtype T = T Int deriving (Num, Show)

main = do
    let a = 10 :: T
    let b = 20 :: T
    let c = a + b :: T
    print c


And now it prints:

T 30

--
April 23, 2014
https://issues.dlang.org/show_bug.cgi?id=12461

--- Comment #3 from Andrej Mitrovic <andrej.mitrovich@gmail.com> ---
(In reply to bearophile_hugs from comment #2)
> (In reply to Andrej Mitrovic from comment #1)
> 
> > But I'm not sure if this is the appropriate fix.
> > Do you have a better idea?
> 
> In Haskell this doesn't compile (newtype is a built-in that is similar to
> Typedef).
> You have to ask the compiler to activate the arithmetic operations between
> two newtypes.

Sounds like a more configurable and complex version of Typedef. Note that 99% of the work of Typedef is done by Proxy, Typedef simply stores a Proxy inside and otherwise has a very minimal implementation.

Anyway I could imagine there is a million little ways you could configure a Typedef, but maybe it's best to have the scaffolding available as a set of mixin templates, so the user can easily create their own specific versions, e.g.:

struct UserTypedef(T)
{
    mixin MixOverload!"opUnary";  // implement opUnary
    mixin MixOverload!"opBinary";  // implement opBinary
}

This is probably simpler than having a super-complicated generic Typedef structure such as:

struct Typedef(bool useOpUnary, bool useOpBinary, ...);

--
April 23, 2014
https://issues.dlang.org/show_bug.cgi?id=12461

--- Comment #4 from bearophile_hugs@eml.cc ---
(In reply to Andrej Mitrovic from comment #3)

> struct UserTypedef(T)
> {
>     mixin MixOverload!"opUnary";  // implement opUnary
>     mixin MixOverload!"opBinary";  // implement opBinary
> }
> 
> This is probably simpler than having a super-complicated generic Typedef structure such as:
> 
> struct Typedef(bool useOpUnary, bool useOpBinary, ...);

Note: I didn't open this enhancement request.

A simpler solution is to offer a way to get the underlying value:

a.get += b.get;


In Haskell you can define the Num typeclass operations of a newclass, or just define a simple function that uses pattern matching, and I use pattern matching again to print it:

newtype T = T Int

add :: T -> T -> T
T a `add` T b = T (a + b)

main = do
    let a = T 10
    let b = T 20
    let c = a `add` b
    let T d = c
    print d

--
December 30, 2019
https://issues.dlang.org/show_bug.cgi?id=12461

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull

--- Comment #5 from Dlang Bot <dlang-bot@dlang.rocks> ---
@berni44 created dlang/phobos pull request #7338 "Fix Issue 12461 - Typedef and opOpAssign" fixing this issue:

- Fix Issue 12461 - Typedef and opOpAssign

https://github.com/dlang/phobos/pull/7338

--
December 31, 2019
https://issues.dlang.org/show_bug.cgi?id=12461

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED

--- Comment #6 from Dlang Bot <dlang-bot@dlang.rocks> ---
dlang/phobos pull request #7338 "Fix Issue 12461 - Typedef and opOpAssign" was merged into master:

- 998ac2bc36e2b0f0ef44837a937871d0d4a0a89c by Bernhard Seckinger:
  Fix Issue 12461 - Typedef and opOpAssign

https://github.com/dlang/phobos/pull/7338

--