f(a::Any, b) = "fallback" f(a::Number, b::Number) = "a and b are both numbers" f(a::Number, b) = "a is a number" f(a, b::Number) = "b is a number" f(a::Integer, b::Integer) = "a and b are both integers" f(1.5,2) f(1,"bar") f(1,2) f("foo",[1,2]) f{T<:Number}(a::T, b::T) = "a and b are both $(T)s" f(big(1.5),big(2.5)) f(big(1),big(2)) #<== integer rule is more specific f("foo","bar") #<== still doesn't apply to non-numbers f(args::Number...) = "$(length(args))-ary heterogeneous call" f{T<:Number}(args::T...) = "$(length(args))-ary homogeneous call" f(1) f(1,2,3) f(1,1.5,2) f() #==> why is it heterogeneous not homogeneous? f(1,2) #<== previous 2-arg method is more specific f("foo") #<== doesn't apply to non-numbers f methods(f) typeof(f) f2(x) = f(x,x) f2("foo") f(a::String, b::String) = "a and b are both strings"; f2(x) = f(x,x) #<== to reset method cache (issue #265) f2("foo") immutable Interval{T<:Real} <: Number lo::T hi::T end (a::Real)..(b::Real) = Interval(a,b) Base.show(io::IO, iv::Interval) = print(io, "($(iv.lo))..($(iv.hi))") 1..2 typeof(ans) sizeof(1..2) #==> two 8-byte ints (1.5)..(2.5) typeof(ans) (1//2)..(2//3) typeof(ans) sizeof((1//2)..(2//3)) #==> just four 8-byte ints methods(Interval) #(0.5)..(1) #<== would be a no method error because of mixed types Interval(lo::Real, hi::Real) = Interval(promote(lo,hi)...) (0.5)..1 1..pi e..pi a::Interval + b::Interval = (a.lo + b.lo)..(a.hi + b.hi) a::Interval - b::Interval = (a.lo - b.hi)..(a.hi - b.lo) (2..3) + (-1..1) (2..3) - (1..2) import Base: convert, promote_rule #<== allows extending them convert{T<:Real}(::Type{Interval{T}}, x::Real) = (x = convert(T,x); x..x) convert{T<:Real}(::Type{Interval{T}}, iv::Interval) = convert(T,iv.lo)..convert(T,iv.hi) promote_rule{A<:Real,B<:Real}(::Type{Interval{A}}, ::Type{B}) = Interval{promote_type(A,B)} promote_rule{A<:Real,B<:Real}(::Type{Interval{A}}, ::Type{Interval{B}}) = Interval{promote_type(A,B)} 1..2 + 1 1..2 + 1.5 3 - 1..2 + 2//3 big(2)^100 + (1//3)..(2//3) big(2)^100 + (1//3)..(2//3) typeof(ans) @which big(2)^100 + (1//3)..(2//3) big(2)^100 typeof(ans) typeof((1//3)..(2//3)) promote_type(Interval{Rational{Int64}}, BigInt) convert(Interval{Rational{BigInt}}, big(2)^100) convert(Interval{Rational{BigInt}}, (1//3)..(2//3)) :(2 ± 1) 2 ± 1 a::Real ± b::Real = (a - b)..(a + b) a::Interval ± b::Interval = (a.lo - b.hi)..(a.hi + b.hi) a::Number ± b::Number = ±(promote(a,b)...) 1 ± 2 pi - (2 ± 1//2) + code_llvm(+,(Int,Int)) code_llvm(+,(Int,Float64)) lo(a,b) = (a ± b).lo hi(a,b) = (a ± b).hi lo(3,2), hi(3,2) code_llvm(lo,(Int,Int)) code_llvm(hi,(Int,Int)) code_native(hi,(Float64,Rational{Int})) methods(split) split("foobarbazqux", r"[aeiou]+"i)