jvz
jvz

Reputation: 1422

`reinterpret` not working with custom primitive type in Julia

I'm trying to implement my own primitive type as follows:

primitive type Odds <: AbstractFloat 64 end
function Odds(x::AbstractFloat)
    if x < 1.0
        throw(DomainError(x, "not a valid odds ratio"))
    end
    reinterpret(Odds, x)
  end
Odds(x::Odds) = x
Float64(x::Odds) = reinterpret(Float64, x)
import Base: +
+(x::Odds, y::Odds) = Odds(Float64(x) + Float64(y))

When I try to make use of the custom + function, it gives this:

julia> Odds(1.2)+Odds(1.3)
ERROR: MethodError: no method matching reinterpret(::typeof(Float64), ::Odds)
Closest candidates are:
  reinterpret(::Type{T}, ::Any) where T at essentials.jl:417
Stacktrace:
 [1] Float64(::Odds) at <xxx>\src\odds.jl:11
 [2] +(::Odds, ::Odds) at <xxx>\src\odds.jl:13
 [3] top-level scope at none:0

I.e., the stacktrace tells me this line:

Float64(x::Odds) = reinterpret(Float64, x)

is not working, because I supply Float64 in the wrong way? The docs (https://docs.julialang.org/en/v1/base/arrays/#Base.reinterpret), and a previous StackOverflow question (Implementing custom primitive types in Julia) suggest I do it the right way.

I'm on Julia 1.2.0, Windows.

Upvotes: 1

Views: 216

Answers (1)

Jakob Nissen
Jakob Nissen

Reputation: 1991

By default you can't add methods to functions in Base without importing them first, or explicitly specifying the namespace. You need to do this:

Base.Float64(x::Odds) = reinterpret(Float64, x)

In general, there is little reason to use a primitive type over a one-field struct. There will be no performance difference, and a one-field struct is easier to work with. The only reason I can think of is if you need to call LLVM intrinsics on your type.

Upvotes: 3

Related Questions