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
>>>>>>>
>>>>>>
>>  ​

Reply via email to