How to test whether comparison is defined for a type?

I defined a new type (Mod29 – integers mod 29).

struct Mod29 <: Real
    function Mod29(value::Integer)
        new(Int8(mod(value, 29)))

In another, generic, algorithm, I need to know whether comparison is defined on a type. I did not define comparison on Mod29, and indeed Mod29(1) < Mod29(3) fails:

**julia&gt;** Mod29(1) &lt; Mod29(3)
**ERROR:** &lt; not defined for Mod29
 [1] **error(** ::String, ::String, ::Type **)** at **./error.jl:42**
 [2] **no_op_err(** ::String, ::Type **)** at **./promotion.jl:410**
 [3] **&lt;(** ::Mod29, ::Mod29 **)** at **./promotion.jl:426**
 [4] top-level scope at **none:0**

But hasmethod(<, (Mod29, Mod29)) and hasmethod(isless, (Mod29, Mod29)) both return true.

I see that < and isless fail trying to do promotion, but I don’t see how to tell that ‘<’ will fail, without trying it and catching the error.

For your amusement, the algorithm I need to change is LU decomposition, where it tries to pivot on the max. If comparison isn’t defined, I just want it to find an element with an inverse, to pivot on. I want to be able to take inverses of matrices of modular numbers.

I think the reason your code is failing is because hasmethod(<,(Real,Real)) is true, and you have defined Mod29 as a subtype of Real. Is that subtyping necessary? When you declare a subtype like this, you are making an implicit promise to support all the methods that go with Real.

One “julian” technique to deal with this problem is to define some new methods:

   haslessthan(::Any) = false
   haslessthan(::Real) = true
   haslessthan(::Mod29) = false

and then dispatch your gaussian elimination on Val{haslessthan(eltype(A))} where A is the matrix. If done correctly, the dispatch is all computed at compile time so there is no run-time overhead in determining which is the correct gaussian elimination method.

also see