That particular error was just because the <= operator was implemented and there was no fallback method to give an informative error. I sent in a PR to fix that: #11372 <https://github.com/JuliaLang/julia/pull/11372>.
Beyond that, I managed to get it working by adding a couple more methods. It was a pain though because it would often crash or give some strange name instead of telling me which method had not been implemented. So I had to search through the Base code to see what was being called. Here is my full working code that is adapted from yours: import Base: show, convert, promote_rule, nextfloat, trunc, round, floor immutable JDate <: FloatingPoint t::Float64 end show(io::IO, x::JDate) = print(io, "JDate($(x.t))") convert(::Type{Float64}, x::JDate) = x.t convert{T<:Integer}(::Type{T}, x::JDate) = T(x.t) convert{T<:Real}(::Type{JDate}, x::T) = JDate(x) promote_rule(::Type{JDate}, ::Type{Float64}) = JDate promote_rule(::Type{JDate}, ::Type{Float32}) = JDate promote_rule(::Type{JDate}, ::Type{Int64}) = JDate <(a::JDate,b::JDate) = <(a.t,b.t) <=(a::JDate,b::JDate) = <=(a.t,b.t) +(a::JDate,b::JDate) = JDate(a.t + b.t) -(a::JDate,b::JDate) = JDate(a.t - b.t) -(a::JDate) = JDate(-a.t) /(a::JDate,b::JDate) = JDate(a.t / b.t) *(a::JDate,b::JDate) = JDate(a.t * b.t) nextfloat(a::JDate,b::Int64) = JDate(nextfloat(a.t, b)) round(a::JDate) = JDate(round(a.t)) trunc(::Type{Int64}, a::JDate) = trunc(Int64, a.t) floor(a::JDate) = JDate(floor(a.t)) rnge = JDate(1):0.5:JDate(2) println(rnge) println(collect(rnge)) Output: JDate(1.0):JDate(0.5):JDate(2.0) JDate[JDate(1.0),JDate(1.5),JDate(2.0)] Note that a couple of your methods were incorrect, like the / and * methods returning a Float64 object. On Tuesday, May 19, 2015 at 4:47:27 PM UTC-4, Chris wrote: I've been playing for a while now, and I'm hitting a wall. I decided to > keep the FloatingPoint subtype, and step through and define all the > necessary conversion/promotion rules, operations, etc. Here is what I have > now: > > immutable JDate <:FloatingPoint > t::Float64 > end > > convert(::Type{JDate}, x::Float64) = JDate(x) > convert(::Type{JDate}, x::Int64) = JDate(float64(x)) > convert(::Type{Float64}, x::JDate) = x.t > convert(::Type{Int64}, x::JDate) = int64(x.t) > > promote_rule(::Type{JDate}, ::Type{Float64}) = JDate > promote_rule(::Type{JDate}, ::Type{Int64}) = JDate > <(a::JDate,b::JDate) = <(float64(a),float64(b)) > +(a::JDate,b::JDate) = JDate(float(a.t) + float(b.t)) > -(a::JDate,b::JDate) = float(a.t) - float(b.t) > /(a::JDate,b::JDate) = /(float64(a),float64(b)) > *(a::JDate,b::JDate) = *(float64(a),float64(b)) > round(a::JDate) = JDate(round(float64(a))) > nextfloat(a::JDate) = JDate(nextfloat(float64(a))) > nextfloat(a::JDate,b::Int64) = JDate(nextfloat(float64(a),b)) > > Then, > julia> [j1:.5:j2] > ERROR: stack overflow > in <= at promotion.jl:170 (repeats 80000 times) > > Any insight into why this is happening? > > Thanks, > Chris > > On Thursday, May 14, 2015 at 3:48:48 AM UTC-10, Josh Langsfeld wrote: >> >> If you do decide to keep it as a FloatingPoint subtype, you should >> probably go the other route of just making sure it interacts natively with >> the standard core operators, promote, convert, etc... Then the colon syntax >> should work automatically, returning a FloatRange{JDate} (which can become >> an Array{JDate,1} via collect()). >> >> On Wed, May 13, 2015 at 9:06 PM, Chris <7hunde...@gmail.com> wrote: >> >>> Now that you mention it, I think the only reason I made it a subtype of >>> FloatingPoint was some (very) vague notion of type inference and >>> performance. I will re-examine that decision now, I think. Thanks for your >>> help. >>> >>> Chris >>> >>> >>> On Wednesday, May 13, 2015 at 2:30:53 PM UTC-4, Josh Langsfeld wrote: >>>> >>>> Yeah, I missed that you were subtyping FloatingPoint before. It still >>>> worked ok for me though once I also defined colon methods suggested by the >>>> ambiguity warnings. in my case it was: >>>> >>>> colon(::JDate, ::JDate, ::JDate) >>>> colon(::JDate, ::FloatingPoint, ::JDate) >>>> colon(::JDate, ::Real, ::JDate) >>>> >>>> It seems to cause a lot of problems to subtype it as a FloatingPoint >>>> though, and I'm not sure what benefit you are getting out of it. For >>>> example, my installation won't even print a JDate value because it checks >>>> for finiteness first which requires subtraction to be defined. But I >>>> assume >>>> you can work around that by just defining enough methods of operators and >>>> promotion rules. >>>> >>>> On Wednesday, May 13, 2015 at 12:29:30 PM UTC-4, Chris wrote: >>>>> >>>>> What should the new method be, precisely? I tried colon(start::JDate, >>>>> step::Real, stop::JDate) = JDate(colon(float64(start),step,float64(stop)) >>>>> (I >>>>> have conversion rules defined for the JDate to Float64 conversions), but >>>>> I >>>>> get several warning messages of the form: >>>>> >>>>> Warning: New definition >>>>> colon(JDate,Real,JDate) at <path>\types.jl:25 >>>>> is ambiguous with: >>>>> colon(T<:FloatingPoint,T<:FloatingPoint,T<:FloatingPoint) at >>>>> range.jl:122. >>>>> To fix, define >>>>> colon(JDate,JDate,JDate) >>>>> before the new definition. >>>>> >>>>> Then, when I test this, I still get a Array{Float64,1}. >>>>> >>>>> Thanks, >>>>> Chris >>>>> >>>>> On Wednesday, May 13, 2015 at 12:05:19 PM UTC-4, Josh Langsfeld wrote: >>>>>> >>>>>> I believe you only need to add a method to Base.colon of the form >>>>>> 'colon(start::JDate, step::Real, stop::JDate)' >>>>>> >>>>>> I just tested it and that was the only thing needed to make the the >>>>>> [J1:s:J2] syntax work. >>>>>> >>>>>> On Wednesday, May 13, 2015 at 11:13:53 AM UTC-4, Chris wrote: >>>>>>> >>>>>>> I have a simple custom type called JDate: >>>>>>> >>>>>>> immutable JDate <: FloatingPoint >>>>>>> >>>>>>> t::Float64 >>>>>>> >>>>>>> end >>>>>>> >>>>>>> When I construct a range, e.g. [J1:s:J2], where J1::JDate, s::Real, >>>>>>> J2::JDate, I'd like the result to be an Array{JDate,1}. What >>>>>>> conversion/promotion rules are necessary to do this? >>>>>>> >>>>>>> Thanks in advance, >>>>>>> Chris >>>>>>> >>>>>> >>