Bug 12461 – Typedef and opOpAssign

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-03-25T05:45:13Z
Last change time
2019-12-31T09:24:47Z
Keywords
pull
Assigned to
No Owner
Creator
John Colvin

Comments

Comment #0 by john.loughran.colvin — 2014-03-25T05:45:13Z
Typedef really doesn't work. import std.typecons; alias Int = Typedef!(int); unittest { Int a, b; a += b; } typecons.d-mixin-3918(3918): Error: incompatible types for (this.Typedef_payload) += (v)): 'int' and 'Typedef!(int, 0)' /d32/f264.d(8): Error: template instance std.typecons.Typedef!(int, 0).Typedef.Proxy!(Typedef_payload).opOpAssign!("+", Typedef!(int, 0), Typedef!(int, 0)) error instantiating /d32/f264.d(8): Error: 'a += b' is not a scalar, it is a Typedef!(int, 0) /d32/f264.d(8): Error: 'a' is not of arithmetic type, it is a Typedef!(int, 0) /d32/f264.d(8): Error: 'b' is not of arithmetic type, it is a Typedef!(int, 0)
Comment #1 by andrej.mitrovich — 2014-04-23T20:14:41Z
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?
Comment #2 by bearophile_hugs — 2014-04-23T21:21:11Z
(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
Comment #3 by andrej.mitrovich — 2014-04-23T21:26:26Z
(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, ...);
Comment #4 by bearophile_hugs — 2014-04-23T21:49:23Z
(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
Comment #5 by dlang-bot — 2019-12-30T12:29:02Z
@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
Comment #6 by dlang-bot — 2019-12-31T09:24:47Z
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