function fib(n) if n < 2 return n else return fib(n-1) + fib(n-2) end end fib(n) = n < 2 ? n : fib(n - 1) + fib(n - 2) fib(30) @time fib(26) A = randn(10,10) b = randn(10,10) x = A \ b A*x - b eps() round(A*x-b, 12) fft(A) f(a, 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]) methods(f) 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() #==> heterogeneous because we can't bind T f(1,2) #<== previous 2-arg method is more specific f("foo") #<== doesn't apply to non-numbers module ModInts export ModInt import Base: convert, promote_rule, show, showcompact immutable ModInt{n} <: Integer k::Int ModInt(k) = new(k % n) end -{n2}(a::ModInt{n2}) = ModInt{n2}(-a.k) +{n}(a::ModInt{n}, b::ModInt{n}) = ModInt{n}(a.k+b.k) -{n}(a::ModInt{n}, b::ModInt{n}) = ModInt{n}(a.k-b.k) *{n}(a::ModInt{n}, b::ModInt{n}) = ModInt{n}(a.k*b.k) convert{n}(::Type{ModInt{n}}, i::Int) = ModInt{n}(i) promote_rule{n}(::Type{ModInt{n}}, ::Type{Int}) = ModInt{n} show{n}(io::IO, k::ModInt{n}) = print(io, "$(k.k) mod $n") showcompact(io::IO, k::ModInt) = print(io, k.k) end # module using ModInts ModInt ModInt{11} a=ModInt{11}(12345532425) b=ModInt{11}(23445134156) a+b a+b+b a+1 2a 2a+1 A = map(ModInt{11}, rand(1:1000, 5,5)) A^2 A^10000000 B = map(ModInt{11}, rand(1:1000, 5,5)) A+B foo{n}(a::ModInt{n}, b::ModInt{n}) = a^2 + 2b - 1 foo{n}(a::ModInt{n}, b::Int) = foo(a, ModInt{n}(b)) foo{n}(a::Int, b::ModInt{n}) = foo(ModInt{n}(a), b) foo(a::Int, b::Int) = foo(ModInt{11}(a), ModInt{11}(b)).k foo(3,4) code_llvm(foo,(Int,Int)) using Gadfly @plot(cos(x)/x, 5, 25)