# Wrap and inherit Number

**URL:** https://discourse.julialang.org/t/wrap-and-inherit-number/4799
**Category:** General Usage
**Tags:** question
**Created:** [July 12, 2017, 11:24am UTC](https://discourse.julialang.org/t/wrap-and-inherit-number/4799 "2017-07-12T11:24:34Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)
#### Post date: [July 12, 2017, 11:24am UTC](https://discourse.julialang.org/t/wrap-and-inherit-number/4799/1 "2017-07-12T11:24:34Z")

</div>

I’ve seen topics touching this in different constellations, but:

How do people create a new type that would magically behave just like any subtype of (say) `Number`? So for example, if:

```julia
struct A{T <: Number}
    x::T
end

```

then I’d just be able to `*`, `+`, `sin`, `exp`, or `sqrt` instances of `A` and on top of that I’d still be able to (re)define additional specialized methods like say `sqrt(a::A) = (a.x)^(1/3)`?

Thanks and sorry for the overlap/repeat.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [July 12, 2017, 11:28am UTC](https://discourse.julialang.org/t/wrap-and-inherit-number/4799/2 "2017-07-12T11:28:03Z")

</div>

You need to define the operations for your new type.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [July 12, 2017, 11:28am UTC](https://discourse.julialang.org/t/wrap-and-inherit-number/4799/3 "2017-07-12T11:28:11Z")

</div>

The manual has a [case study on Rational](https://docs.julialang.org/en/latest/manual/constructors/#Case-Study:-Rational-1).

[Dual in ForwardDiff](https://github.com/JuliaDiff/ForwardDiff.jl) is a very elaborate example.

---

<div class="post-metadata">

### Author: ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)
#### Post date: [July 12, 2017, 11:38am UTC](https://discourse.julialang.org/t/wrap-and-inherit-number/4799/4 "2017-07-12T11:38:09Z")

</div>

isn’t there some macro that does that for me…? Or do you all use meta-programming to define all the possible methods?

---

<div class="post-metadata">

### Author: ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)
#### Post date: [July 12, 2017, 11:38am UTC](https://discourse.julialang.org/t/wrap-and-inherit-number/4799/5 "2017-07-12T11:38:55Z")

</div>

But even then I can’t just go and

```julia
julia> a = OurRational(1,2)
OurRational{Int64}(1, 2)

julia> a*a
ERROR: * not defined for OurRational{Int64}

```

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [July 12, 2017, 11:56am UTC](https://discourse.julialang.org/t/wrap-and-inherit-number/4799/6 "2017-07-12T11:56:32Z")

</div>

How would you expect Julia to know what you mean by `*` for a new type?

---

<div class="post-metadata">

### Author: ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)
#### Post date: [July 12, 2017, 12:01pm UTC](https://discourse.julialang.org/t/wrap-and-inherit-number/4799/7 "2017-07-12T12:01:12Z")

</div>

No no, I understand. But I had hoped that if I wanted to mimic, say, `Float64`, then there would have been an easy way to do that. Kind of like, in stead of starting from scratch: “here is a new type, you don’t know anything about it, let me tell you all you need to know about it”, starting from the top and “adjusting down”: “here is a new type, it’s exactly like Float64, except in this and this and that case”…

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [July 12, 2017, 12:08pm UTC](https://discourse.julialang.org/t/wrap-and-inherit-number/4799/8 "2017-07-12T12:08:24Z")

</div>

You could do something along the lines of

```julia
module PseudoNumbers

export PseudoNumber, getnumber # this is the interface

abstract type PseudoNumber end

function getnumber end

import Base: + # and the rest ...

# should define for univariate and multivariate operators using macros,
# this is just an example
+(a::T, b::T) where {T <: PseudoNumber} = T(getnumber(a) + getnumber(b))

end

```

and then all the code you would need to write is

```julia
using PseudoNumbers

struct MyFloat{T} <: PseudoNumber
    x::T
end

PseudoNumbers.getnumber(mf::MyFloat) = mf.x

MyFloat(1.0) + MyFloat(2.0) # works out of the box

```

but I expect you would have to think about corner cases (lifting reals, how to combine two different types, etc).

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [July 12, 2017, 1:12pm UTC](https://discourse.julialang.org/t/wrap-and-inherit-number/4799/9 "2017-07-12T13:12:29Z")

</div>

One option that we discussed a while back ([https://github.com/JuliaLang/julia/pull/3292](https://github.com/JuliaLang/julia/pull/3292)) is for a package to define a `@delegate` macro, so that you could do e.g.:

```julia
struct A{T<:Number}
    x::T
end
@delegate A.x Number

```

and it would use `methodswith(Number, Base)` to find all of the (exported) `::Number` methods and define corresponding `a::A` methods that pass through `a.x`.

I don’t think anyone ever actually tried implementing such a thing, but it would be an interesting experiment.

([TypedDelegation.jl](https://github.com/JuliaArbTypes/TypedDelegation.jl) might be a reasonable place to work on this.)

---

<div class="post-metadata">

### Author: ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)
#### Post date: [July 12, 2017, 1:15pm UTC](https://discourse.julialang.org/t/wrap-and-inherit-number/4799/10 "2017-07-12T13:15:10Z")

</div>

I think that would be useful. Before you suggest I do that, I’ll just add: I suck at meta programming…

---

<div class="post-metadata">

### Author: ![davidanthoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/davidanthoff/32/223493_2.png) [@davidanthoff](https://discourse.julialang.org/u/davidanthoff)
#### Post date: [July 12, 2017, 1:19pm UTC](https://discourse.julialang.org/t/wrap-and-inherit-number/4799/11 "2017-07-12T13:19:35Z")

</div>

While you can implement all the methods that a normal number has for your custom type, there is one thing where it gets tricky: do you want to inherit from `Number` or not? If you don’t, you can’t pass instances of your type to functions that only accept `Number`s, even if your type behaves like a number. I don’t think there is a good solution to this right now, we’ll probably have to wait for either traits or interfaces in some future julia version for an elegant solution.

---

<div class="post-metadata">

### Author: ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)
#### Post date: [July 12, 2017, 1:20pm UTC](https://discourse.julialang.org/t/wrap-and-inherit-number/4799/12 "2017-07-12T13:20:35Z")

</div>

automatic promotion?

---

<div class="post-metadata">

### Author: ![sambitdash](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sambitdash/32/1377_2.png) [@sambitdash](https://discourse.julialang.org/u/sambitdash)
#### Post date: [July 12, 2017, 1:24pm UTC](https://discourse.julialang.org/t/wrap-and-inherit-number/4799/13 "2017-07-12T13:24:21Z")

</div>

Automatic promotion should be avoided for custom types. They are good only for built-in types.

---

<div class="post-metadata">

### Author: ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)
#### Post date: [July 12, 2017, 1:50pm UTC](https://discourse.julialang.org/t/wrap-and-inherit-number/4799/14 "2017-07-12T13:50:58Z")

</div>

A few weeks ago @Per shared the intention to work on a library that may suit your needs, if your type will be a subtype of `AbstractFloat` (but it may not be the case):

> [@AbstractFloat math (Is anybody already doing this?)](https://discourse.julialang.org/t/abstractfloat-math-is-anybody-already-doing-this/4363):
>
> I’m planning an open-source (MIT license) project to do in my spare time, but I thought it might be a good idea to check with the community first, in case anybody is already doing something similar. My idea is to write a package AbstractFloatMath (working title) of pure-Julia routines for common mathematical functions (sin, log, sqrt, …) that will take AbstractFloat arguments, i.e. work with any user defined type that is \<: AbstractFloat. For a new floating-point type, it will be enough to i…

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [July 12, 2017, 1:54pm UTC](https://discourse.julialang.org/t/wrap-and-inherit-number/4799/15 "2017-07-12T13:54:30Z")

</div>

Ref this issue [https://github.com/JuliaLang/julia/issues/9821](https://github.com/JuliaLang/julia/issues/9821).

---

<div class="post-metadata">

### Author: ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)
#### Post date: [July 12, 2017, 1:58pm UTC](https://discourse.julialang.org/t/wrap-and-inherit-number/4799/16 "2017-07-12T13:58:03Z")

</div>

Sounds great. I’m working on the tests now, but this whole thing is just for my [idea](https://discourse.julialang.org/t/should-there-be-a-native-angle-type/4611) with the `Angle` type. I defined all the functions needed for the conversions and the trigonometry, but now “all” I need is for this Angle type to behave like a `Number` (or `AbstractFloat`) in every other situation…

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [July 12, 2017, 2:09pm UTC](https://discourse.julialang.org/t/wrap-and-inherit-number/4799/17 "2017-07-12T14:09:04Z")

</div>

> [@sambitdash](#):
>
> Automatic promotion should be avoided for custom types. They are good only for built-in types.

That’s totally wrong. The whole point of Julia’s promotion mechanism is that it is _not_ just for “built-in” types, and is equally extensible to user-defined types. [https://docs.julialang.org/en/latest/manual/conversion-and-promotion/](https://docs.julialang.org/en/latest/manual/conversion-and-promotion/)

The real problem is that promotion rules are defined for mixed operations on different types, e.g. if you do `a + b` where `a` and `b` are different `Number` types then it will call `promote(a,b)` by default. This doesn’t help you at all for `exp(x)`, for example, or for non-`Number` types, where the promotion code is not called in the default methods.

---

<div class="post-metadata">

### Author: ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)
#### Post date: [July 12, 2017, 6:40pm UTC](https://discourse.julialang.org/t/wrap-and-inherit-number/4799/18 "2017-07-12T18:40:38Z")

</div>

The `@forward` macro from Lazy.jl makes this a bit easier by allowing you to delegate a given list of functions to a specific field of a type: [https://github.com/MikeInnes/Lazy.jl/blob/master/src/macros.jl#L267](https://github.com/MikeInnes/Lazy.jl/blob/master/src/macros.jl#L267)

(this is not nearly as fancy as the hypothetical `@delegate`, but at least it exists right now)

---

<div class="post-metadata">

### Author: ![kevin.squire](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kevin.squire/32/62_2.png) [@kevin.squire](https://discourse.julialang.org/u/kevin.squire)
#### Post date: [July 13, 2017, 3:23am UTC](https://discourse.julialang.org/t/wrap-and-inherit-number/4799/19 "2017-07-13T03:23:59Z")

</div>

DataStructures.jl has an [implementation of `@delegate`](https://github.com/JuliaCollections/DataStructures.jl/blob/master/src/delegate.jl). If there’s interest, that could be turned into a (1 or 2 macro) package.

Cheers,  
Kevin

---

<div class="post-metadata">

### Author: ![kevin.squire](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kevin.squire/32/62_2.png) [@kevin.squire](https://discourse.julialang.org/u/kevin.squire)
#### Post date: [July 13, 2017, 6:49am UTC](https://discourse.julialang.org/t/wrap-and-inherit-number/4799/20 "2017-07-13T06:49:46Z")

</div>

To be clear, that implementation of delegate is not as full featured as @stevengj’s described version above.

[Next page](https://discourse.julialang.org/t/wrap-and-inherit-number/4799.md?page=2)
