# Interface for \`Number\`

**URL:** <https://discourse.julialang.org/t/interface-for-number/2723>\
**Category:** General Usage\
**Created:** [March 17, 2017, 4:44am UTC](https://discourse.julialang.org/t/interface-for-number/2723 "2017-03-17T04:44:49Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)\
**Post date:** [March 17, 2017, 4:44am UTC](https://discourse.julialang.org/t/interface-for-number/2723/1 "2017-03-17T04:44:49Z")

</div>

I recently ran into an issue overriding `zero` for my own `Number`:

```julia
julia> immutable Infinity <: Number end

julia> Base.zero(::Infinity) = 0

julia> import Base: +

julia> +(::Infinity,::Int) = Infinity()
+ (generic function with 181 methods)

julia> reduce(+,[Infinity(),Infinity()])
ERROR: MethodError: Cannot `convert` an object of type Int64 to an object of type Infinity
This may have arisen from a call to the constructor Infinity(...),
since type constructors fall back to convert methods.
Stacktrace:
 [1] _mapreduce(::Base.#identity, ::Base.#+, ::IndexLinear, ::Array{Infinity,1}) at ./reduce.jl:260
 [2] reduce(::Function, ::Array{Infinity,1}) at ./reduce.jl:321

```

The issue appears to be that `zero{T<:Number}(::T)` is expected to return a `T`.

Is this a bug, or is this part of the `Number` “Interface”? Is the `Number` “Interface” written down anywhere?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [March 17, 2017, 4:48am UTC](https://discourse.julialang.org/t/interface-for-number/2723/2 "2017-03-17T04:48:26Z")

</div>

> [@dlfivefifty](#):
>
> The issue appears to be that zero{T\<:Number}(::T) is expected to return a T.
> 
> Is this a bug, or is this part of the Number “Interface”? Is the Number “Interface” written down anywhere?

I’d say it’s part of the interface. If you can’t expect that `zero(::T)` returns a type `T`, then lots of codes would be potentially type-unstable.

I don’t think this interface is written down anywhere, but it should get documented better.

---

<div class="post-metadata">

**Author:** ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)\
**Post date:** [March 17, 2017, 4:53am UTC](https://discourse.julialang.org/t/interface-for-number/2723/3 "2017-03-17T04:53:45Z")

</div>

OK that’s reasonable. Yes, if built in types have an interface that Base Julia assumes (like for Number) it should be written down.

Even better, there should be a `testnumberinterface(Infinity)` to test that all the contracts that Base expects are satisfied for my type. (Also, `testiterator`, `testabstractarray`, etc.)

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [March 17, 2017, 10:38am UTC](https://discourse.julialang.org/t/interface-for-number/2723/4 "2017-03-17T10:38:30Z")

</div>

> [@dlfivefifty](#):
>
> The issue appears to be that zero{T\<:Number}(::T) is expected to return a T.

Is this new in v0.6?

For v0.5, the following works:

```julia
immutable Infinity <: Number end

Base.zero(::Infinity) = 0

import Base: +
+(::Infinity,::Int) = Infinity()
+(::Infinity,::Infinity) = Infinity()

reduce(+,[Infinity(),Infinity()])

```

---

<div class="post-metadata">

**Author:** ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)\
**Post date:** [March 17, 2017, 10:45am UTC](https://discourse.julialang.org/t/interface-for-number/2723/5 "2017-03-17T10:45:33Z")

</div>

Yes it’s 0.6 (sorrry, should have mentioned this was a surprising new behaviour of something that worked fine in 0.5)

---

<div class="post-metadata">

**Author:** ![nalimilan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nalimilan/32/147_2.png) [@nalimilan](https://discourse.julialang.org/u/nalimilan)\
**Post date:** [March 17, 2017, 7:19pm UTC](https://discourse.julialang.org/t/interface-for-number/2723/6 "2017-03-17T19:19:51Z")

</div>

Note that the precise problem is not that `zero()` returns a different type, it’s that the value returned by `zero()` cannot be converted to `Infinity`. Defining this (incorrect) method fixes the issue:  
`Base.convert(::Type{Infinity}, x::Integer) = Infinity()`.

This sounds like an unintentional restriction to me. It could be worth filing a bug. Ideally what should happen is that either the error would only be thrown when the collection is empty (i.e. when `zero` must be used), or we would accept a type instability by returning `0` disregarding its type. But these are complex issues.

---

<div class="post-metadata">

**Author:** ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)\
**Post date:** [March 20, 2017, 4:08am UTC](https://discourse.julialang.org/t/interface-for-number/2723/7 "2017-03-20T04:08:30Z")

</div>

Created an issue: [https://github.com/JuliaLang/julia/issues/21097](https://github.com/JuliaLang/julia/issues/21097)

---

<div class="post-metadata">

**Author:** ![juthohaegeman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juthohaegeman/32/8620_2.png) [@juthohaegeman](https://discourse.julialang.org/u/juthohaegeman)\
**Post date:** [January 11, 2019, 9:46am UTC](https://discourse.julialang.org/t/interface-for-number/2723/8 "2019-01-11T09:46:58Z")

</div>

I was suggested this topic when I was about to start a new development discussion titled “What is a `Number`”

In general, interfaces and abstract types in Julia are pretty well documented and defined, (e.g. `AbstractArray`, iterator interface, …). It is suprising to see so little documentation about what it constitutes to be a `<:Number`, both mathematically and in terms of interface. With currently many active PR’s about making Base code consistent with various number types that are not `<:Real` or `<:Complex`, this would probably be good to have.

So first the mathematics, what are the properties of a type in order to be a subtype of `Number`? Is it supposed to represent elements from a ring , a division ring (I think that this is still fine for `Integer`s, as long as they get promoted to another type under division), a normed division ring, a field (I guess not since non-commutativity of e.g. quaternions is the cause for some recent PRs).

---

<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:** [January 11, 2019, 10:10am UTC](https://discourse.julialang.org/t/interface-for-number/2723/9 "2019-01-11T10:10:47Z")

</div>

I run into a related problem frequently: if I get a container with element type `T <: Number`, and create a result `S`, which I need to precompute, what is the best way to do this? Think of `T` eg as a `ForwardDiff.Dual`, or a similar construct related to a tape from one of the reverse AD packages.

Eg if I know I will be using something that can be based on the four basic arithmetic ops (ie a field), I frequently calculate

```julia
S = typeof(one(T)/one(T))

```

If I have multiple inputs,

```julia
S = typeof(one(T1)/one(T2)/one(T3))

```

also seems to work, but always feels like a hack. A `fieldclosure(T1, T2, ...)` would be nice.

---

<div class="post-metadata">

**Author:** ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)\
**Post date:** [January 11, 2019, 11:22am UTC](https://discourse.julialang.org/t/interface-for-number/2723/10 "2019-01-11T11:22:14Z")

</div>

> So first the mathematics

This is the wrong approach I think. I doubt there’s any useful mathematical definition that includes everything that needs to be `<: Number`, e.g., floating point arithmetic, interval arithmetic, quaternions, dual numbers, etc.

It’s much better to define `Number` as an interface, and anything that implements the `Number` interface is acceptable. So it’s about overriding `+`, `-`, `*`, `/`, etc., not about mathematical consistency.

---

<div class="post-metadata">

**Author:** ![juthohaegeman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juthohaegeman/32/8620_2.png) [@juthohaegeman](https://discourse.julialang.org/u/juthohaegeman)\
**Post date:** [January 11, 2019, 12:54pm UTC](https://discourse.julialang.org/t/interface-for-number/2723/11 "2019-01-11T12:54:30Z")

</div>

Yes I was exaggerating, I know it’s not a good idea to try to map mathematical structures onto the type hierarchy for various reasons. But I do mean establishing the kind of mathematical properties that are expected of a `Number`, i.e. I guess commutative addition operator, associative but not necessarily commutative multiplication operator, is `norm` part of the required interface, …

---

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [January 11, 2019, 1:31pm UTC](https://discourse.julialang.org/t/interface-for-number/2723/12 "2019-01-11T13:31:51Z")

</div>

See [here](https://github.com/JuliaArrays/StaticArrays.jl/blob/786b6f006bd9fcbf7445e6bef018a666f88a44da/src/arraymath.jl#L144) for a variant of `fieldclosure` in the wild. I also implemented such a thing in more then one place…

---

<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:** [January 11, 2019, 2:37pm UTC](https://discourse.julialang.org/t/interface-for-number/2723/13 "2019-01-11T14:37:32Z")

</div>

It would be great to either (in order of my preferences)

1. make this part of `Base`.
2. package it separately,
3. or at least export as supported API.

I end up coding a variant of this many times.

---

<div class="post-metadata">

**Author:** ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)\
**Post date:** [January 11, 2019, 4:47pm UTC](https://discourse.julialang.org/t/interface-for-number/2723/14 "2019-01-11T16:47:46Z")

</div>

There is also this package available

> **[GitHub - SimonDanisch/AbstractNumbers.jl: Define your own number types in...](https://github.com/SimonDanisch/AbstractNumbers.jl)**
>
> Define your own number types in Julia super easily! - GitHub - SimonDanisch/AbstractNumbers.jl: Define your own number types in Julia super easily!

---

<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:** [January 11, 2019, 5:30pm UTC](https://discourse.julialang.org/t/interface-for-number/2723/15 "2019-01-11T17:30:57Z")

</div>

> [@Tamas\_Papp](#):
>
> e.g. if I know I will be using something that can be based on the four basic arithmetic ops (ie a field), I frequently calculate
> 
> ```julia
> S = typeof(one(T)/one(T))
> 
> ```
> 
> […] a `fieldclosure(T1, T2, ...)` would be nice.

Be careful that numbers also include dimensionful quantities, ala Unitful.jl, so ideally generic code should do type computations in a dimensionfully correct way. For example `one(T)` returns the type of the _multiplicative identity_ for `T`, which strips away any units.

Writing truly type-generic numeric code, especially handling the dimensionful case, is tricky and takes testing, though.

---

<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:** [January 11, 2019, 5:48pm UTC](https://discourse.julialang.org/t/interface-for-number/2723/16 "2019-01-11T17:48:14Z")

</div>

> [@stevengj](#):
>
> Writing truly type-generic numeric code, especially handling the dimensionful case, is tricky and takes testing, though.

Which is why existing best practices should be shared, possibly in a package.

---

<div class="post-metadata">

**Author:** ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)\
**Post date:** [January 11, 2019, 11:49pm UTC](https://discourse.julialang.org/t/interface-for-number/2723/17 "2019-01-11T23:49:26Z")

</div>

In my new upcoming [Grassmann.jl](https://github.com/chakravala/Grassmann.jl) package, I am providing a generalized number type for which a product algebra is defined. The parametric `VectorSpace` type system with direct-sum capability helps encode the mathematical properties of each mathematical space, making it possible for many of the computations to be entirely pre-allocated in memory or cached by input. By default, it is defined over a scalar field taking `Number` types, but I have decided to provide an additional convenient feature which can make extending the entire product algebra to different number types a breeze.

Due to the abstract generality of the code generation of the `Grassmann` product algebra, it is possible to extend the entire set of operations to other kinds of scalar coefficient types. By default, the coefficients are required to be `<:Number` . However, if this does not suit your needs, an alternative scalar product algebra can be specified with

```nohighlight
generate_product_algebra(SymField,:(Sym.:*),:(Sym.:+),:(Sym.:-),:svec)

```

where `SymField` is the desired scalar field and `Sym` is the scope which contains the scalar field algebra for `SymField` . Currently, it is feasible to enable symbolic scalar computation, by specifying the operations. It should be straight-forward to substitute any other extended algebraic operations and for extended fields.

My hope is that it will be extensible enough to handle different promotion situations, such as propagating dimensionful quantities, which I have not given much thought to yet.
