From 679175202f30808991c28d07188cb9309a4fdc78 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Sun, 29 Jan 2017 00:45:30 -0500 Subject: [PATCH] deprecate special "inner constructor" syntax. part of #11310 --- NEWS.md | 12 +++++++ base/LineEdit.jl | 9 +++--- base/atomics.jl | 4 +-- base/base.jl | 4 +-- base/bitarray.jl | 4 +-- base/boot.jl | 4 +-- base/channels.jl | 8 ++--- base/dft.jl | 6 ++-- base/dict.jl | 54 +++++++++++++++---------------- base/fft/FFTW.jl | 4 +-- base/fft/dct.jl | 2 +- base/iobuffer.jl | 8 +++-- base/linalg/arnoldi.jl | 4 +-- base/linalg/bidiag.jl | 8 ++--- base/linalg/eigen.jl | 12 ++++--- base/linalg/hessenberg.jl | 7 ++-- base/linalg/lq.jl | 8 ++--- base/linalg/lu.jl | 4 +-- base/linalg/qr.jl | 22 +++++++------ base/linalg/rowvector.jl | 14 ++++---- base/linalg/schur.jl | 14 +++++--- base/linalg/svd.jl | 15 ++++++--- base/linalg/tridiag.jl | 6 ++-- base/methodshow.jl | 18 ++++++++--- base/multidimensional.jl | 18 +++++------ base/multinverses.jl | 4 +-- base/parallel/clusterserialize.jl | 6 ++-- base/parallel/remotecall.jl | 5 ++- base/permuteddimsarray.jl | 4 +-- base/range.jl | 8 ++--- base/refpointer.jl | 8 ++--- base/replutil.jl | 4 +-- base/serialize.jl | 2 +- base/set.jl | 4 +-- base/sharedarray.jl | 2 +- base/show.jl | 13 ++++++-- base/sparse/cholmod.jl | 12 +++---- base/sparse/sparsematrix.jl | 3 +- base/sparse/sparsevector.jl | 4 +-- base/sparse/spqr.jl | 4 +-- base/subarray.jl | 6 ++-- base/weakkeydict.jl | 30 ++++++++--------- doc/src/manual/constructors.md | 32 +++++++++--------- doc/src/manual/methods.md | 29 +++++++++++------ examples/ModInts.jl | 2 +- examples/lru.jl | 6 ++-- src/ast.scm | 5 ++- src/julia-parser.scm | 4 +-- src/julia-syntax.scm | 3 ++ test/abstractarray.jl | 12 ++++--- test/core.jl | 16 ++++----- test/inference.jl | 2 +- test/keywordargs.jl | 2 +- test/reflection.jl | 2 +- test/replutil.jl | 14 ++++---- test/show.jl | 2 +- test/vecelement.jl | 2 +- test/worlds.jl | 2 +- 58 files changed, 298 insertions(+), 225 deletions(-) diff --git a/NEWS.md b/NEWS.md index 29efbed34761d..a4b9367999d1c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -22,6 +22,18 @@ New language features Language changes ---------------- + * "Inner constructor" syntax for parametric types is deprecated. For example, + in this definition: + ``` + type Foo{T,S<:Real} + x + Foo(x) = new(x) + end + ``` + the syntax `Foo(x) = new(x)` actually defined a constructor for `Foo{T,S}`, + i.e. the case where the type parameters are specified. For clarity, this + definition now must be written as `Foo{T,S}(x) where {T,S<:Real} = new(x)`. ([#11310]) + * Multi-line and single-line nonstandard command literals have been added. A nonstandard command literal is like a nonstandard string literal, but the syntax uses backquotes (``` ` ```) instead of double quotes, and the diff --git a/base/LineEdit.jl b/base/LineEdit.jl index f497e76f7f43c..6a76f05f333ab 100644 --- a/base/LineEdit.jl +++ b/base/LineEdit.jl @@ -1014,10 +1014,10 @@ type HistoryPrompt{T<:HistoryProvider} <: TextInterface hp::T complete keymap_dict::Dict{Char,Any} - HistoryPrompt(hp) = new(hp, EmptyCompletionProvider()) + HistoryPrompt{T}(hp) where T<:HistoryProvider = new(hp, EmptyCompletionProvider()) end -HistoryPrompt{T<:HistoryProvider}(hp::T) = HistoryPrompt{T}(hp) +HistoryPrompt(hp::T) where T<:HistoryProvider = HistoryPrompt{T}(hp) init_state(terminal, p::HistoryPrompt) = SearchState(terminal, p, true, IOBuffer(), IOBuffer()) type PrefixSearchState <: ModeState @@ -1054,10 +1054,11 @@ type PrefixHistoryPrompt{T<:HistoryProvider} <: TextInterface parent_prompt::Prompt complete keymap_dict::Dict{Char,Any} - PrefixHistoryPrompt(hp, parent_prompt) = new(hp, parent_prompt, EmptyCompletionProvider()) + PrefixHistoryPrompt{T}(hp, parent_prompt) where T<:HistoryProvider = + new(hp, parent_prompt, EmptyCompletionProvider()) end -PrefixHistoryPrompt{T<:HistoryProvider}(hp::T, parent_prompt) = PrefixHistoryPrompt{T}(hp, parent_prompt) +PrefixHistoryPrompt(hp::T, parent_prompt) where T<:HistoryProvider = PrefixHistoryPrompt{T}(hp, parent_prompt) init_state(terminal, p::PrefixHistoryPrompt) = PrefixSearchState(terminal, p, "", IOBuffer()) write_prompt(terminal, s::PrefixSearchState) = write_prompt(terminal, s.histprompt.parent_prompt) diff --git a/base/atomics.jl b/base/atomics.jl index f2cd218d9a607..676059ae56d17 100644 --- a/base/atomics.jl +++ b/base/atomics.jl @@ -58,8 +58,8 @@ Atomic operations use an `atomic_` prefix, such as `atomic_add!`, """ type Atomic{T<:AtomicTypes} value::T - Atomic() = new(zero(T)) - Atomic(value) = new(value) + Atomic{T}() where T<:AtomicTypes = new(zero(T)) + Atomic{T}(value) where T<:AtomicTypes = new(value) end Atomic() = Atomic{Int}() diff --git a/base/base.jl b/base/base.jl index 45d8de10d8281..403863bf33fa0 100644 --- a/base/base.jl +++ b/base/base.jl @@ -152,6 +152,6 @@ immutable Nullable{T} hasvalue::Bool value::T - Nullable() = new(false) - Nullable(value::T, hasvalue::Bool=true) = new(hasvalue, value) + Nullable{T}() where T = new(false) + Nullable{T}(value::T, hasvalue::Bool=true) where T = new(hasvalue, value) end diff --git a/base/bitarray.jl b/base/bitarray.jl index efb2381a5c53a..3cea7cb4e1706 100644 --- a/base/bitarray.jl +++ b/base/bitarray.jl @@ -8,7 +8,7 @@ type BitArray{N} <: DenseArray{Bool, N} chunks::Vector{UInt64} len::Int dims::NTuple{N,Int} - function BitArray(dims::Vararg{Int,N}) + function BitArray{N}(dims::Vararg{Int,N}) where N n = 1 i = 1 for d in dims @@ -36,7 +36,7 @@ Construct an uninitialized `BitArray` with the given dimensions. Behaves identically to the [`Array`](@ref) constructor. """ BitArray(dims::Integer...) = BitArray(map(Int,dims)) -BitArray{N}(dims::NTuple{N,Int}) = BitArray{N}(dims...) +BitArray(dims::NTuple{N,Int}) where N = BitArray{N}(dims...) typealias BitVector BitArray{1} typealias BitMatrix BitArray{2} diff --git a/base/boot.jl b/base/boot.jl index 20f786d6415e5..7c1e5c1e59b4d 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -269,9 +269,9 @@ Void() = nothing immutable VecElement{T} value::T - VecElement(value::T) = new(value) # disable converting constructor in Core + VecElement{T}(value::T) where T = new(value) # disable converting constructor in Core end -VecElement{T}(arg::T) = VecElement{T}(arg) +VecElement(arg::T) where T = VecElement{T}(arg) # used by lowering of splicing unquote splicedexpr(hd::Symbol, args::Array{Any,1}) = (e=Expr(hd); e.args=args; e) diff --git a/base/channels.jl b/base/channels.jl index 61cdf753568d3..84ee87ff9a9c8 100644 --- a/base/channels.jl +++ b/base/channels.jl @@ -29,14 +29,14 @@ type Channel{T} <: AbstractChannel # Used when sz_max == 0, i.e., an unbuffered channel. takers::Array{Condition} - function Channel(sz::Float64) + function Channel{T}(sz::Float64) where T if sz == Inf Channel{T}(typemax(Int)) else Channel{T}(convert(Int, sz)) end end - function Channel(sz::Integer) + function Channel{T}(sz::Integer) where T if sz < 0 throw(ArgumentError("Channel size must be either 0, a positive integer or Inf")) end @@ -44,7 +44,7 @@ type Channel{T} <: AbstractChannel end # deprecated empty constructor - function Channel() + function Channel{T}() where T depwarn(string("The empty constructor Channel() is deprecated. ", "The channel size needs to be specified explictly. ", "Defaulting to Channel{$T}(32)."), :Channel) @@ -364,7 +364,7 @@ show(io::IO, c::Channel) = print(io, "$(typeof(c))(sz_max:$(c.sz_max),sz_curr:$( type ChannelIterState{T} hasval::Bool val::T - ChannelIterState(x) = new(x) + ChannelIterState{T}(has::Bool) where T = new(has) end start{T}(c::Channel{T}) = ChannelIterState{T}(false) diff --git a/base/dft.jl b/base/dft.jl index b676dee045b85..304c8b4e6da97 100644 --- a/base/dft.jl +++ b/base/dft.jl @@ -241,10 +241,10 @@ type ScaledPlan{T,P,N} <: Plan{T} p::P scale::N # not T, to avoid unnecessary promotion to Complex pinv::Plan - ScaledPlan(p, scale) = new(p, scale) + ScaledPlan{T,P,N}(p, scale) where {T,P,N} = new(p, scale) end -(::Type{ScaledPlan{T}}){T,P,N}(p::P, scale::N) = ScaledPlan{T,P,N}(p, scale) -ScaledPlan{T}(p::Plan{T}, scale::Number) = ScaledPlan{T}(p, scale) +ScaledPlan{T}(p::P, scale::N) where {T,P,N} = ScaledPlan{T,P,N}(p, scale) +ScaledPlan(p::Plan{T}, scale::Number) where T = ScaledPlan{T}(p, scale) ScaledPlan(p::ScaledPlan, α::Number) = ScaledPlan(p.p, p.scale * α) size(p::ScaledPlan) = size(p.p) diff --git a/base/dict.jl b/base/dict.jl index 722b2be8bfdfe..9fb2fdfe9b7e5 100644 --- a/base/dict.jl +++ b/base/dict.jl @@ -99,27 +99,11 @@ type Dict{K,V} <: Associative{K,V} idxfloor::Int # an index <= the indexes of all used slots maxprobe::Int - function Dict() + function Dict{K,V}() where V where K n = 16 new(zeros(UInt8,n), Array{K,1}(n), Array{V,1}(n), 0, 0, 0, 1, 0) end - function Dict(kv) - h = Dict{K,V}() - for (k,v) in kv - h[k] = v - end - return h - end - Dict(p::Pair) = setindex!(Dict{K,V}(), p.second, p.first) - function Dict(ps::Pair...) - h = Dict{K,V}() - sizehint!(h, length(ps)) - for p in ps - h[p.first] = p.second - end - return h - end - function Dict(d::Dict{K,V}) + function Dict{K,V}(d::Dict{K,V}) where V where K if d.ndel > 0 rehash!(d) end @@ -128,6 +112,22 @@ type Dict{K,V} <: Associative{K,V} d.maxprobe) end end +function Dict{K,V}(kv) where V where K + h = Dict{K,V}() + for (k,v) in kv + h[k] = v + end + return h +end +Dict{K,V}(p::Pair) where V where K = setindex!(Dict{K,V}(), p.second, p.first) +function Dict{K,V}(ps::Pair...) where V where K + h = Dict{K,V}() + sizehint!(h, length(ps)) + for p in ps + h[p.first] = p.second + end + return h +end # Note the constructors of WeakKeyDict mirror these here, keep in sync. Dict() = Dict{Any,Any}() Dict(kv::Tuple{}) = Dict() @@ -135,10 +135,10 @@ copy(d::Dict) = Dict(d) const AnyDict = Dict{Any,Any} -Dict{K,V}(ps::Pair{K,V}...) = Dict{K,V}(ps) -Dict{K }(ps::Pair{K}...,) = Dict{K,Any}(ps) -Dict{V }(ps::(Pair{K,V} where K)...,) = Dict{Any,V}(ps) -Dict( ps::Pair...) = Dict{Any,Any}(ps) +Dict(ps::Pair{K,V}...) where {K,V} = Dict{K,V}(ps) +Dict(ps::Pair{K}...,) where K = Dict{K,Any}(ps) +Dict(ps::(Pair{K,V} where K)...,) where V = Dict{Any,V}(ps) +Dict(ps::Pair...) = Dict{Any,Any}(ps) function Dict(kv) try @@ -599,9 +599,9 @@ immutable ImmutableDict{K, V} <: Associative{K,V} parent::ImmutableDict{K, V} key::K value::V - ImmutableDict() = new() # represents an empty dictionary - ImmutableDict(key, value) = (empty = new(); new(empty, key, value)) - ImmutableDict(parent::ImmutableDict, key, value) = new(parent, key, value) + ImmutableDict{K,V}() where {K,V} = new() # represents an empty dictionary + ImmutableDict{K,V}(key, value) where {K,V} = (empty = new(); new(empty, key, value)) + ImmutableDict{K,V}(parent::ImmutableDict, key, value) where {K,V} = new(parent, key, value) end """ @@ -621,8 +621,8 @@ Create a new entry in the Immutable Dictionary for the key => value pair """ ImmutableDict -ImmutableDict{K,V}(KV::Pair{K,V}) = ImmutableDict{K,V}(KV[1], KV[2]) -ImmutableDict{K,V}(t::ImmutableDict{K,V}, KV::Pair) = ImmutableDict{K,V}(t, KV[1], KV[2]) +ImmutableDict(KV::Pair{K,V}) where {K,V} = ImmutableDict{K,V}(KV[1], KV[2]) +ImmutableDict(t::ImmutableDict{K,V}, KV::Pair) where {K,V} = ImmutableDict{K,V}(t, KV[1], KV[2]) function in(key_value::Pair, dict::ImmutableDict, valcmp=(==)) key, value = key_value diff --git a/base/fft/FFTW.jl b/base/fft/FFTW.jl index 502399f9a4398..4a595e2e937bf 100644 --- a/base/fft/FFTW.jl +++ b/base/fft/FFTW.jl @@ -211,8 +211,8 @@ for P in (:cFFTWPlan, :rFFTWPlan, :r2rFFTWPlan) # complex, r2c/c2r, and r2r flags::UInt32 # planner flags region::Any # region (iterable) of dims that are transormed pinv::ScaledPlan - function $P(plan::PlanPtr, flags::Integer, R::Any, - X::StridedArray{T, N}, Y::StridedArray) + function $P{T,K,inplace,N}(plan::PlanPtr, flags::Integer, R::Any, + X::StridedArray{T, N}, Y::StridedArray) where {T<:fftwNumber,K,inplace,N} p = new(plan, size(X), size(Y), strides(X), strides(Y), alignment_of(X), alignment_of(Y), flags, R) finalizer(p, destroy_plan) diff --git a/base/fft/dct.jl b/base/fft/dct.jl index 00e8675ffac97..f97f52ee3be0f 100644 --- a/base/fft/dct.jl +++ b/base/fft/dct.jl @@ -15,7 +15,7 @@ type DCTPlan{T<:fftwNumber,K,inplace} <: Plan{T} nrm::Float64 # normalization factor region::Dims # dimensions being transformed pinv::DCTPlan{T} - DCTPlan(plan,r,nrm,region) = new(plan,r,nrm,region) + DCTPlan{T,K,inplace}(plan,r,nrm,region) where {T<:fftwNumber,K,inplace} = new(plan,r,nrm,region) end size(p::DCTPlan) = size(p.plan) diff --git a/base/iobuffer.jl b/base/iobuffer.jl index a77c2f82bebf5..72af09462d340 100644 --- a/base/iobuffer.jl +++ b/base/iobuffer.jl @@ -14,13 +14,17 @@ type AbstractIOBuffer{T<:AbstractVector{UInt8}} <: IO ptr::Int # read (and maybe write) pointer mark::Int # reset mark location for ptr (or <0 for no mark) - AbstractIOBuffer(data::T,readable::Bool,writable::Bool,seekable::Bool,append::Bool,maxsize::Int) = + function AbstractIOBuffer{T}(data::T, readable::Bool, writable::Bool, seekable::Bool, append::Bool, + maxsize::Int) where T<:AbstractVector{UInt8} new(data,readable,writable,seekable,append,length(data),maxsize,1,-1) + end end typealias IOBuffer AbstractIOBuffer{Vector{UInt8}} -AbstractIOBuffer{T<:AbstractVector{UInt8}}(data::T, readable::Bool, writable::Bool, seekable::Bool, append::Bool, maxsize::Int) = +function AbstractIOBuffer(data::T, readable::Bool, writable::Bool, seekable::Bool, append::Bool, + maxsize::Int) where T<:AbstractVector{UInt8} AbstractIOBuffer{T}(data, readable, writable, seekable, append, maxsize) +end # allocate Vector{UInt8}s for IOBuffer storage that can efficiently become Strings StringVector(n::Integer) = Vector{UInt8}(_string_n(n)) diff --git a/base/linalg/arnoldi.jl b/base/linalg/arnoldi.jl index d6df493e79901..e85a82fb47c56 100644 --- a/base/linalg/arnoldi.jl +++ b/base/linalg/arnoldi.jl @@ -288,10 +288,10 @@ type SVDOperator{T<:BlasFloat,S} <: AbstractArray{T, 2} X::S m::Int n::Int - SVDOperator(X::AbstractMatrix) = new(X, size(X, 1), size(X, 2)) + SVDOperator{T,S}(X::AbstractMatrix) where {T<:BlasFloat,S} = new(X, size(X, 1), size(X, 2)) end -function SVDOperator{T}(A::AbstractMatrix{T}) +function SVDOperator(A::AbstractMatrix{T}) where T Tnew = typeof(zero(T)/sqrt(one(T))) Anew = convert(AbstractMatrix{Tnew}, A) SVDOperator{Tnew,typeof(Anew)}(Anew) diff --git a/base/linalg/bidiag.jl b/base/linalg/bidiag.jl index f040cd127c27d..02c91e2f05cdc 100644 --- a/base/linalg/bidiag.jl +++ b/base/linalg/bidiag.jl @@ -5,7 +5,7 @@ type Bidiagonal{T} <: AbstractMatrix{T} dv::Vector{T} # diagonal ev::Vector{T} # sub/super diagonal isupper::Bool # is upper bidiagonal (true) or lower (false) - function Bidiagonal(dv::Vector{T}, ev::Vector{T}, isupper::Bool) + function Bidiagonal{T}(dv::Vector{T}, ev::Vector{T}, isupper::Bool) where T if length(ev) != length(dv)-1 throw(DimensionMismatch("length of diagonal vector is $(length(dv)), length of off-diagonal vector is $(length(ev))")) end @@ -52,7 +52,7 @@ julia> Bl = Bidiagonal(dv, ev, false) # ev is on the first subdiagonal ⋅ ⋅ 9 4 ``` """ -Bidiagonal{T}(dv::AbstractVector{T}, ev::AbstractVector{T}, isupper::Bool) = Bidiagonal{T}(collect(dv), collect(ev), isupper) +Bidiagonal(dv::AbstractVector{T}, ev::AbstractVector{T}, isupper::Bool) where T = Bidiagonal{T}(collect(dv), collect(ev), isupper) Bidiagonal(dv::AbstractVector, ev::AbstractVector) = throw(ArgumentError("did you want an upper or lower Bidiagonal? Try again with an additional true (upper) or false (lower) argument.")) """ @@ -106,7 +106,7 @@ Bidiagonal(dv::AbstractVector, ev::AbstractVector, uplo::Char) = begin end Bidiagonal(collect(dv), collect(ev), isupper) end -function Bidiagonal{Td,Te}(dv::AbstractVector{Td}, ev::AbstractVector{Te}, isupper::Bool) +function Bidiagonal(dv::AbstractVector{Td}, ev::AbstractVector{Te}, isupper::Bool) where {Td,Te} T = promote_type(Td,Te) Bidiagonal(convert(Vector{T}, dv), convert(Vector{T}, ev), isupper) end @@ -197,7 +197,7 @@ full(A::Bidiagonal) = convert(Array, A) promote_rule{T,S}(::Type{Matrix{T}}, ::Type{Bidiagonal{S}})=Matrix{promote_type(T,S)} #Converting from Bidiagonal to Tridiagonal -Tridiagonal{T}(M::Bidiagonal{T}) = convert(Tridiagonal{T}, M) +Tridiagonal(M::Bidiagonal{T}) where T = convert(Tridiagonal{T}, M) function convert{T}(::Type{Tridiagonal{T}}, A::Bidiagonal) z = zeros(T, size(A)[1]-1) A.isupper ? Tridiagonal(z, convert(Vector{T},A.dv), convert(Vector{T},A.ev)) : Tridiagonal(convert(Vector{T},A.ev), convert(Vector{T},A.dv), z) diff --git a/base/linalg/eigen.jl b/base/linalg/eigen.jl index 423c2a224b19c..87ff0da9804cb 100644 --- a/base/linalg/eigen.jl +++ b/base/linalg/eigen.jl @@ -4,17 +4,21 @@ immutable Eigen{T,V,S<:AbstractMatrix,U<:AbstractVector} <: Factorization{T} values::U vectors::S - Eigen(values::AbstractVector{V}, vectors::AbstractMatrix{T}) = new(values, vectors) + Eigen{T,V,S,U}(values::AbstractVector{V}, vectors::AbstractMatrix{T}) where {T,V,S,U} = + new(values, vectors) end -Eigen{T,V}(values::AbstractVector{V}, vectors::AbstractMatrix{T}) = Eigen{T,V,typeof(vectors),typeof(values)}(values, vectors) +Eigen(values::AbstractVector{V}, vectors::AbstractMatrix{T}) where {T,V} = + Eigen{T,V,typeof(vectors),typeof(values)}(values, vectors) # Generalized eigenvalue problem. immutable GeneralizedEigen{T,V,S<:AbstractMatrix,U<:AbstractVector} <: Factorization{T} values::U vectors::S - GeneralizedEigen(values::AbstractVector{V}, vectors::AbstractMatrix{T}) = new(values, vectors) + GeneralizedEigen{T,V,S,U}(values::AbstractVector{V}, vectors::AbstractMatrix{T}) where {T,V,S,U} = + new(values, vectors) end -GeneralizedEigen{T,V}(values::AbstractVector{V}, vectors::AbstractMatrix{T}) = GeneralizedEigen{T,V,typeof(vectors),typeof(values)}(values, vectors) +GeneralizedEigen(values::AbstractVector{V}, vectors::AbstractMatrix{T}) where {T,V} = + GeneralizedEigen{T,V,typeof(vectors),typeof(values)}(values, vectors) function getindex(A::Union{Eigen,GeneralizedEigen}, d::Symbol) diff --git a/base/linalg/hessenberg.jl b/base/linalg/hessenberg.jl index a51aae6455091..f32f3544c899b 100644 --- a/base/linalg/hessenberg.jl +++ b/base/linalg/hessenberg.jl @@ -3,9 +3,10 @@ immutable Hessenberg{T,S<:AbstractMatrix} <: Factorization{T} factors::S τ::Vector{T} - Hessenberg(factors::AbstractMatrix{T}, τ::Vector{T}) = new(factors, τ) + Hessenberg{T,S}(factors::AbstractMatrix{T}, τ::Vector{T}) where {T,S<:AbstractMatrix} = + new(factors, τ) end -Hessenberg{T}(factors::AbstractMatrix{T}, τ::Vector{T}) = Hessenberg{T,typeof(factors)}(factors, τ) +Hessenberg(factors::AbstractMatrix{T}, τ::Vector{T}) where T = Hessenberg{T,typeof(factors)}(factors, τ) Hessenberg(A::StridedMatrix) = Hessenberg(LAPACK.gehrd!(A)...) @@ -55,7 +56,7 @@ end immutable HessenbergQ{T,S<:AbstractMatrix} <: AbstractMatrix{T} factors::S τ::Vector{T} - HessenbergQ(factors::AbstractMatrix{T}, τ::Vector{T}) = new(factors, τ) + HessenbergQ{T,S}(factors::AbstractMatrix{T}, τ::Vector{T}) where {T,S<:AbstractMatrix} = new(factors, τ) end HessenbergQ{T}(factors::AbstractMatrix{T}, τ::Vector{T}) = HessenbergQ{T,typeof(factors)}(factors, τ) HessenbergQ(A::Hessenberg) = HessenbergQ(A.factors, A.τ) diff --git a/base/linalg/lq.jl b/base/linalg/lq.jl index 81d06d2d6cd4d..c8f5dde2e96cc 100644 --- a/base/linalg/lq.jl +++ b/base/linalg/lq.jl @@ -5,17 +5,17 @@ immutable LQ{T,S<:AbstractMatrix} <: Factorization{T} factors::S τ::Vector{T} - LQ(factors::AbstractMatrix{T}, τ::Vector{T}) = new(factors, τ) + LQ{T,S}(factors::AbstractMatrix{T}, τ::Vector{T}) where {T,S<:AbstractMatrix} = new(factors, τ) end immutable LQPackedQ{T,S<:AbstractMatrix} <: AbstractMatrix{T} factors::Matrix{T} τ::Vector{T} - LQPackedQ(factors::AbstractMatrix{T}, τ::Vector{T}) = new(factors, τ) + LQPackedQ{T,S}(factors::AbstractMatrix{T}, τ::Vector{T}) where {T,S<:AbstractMatrix} = new(factors, τ) end -LQ{T}(factors::AbstractMatrix{T}, τ::Vector{T}) = LQ{T,typeof(factors)}(factors, τ) -LQPackedQ{T}(factors::AbstractMatrix{T}, τ::Vector{T}) = LQPackedQ{T,typeof(factors)}(factors, τ) +LQ(factors::AbstractMatrix{T}, τ::Vector{T}) where T = LQ{T,typeof(factors)}(factors, τ) +LQPackedQ(factors::AbstractMatrix{T}, τ::Vector{T}) where T = LQPackedQ{T,typeof(factors)}(factors, τ) """ lqfact!(A) -> LQ diff --git a/base/linalg/lu.jl b/base/linalg/lu.jl index d00cdf2eddead..c06113f09be69 100644 --- a/base/linalg/lu.jl +++ b/base/linalg/lu.jl @@ -7,9 +7,9 @@ immutable LU{T,S<:AbstractMatrix} <: Factorization{T} factors::S ipiv::Vector{BlasInt} info::BlasInt - LU(factors::AbstractMatrix{T}, ipiv::Vector{BlasInt}, info::BlasInt) = new(factors, ipiv, info) + LU{T,S}(factors::AbstractMatrix{T}, ipiv::Vector{BlasInt}, info::BlasInt) where {T,S} = new(factors, ipiv, info) end -LU{T}(factors::AbstractMatrix{T}, ipiv::Vector{BlasInt}, info::BlasInt) = LU{T,typeof(factors)}(factors, ipiv, info) +LU(factors::AbstractMatrix{T}, ipiv::Vector{BlasInt}, info::BlasInt) where T = LU{T,typeof(factors)}(factors, ipiv, info) # StridedMatrix function lufact!{T<:BlasFloat}(A::StridedMatrix{T}, pivot::Union{Type{Val{false}}, Type{Val{true}}} = Val{true}) diff --git a/base/linalg/qr.jl b/base/linalg/qr.jl index 49464e75c5edc..4906d39dafae8 100644 --- a/base/linalg/qr.jl +++ b/base/linalg/qr.jl @@ -5,24 +5,26 @@ immutable QR{T,S<:AbstractMatrix} <: Factorization{T} factors::S τ::Vector{T} - QR(factors::AbstractMatrix{T}, τ::Vector{T}) = new(factors, τ) + QR{T,S}(factors::AbstractMatrix{T}, τ::Vector{T}) where {T,S<:AbstractMatrix} = new(factors, τ) end -QR{T}(factors::AbstractMatrix{T}, τ::Vector{T}) = QR{T,typeof(factors)}(factors, τ) +QR(factors::AbstractMatrix{T}, τ::Vector{T}) where T = QR{T,typeof(factors)}(factors, τ) # Note. For QRCompactWY factorization without pivoting, the WY representation based method introduced in LAPACK 3.4 immutable QRCompactWY{S,M<:AbstractMatrix} <: Factorization{S} factors::M T::Matrix{S} - QRCompactWY(factors::AbstractMatrix{S}, T::AbstractMatrix{S}) = new(factors, T) + QRCompactWY{S,M}(factors::AbstractMatrix{S}, T::AbstractMatrix{S}) where {S,M<:AbstractMatrix} = new(factors, T) end -QRCompactWY{S}(factors::AbstractMatrix{S}, T::AbstractMatrix{S}) = QRCompactWY{S,typeof(factors)}(factors, T) +QRCompactWY(factors::AbstractMatrix{S}, T::AbstractMatrix{S}) where S = QRCompactWY{S,typeof(factors)}(factors, T) immutable QRPivoted{T,S<:AbstractMatrix} <: Factorization{T} factors::S τ::Vector{T} jpvt::Vector{BlasInt} - QRPivoted(factors::AbstractMatrix{T}, τ::Vector{T}, jpvt::Vector{BlasInt}) = new(factors, τ, jpvt) + QRPivoted{T,S}(factors::AbstractMatrix{T}, τ::Vector{T}, jpvt::Vector{BlasInt}) where {T,S<:AbstractMatrix} = + new(factors, τ, jpvt) end -QRPivoted{T}(factors::AbstractMatrix{T}, τ::Vector{T}, jpvt::Vector{BlasInt}) = QRPivoted{T,typeof(factors)}(factors, τ, jpvt) +QRPivoted(factors::AbstractMatrix{T}, τ::Vector{T}, jpvt::Vector{BlasInt}) where T = + QRPivoted{T,typeof(factors)}(factors, τ, jpvt) function qrfactUnblocked!{T}(A::AbstractMatrix{T}) m, n = size(A) @@ -342,16 +344,16 @@ getq(A::Union{QR, QRPivoted}) = QRPackedQ(A.factors,A.τ) immutable QRPackedQ{T,S<:AbstractMatrix} <: AbstractMatrix{T} factors::S τ::Vector{T} - QRPackedQ(factors::AbstractMatrix{T}, τ::Vector{T}) = new(factors, τ) + QRPackedQ{T,S}(factors::AbstractMatrix{T}, τ::Vector{T}) where {T,S<:AbstractMatrix} = new(factors, τ) end -QRPackedQ{T}(factors::AbstractMatrix{T}, τ::Vector{T}) = QRPackedQ{T,typeof(factors)}(factors, τ) +QRPackedQ(factors::AbstractMatrix{T}, τ::Vector{T}) where T = QRPackedQ{T,typeof(factors)}(factors, τ) immutable QRCompactWYQ{S, M<:AbstractMatrix} <: AbstractMatrix{S} factors::M T::Matrix{S} - QRCompactWYQ(factors::AbstractMatrix{S}, T::Matrix{S}) = new(factors, T) + QRCompactWYQ{S,M}(factors::AbstractMatrix{S}, T::Matrix{S}) where {S,M<:AbstractMatrix} = new(factors, T) end -QRCompactWYQ{S}(factors::AbstractMatrix{S}, T::Matrix{S}) = QRCompactWYQ{S,typeof(factors)}(factors, T) +QRCompactWYQ(factors::AbstractMatrix{S}, T::Matrix{S}) where S = QRCompactWYQ{S,typeof(factors)}(factors, T) convert{T}(::Type{QRPackedQ{T}}, Q::QRPackedQ) = QRPackedQ(convert(AbstractMatrix{T}, Q.factors), convert(Vector{T}, Q.τ)) convert{T}(::Type{AbstractMatrix{T}}, Q::QRPackedQ{T}) = Q diff --git a/base/linalg/rowvector.jl b/base/linalg/rowvector.jl index 9bc908d20f781..fd54ed55e0334 100644 --- a/base/linalg/rowvector.jl +++ b/base/linalg/rowvector.jl @@ -15,7 +15,7 @@ scalar, but will otherwise behave similarly. """ immutable RowVector{T,V<:AbstractVector} <: AbstractMatrix{T} vec::V - function RowVector(v::V) + function RowVector{T,V}(v::V) where V<:AbstractVector where T check_types(T,v) new(v) end @@ -30,16 +30,16 @@ end @inline transpose_type{T}(::Type{T}) = promote_op(transpose, T) # Constructors that take a vector -@inline RowVector{T}(vec::AbstractVector{T}) = RowVector{transpose_type(T),typeof(vec)}(vec) -@inline (::Type{RowVector{T}}){T}(vec::AbstractVector{T}) = RowVector{T,typeof(vec)}(vec) +@inline RowVector(vec::AbstractVector{T}) where T = RowVector{transpose_type(T),typeof(vec)}(vec) +@inline RowVector{T}(vec::AbstractVector{T}) where T = RowVector{T,typeof(vec)}(vec) # Constructors that take a size and default to Array -@inline (::Type{RowVector{T}}){T}(n::Int) = RowVector{T}(Vector{transpose_type(T)}(n)) -@inline (::Type{RowVector{T}}){T}(n1::Int, n2::Int) = n1 == 1 ? +@inline RowVector{T}(n::Int) where T = RowVector{T}(Vector{transpose_type(T)}(n)) +@inline RowVector{T}(n1::Int, n2::Int) where T = n1 == 1 ? RowVector{T}(Vector{transpose_type(T)}(n2)) : error("RowVector expects 1×N size, got ($n1,$n2)") -@inline (::Type{RowVector{T}}){T}(n::Tuple{Int}) = RowVector{T}(Vector{transpose_type(T)}(n[1])) -@inline (::Type{RowVector{T}}){T}(n::Tuple{Int,Int}) = n[1] == 1 ? +@inline RowVector{T}(n::Tuple{Int}) where T = RowVector{T}(Vector{transpose_type(T)}(n[1])) +@inline RowVector{T}(n::Tuple{Int,Int}) where T = n[1] == 1 ? RowVector{T}(Vector{transpose_type(T)}(n[2])) : error("RowVector expects 1×N size, got $n") diff --git a/base/linalg/schur.jl b/base/linalg/schur.jl index 63f04c9784f57..5d8a41193f21c 100644 --- a/base/linalg/schur.jl +++ b/base/linalg/schur.jl @@ -5,9 +5,9 @@ immutable Schur{Ty,S<:AbstractMatrix} <: Factorization{Ty} T::S Z::S values::Vector - Schur(T::AbstractMatrix{Ty}, Z::AbstractMatrix{Ty}, values::Vector) = new(T, Z, values) + Schur{Ty,S}(T::AbstractMatrix{Ty}, Z::AbstractMatrix{Ty}, values::Vector) where {Ty,S} = new(T, Z, values) end -Schur{Ty}(T::AbstractMatrix{Ty}, Z::AbstractMatrix{Ty}, values::Vector) = Schur{Ty, typeof(T)}(T, Z, values) +Schur(T::AbstractMatrix{Ty}, Z::AbstractMatrix{Ty}, values::Vector) where Ty = Schur{Ty, typeof(T)}(T, Z, values) """ schurfact!(A::StridedMatrix) -> F::Schur @@ -146,9 +146,15 @@ immutable GeneralizedSchur{Ty,M<:AbstractMatrix} <: Factorization{Ty} beta::Vector{Ty} Q::M Z::M - GeneralizedSchur(S::AbstractMatrix{Ty}, T::AbstractMatrix{Ty}, alpha::Vector, beta::Vector{Ty}, Q::AbstractMatrix{Ty}, Z::AbstractMatrix{Ty}) = new(S, T, alpha, beta, Q, Z) + function GeneralizedSchur{Ty,M}(S::AbstractMatrix{Ty}, T::AbstractMatrix{Ty}, alpha::Vector, + beta::Vector{Ty}, Q::AbstractMatrix{Ty}, Z::AbstractMatrix{Ty}) where {Ty,M} + new(S, T, alpha, beta, Q, Z) + end +end +function GeneralizedSchur(S::AbstractMatrix{Ty}, T::AbstractMatrix{Ty}, alpha::Vector, + beta::Vector{Ty}, Q::AbstractMatrix{Ty}, Z::AbstractMatrix{Ty}) where Ty + GeneralizedSchur{Ty, typeof(S)}(S, T, alpha, beta, Q, Z) end -GeneralizedSchur{Ty}(S::AbstractMatrix{Ty}, T::AbstractMatrix{Ty}, alpha::Vector, beta::Vector{Ty}, Q::AbstractMatrix{Ty}, Z::AbstractMatrix{Ty}) = GeneralizedSchur{Ty, typeof(S)}(S, T, alpha, beta, Q, Z) """ schurfact!(A::StridedMatrix, B::StridedMatrix) -> F::GeneralizedSchur diff --git a/base/linalg/svd.jl b/base/linalg/svd.jl index 7c7183f720ce0..4c4dca7ce6f35 100644 --- a/base/linalg/svd.jl +++ b/base/linalg/svd.jl @@ -5,9 +5,10 @@ immutable SVD{T,Tr,M<:AbstractArray} <: Factorization{T} U::M S::Vector{Tr} Vt::M - SVD(U::AbstractArray{T}, S::Vector{Tr}, Vt::AbstractArray{T}) = new(U, S, Vt) + SVD{T,Tr,M}(U::AbstractArray{T}, S::Vector{Tr}, Vt::AbstractArray{T}) where {T,Tr,M} = + new(U, S, Vt) end -SVD{T,Tr}(U::AbstractArray{T}, S::Vector{Tr}, Vt::AbstractArray{T}) = SVD{T,Tr,typeof(U)}(U, S, Vt) +SVD(U::AbstractArray{T}, S::Vector{Tr}, Vt::AbstractArray{T}) where {T,Tr} = SVD{T,Tr,typeof(U)}(U, S, Vt) """ svdfact!(A, thin::Bool=true) -> SVD @@ -178,9 +179,15 @@ immutable GeneralizedSVD{T,S} <: Factorization{T} k::Int l::Int R::S - GeneralizedSVD(U::AbstractMatrix{T}, V::AbstractMatrix{T}, Q::AbstractMatrix{T}, a::Vector, b::Vector, k::Int, l::Int, R::AbstractMatrix{T}) = new(U, V, Q, a, b, k, l, R) + function GeneralizedSVD{T,S}(U::AbstractMatrix{T}, V::AbstractMatrix{T}, Q::AbstractMatrix{T}, + a::Vector, b::Vector, k::Int, l::Int, R::AbstractMatrix{T}) where {T,S} + new(U, V, Q, a, b, k, l, R) + end +end +function GeneralizedSVD(U::AbstractMatrix{T}, V::AbstractMatrix{T}, Q::AbstractMatrix{T}, + a::Vector, b::Vector, k::Int, l::Int, R::AbstractMatrix{T}) where T + GeneralizedSVD{T,typeof(U)}(U, V, Q, a, b, k, l, R) end -GeneralizedSVD{T}(U::AbstractMatrix{T}, V::AbstractMatrix{T}, Q::AbstractMatrix{T}, a::Vector, b::Vector, k::Int, l::Int, R::AbstractMatrix{T}) = GeneralizedSVD{T,typeof(U)}(U, V, Q, a, b, k, l, R) """ svdfact!(A, B) -> GeneralizedSVD diff --git a/base/linalg/tridiag.jl b/base/linalg/tridiag.jl index 26c2e7fe49b6e..6ece76051f0f7 100644 --- a/base/linalg/tridiag.jl +++ b/base/linalg/tridiag.jl @@ -6,7 +6,7 @@ immutable SymTridiagonal{T} <: AbstractMatrix{T} dv::Vector{T} # diagonal ev::Vector{T} # subdiagonal - function SymTridiagonal(dv::Vector{T}, ev::Vector{T}) + function SymTridiagonal{T}(dv::Vector{T}, ev::Vector{T}) where T if !(length(dv) - 1 <= length(ev) <= length(dv)) throw(DimensionMismatch("subdiagonal has wrong length. Has length $(length(ev)), but should be either $(length(dv) - 1) or $(length(dv)).")) end @@ -46,9 +46,9 @@ julia> SymTridiagonal(dv, ev) ⋅ ⋅ 9 4 ``` """ -SymTridiagonal{T}(dv::Vector{T}, ev::Vector{T}) = SymTridiagonal{T}(dv, ev) +SymTridiagonal(dv::Vector{T}, ev::Vector{T}) where T = SymTridiagonal{T}(dv, ev) -function SymTridiagonal{Td,Te}(dv::AbstractVector{Td}, ev::AbstractVector{Te}) +function SymTridiagonal(dv::AbstractVector{Td}, ev::AbstractVector{Te}) where {Td,Te} T = promote_type(Td,Te) SymTridiagonal(convert(Vector{T}, dv), convert(Vector{T}, ev)) end diff --git a/base/methodshow.jl b/base/methodshow.jl index 269a1dfeb89cc..e3fe26c282f1b 100644 --- a/base/methodshow.jl +++ b/base/methodshow.jl @@ -84,6 +84,17 @@ function kwarg_decl(m::Method, kwtype::DataType) return () end +function show_method_params(io::IO, tv) + if !isempty(tv) + print(io, " where ") + if length(tv) == 1 + show(io, tv[1]) + else + show_delim_array(io, tv, '{', ',', '}', false) + end + end +end + function show(io::IO, m::Method; kwtype::Nullable{DataType}=Nullable{DataType}()) tv, decls, file, line = arg_decl_parts(m) sig = unwrap_unionall(m.sig) @@ -107,9 +118,6 @@ function show(io::IO, m::Method; kwtype::Nullable{DataType}=Nullable{DataType}() else print(io, "(", d1[1], "::", d1[2], ")") end - if !isempty(tv) - show_delim_array(io, tv, '{', ',', '}', false) - end print(io, "(") join(io, [isempty(d[2]) ? d[1] : d[1]*"::"*d[2] for d in decls[2:end]], ", ", ", ") @@ -120,7 +128,9 @@ function show(io::IO, m::Method; kwtype::Nullable{DataType}=Nullable{DataType}() join(io, kwargs, ", ", ", ") end end - print(io, ") in ", m.module) + print(io, ")") + show_method_params(io, tv) + print(io, " in ", m.module) if line > 0 print(io, " at ", file, ":", line) end diff --git a/base/multidimensional.jl b/base/multidimensional.jl index b7b305dd621db..6472f6be0750b 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -15,16 +15,16 @@ module IteratorsMD # CartesianIndex immutable CartesianIndex{N} <: AbstractCartesianIndex{N} I::NTuple{N,Int} - CartesianIndex(index::NTuple{N,Integer}) = new(index) + CartesianIndex{N}(index::NTuple{N,Integer}) where N = new(index) end - CartesianIndex{N}(index::NTuple{N,Integer}) = CartesianIndex{N}(index) - (::Type{CartesianIndex})(index::Integer...) = CartesianIndex(index) - (::Type{CartesianIndex{N}}){N}(index::Vararg{Integer,N}) = CartesianIndex{N}(index) + CartesianIndex(index::NTuple{N,Integer}) where N = CartesianIndex{N}(index) + CartesianIndex(index::Integer...) = CartesianIndex(index) + CartesianIndex{N}(index::Vararg{Integer,N}) where N = CartesianIndex{N}(index) # Allow passing tuples smaller than N - (::Type{CartesianIndex{N}}){N}(index::Tuple) = CartesianIndex{N}(fill_to_length(index, 1, Val{N})) - (::Type{CartesianIndex{N}}){N}(index::Integer...) = CartesianIndex{N}(index) - (::Type{CartesianIndex{N}}){N}() = CartesianIndex{N}(()) + CartesianIndex{N}(index::Tuple) where N = CartesianIndex{N}(fill_to_length(index, 1, Val{N})) + CartesianIndex{N}(index::Integer...) where N = CartesianIndex{N}(index) + CartesianIndex{N}() where N = CartesianIndex{N}(()) # Un-nest passed CartesianIndexes CartesianIndex(index::Union{Integer, CartesianIndex}...) = CartesianIndex(flatten(index)) flatten(I::Tuple{}) = I @@ -276,10 +276,10 @@ wrapped with `LogicalIndex` upon calling `to_indices`. immutable LogicalIndex{T, A<:AbstractArray{Bool}} <: AbstractVector{T} mask::A sum::Int - LogicalIndex(mask::A) = new(mask, countnz(mask)) + LogicalIndex{T,A}(mask::A) where {T,A<:AbstractArray{Bool}} = new(mask, countnz(mask)) end LogicalIndex(mask::AbstractVector{Bool}) = LogicalIndex{Int, typeof(mask)}(mask) -LogicalIndex{N}(mask::AbstractArray{Bool, N}) = LogicalIndex{CartesianIndex{N}, typeof(mask)}(mask) +LogicalIndex(mask::AbstractArray{Bool, N}) where N = LogicalIndex{CartesianIndex{N}, typeof(mask)}(mask) (::Type{LogicalIndex{Int}})(mask::AbstractArray) = LogicalIndex{Int, typeof(mask)}(mask) size(L::LogicalIndex) = (L.sum,) length(L::LogicalIndex) = L.sum diff --git a/base/multinverses.jl b/base/multinverses.jl index c358b360c15e0..c1a72ec84ecde 100644 --- a/base/multinverses.jl +++ b/base/multinverses.jl @@ -49,7 +49,7 @@ immutable SignedMultiplicativeInverse{T<:Signed} <: MultiplicativeInverse{T} addmul::Int8 shift::UInt8 - function SignedMultiplicativeInverse(d::T) + function SignedMultiplicativeInverse{T}(d::T) where T<:Signed d == 0 && throw(ArgumentError("cannot compute magic for d == $d")) signedmin = unsigned(typemin(T)) UT = unsigned(T) @@ -94,7 +94,7 @@ immutable UnsignedMultiplicativeInverse{T<:Unsigned} <: MultiplicativeInverse{T} add::Bool shift::UInt8 - function UnsignedMultiplicativeInverse(d::T) + function UnsignedMultiplicativeInverse{T}(d::T) where T<:Unsigned d == 0 && throw(ArgumentError("cannot compute magic for d == $d")) u2 = convert(T, 2) add = false diff --git a/base/parallel/clusterserialize.jl b/base/parallel/clusterserialize.jl index e2cac9d36e543..5aed58c648152 100644 --- a/base/parallel/clusterserialize.jl +++ b/base/parallel/clusterserialize.jl @@ -16,8 +16,10 @@ type ClusterSerializer{I<:IO} <: AbstractSerializer # anonymous functions. anonfunc_id::UInt64 - ClusterSerializer(io::I) = new(io, 0, ObjectIdDict(), Base.worker_id_from_socket(io), - Set{UInt64}(), Dict{UInt64, UInt64}(), Dict{UInt64, Vector{Symbol}}(), 0) + function ClusterSerializer{I}(io::I) where I<:IO + new(io, 0, ObjectIdDict(), Base.worker_id_from_socket(io), + Set{UInt64}(), Dict{UInt64, UInt64}(), Dict{UInt64, Vector{Symbol}}(), 0) + end end ClusterSerializer(io::IO) = ClusterSerializer{typeof(io)}(io) diff --git a/base/parallel/remotecall.jl b/base/parallel/remotecall.jl index 5eb1ee39bdfef..0cbef021603a5 100644 --- a/base/parallel/remotecall.jl +++ b/base/parallel/remotecall.jl @@ -27,7 +27,10 @@ type RemoteChannel{T<:AbstractChannel} <: AbstractRemoteRef whence::Int id::Int - RemoteChannel(w::Int, rrid::RRID) = (r = new(w, rrid.whence, rrid.id); return test_existing_ref(r)) + function RemoteChannel{T}(w::Int, rrid::RRID) where T<:AbstractChannel + r = new(w, rrid.whence, rrid.id) + return test_existing_ref(r) + end end function test_existing_ref(r::AbstractRemoteRef) diff --git a/base/permuteddimsarray.jl b/base/permuteddimsarray.jl index 530055b5da518..133ad971871b1 100644 --- a/base/permuteddimsarray.jl +++ b/base/permuteddimsarray.jl @@ -8,7 +8,7 @@ export permutedims, PermutedDimsArray immutable PermutedDimsArray{T,N,perm,iperm,AA<:AbstractArray} <: AbstractArray{T,N} parent::AA - function PermutedDimsArray(data::AA) + function PermutedDimsArray{T,N,perm,iperm,AA}(data::AA) where {T,N,perm,iperm,AA<:AbstractArray} (isa(perm, NTuple{N,Int}) && isa(iperm, NTuple{N,Int})) || error("perm and iperm must both be NTuple{$N,Int}") isperm(perm) || throw(ArgumentError(string(perm, " is not a valid permutation of dimensions 1:", N))) all(map(d->iperm[perm[d]]==d, 1:N)) || throw(ArgumentError(string(perm, " and ", iperm, " must be inverses"))) @@ -39,7 +39,7 @@ julia> B[3,1,2] == A[1,2,3] true ``` """ -function PermutedDimsArray{T,N}(data::AbstractArray{T,N}, perm) +function PermutedDimsArray(data::AbstractArray{T,N}, perm) where {T,N} length(perm) == N || throw(ArgumentError(string(perm, " is not a valid permutation of dimensions 1:", N))) iperm = invperm(perm) PermutedDimsArray{T,N,(perm...,),(iperm...,),typeof(data)}(data) diff --git a/base/range.jl b/base/range.jl index 628cfecb6cdfd..6ea72f7ab7c55 100644 --- a/base/range.jl +++ b/base/range.jl @@ -70,7 +70,7 @@ immutable StepRange{T,S} <: OrdinalRange{T,S} step::S stop::T - function StepRange{T,S}(start::T, step::S, stop::T) where (T,S) + function StepRange{T,S}(start::T, step::S, stop::T) where {T,S} new(start, step, steprange_last(start,step,stop)) end end @@ -123,7 +123,7 @@ steprange_last_empty(start, step, stop) = start - step steprem(start,stop,step) = (stop-start) % step -StepRange(start::T, step::S, stop::T) where (T,S) = StepRange{T,S}(start, step, stop) +StepRange(start::T, step::S, stop::T) where {T,S} = StepRange{T,S}(start, step, stop) immutable UnitRange{T<:Real} <: AbstractUnitRange{T} start::T @@ -170,14 +170,14 @@ immutable StepRangeLen{T,R,S} <: Range{T} len::Int # length of the range offset::Int # the index of ref - function StepRangeLen{T,R,S}(ref::R, step::S, len::Integer, offset::Integer = 1) where (T,R,S) + function StepRangeLen{T,R,S}(ref::R, step::S, len::Integer, offset::Integer = 1) where {T,R,S} len >= 0 || throw(ArgumentError("length cannot be negative, got $len")) 1 <= offset <= max(1,len) || throw(ArgumentError("StepRangeLen: offset must be in [1,$len], got $offset")) new(ref, step, len, offset) end end -StepRangeLen(ref::R, step::S, len::Integer, offset::Integer = 1) where (R,S) = +StepRangeLen(ref::R, step::S, len::Integer, offset::Integer = 1) where {R,S} = StepRangeLen{typeof(ref+0*step),R,S}(ref, step, len, offset) ## linspace and logspace diff --git a/base/refpointer.jl b/base/refpointer.jl index 45f75752091a5..1e0ad43b5c982 100644 --- a/base/refpointer.jl +++ b/base/refpointer.jl @@ -37,8 +37,8 @@ unsafe_convert{T}(::Type{Ref{T}}, x) = unsafe_convert(Ptr{T}, x) type RefValue{T} <: Ref{T} x::T - RefValue() = new() - RefValue(x) = new(x) + RefValue{T}() where T = new() + RefValue{T}(x) where T = new(x) end RefValue{T}(x::T) = RefValue{T}(x) isassigned(x::RefValue) = isdefined(x, :x) @@ -64,11 +64,11 @@ end unsafe_convert{T}(::Type{Ptr{Void}}, b::RefValue{T}) = convert(Ptr{Void}, unsafe_convert(Ptr{T}, b)) ### Methods for a Ref object that is backed by an array at index i -immutable RefArray{T, A<:AbstractArray, R} <: Ref{T} +immutable RefArray{T, A<:AbstractArray{T}, R} <: Ref{T} x::A i::Int roots::R # should be either ::Void or ::Any - RefArray(x,i,roots=nothing) = (@assert(eltype(A) == T); new(x,i,roots)) + RefArray{T,A,R}(x,i,roots=nothing) where {T,A<:AbstractArray{T},R} = new(x,i,roots) end RefArray{T}(x::AbstractArray{T},i::Int,roots::Any) = RefArray{T,typeof(x),Any}(x, i, roots) RefArray{T}(x::AbstractArray{T},i::Int=1,roots::Void=nothing) = RefArray{T,typeof(x),Void}(x, i, nothing) diff --git a/base/replutil.jl b/base/replutil.jl index 78f95cbe2951d..4056bd128ef0d 100644 --- a/base/replutil.jl +++ b/base/replutil.jl @@ -458,9 +458,6 @@ function show_method_candidates(io::IO, ex::MethodError, kwargs::Vector=Any[]) if !isa(tv,SimpleVector) tv = Any[tv] end - if !isempty(tv) - show_delim_array(buf, tv, '{', ',', '}', false) - end print(buf, "(") t_i = copy(arg_types_param) right_matches = 0 @@ -540,6 +537,7 @@ function show_method_candidates(io::IO, ex::MethodError, kwargs::Vector=Any[]) length(kwords) > 0 && print(buf, "; ", join(kwords, ", ")) end print(buf, ")") + show_method_params(buf, tv) print(buf, " at ", method.file, ":", method.line) if !isempty(kwargs) unexpected = Symbol[] diff --git a/base/serialize.jl b/base/serialize.jl index 2defd0c591430..ee40289720394 100644 --- a/base/serialize.jl +++ b/base/serialize.jl @@ -12,7 +12,7 @@ type SerializationState{I<:IO} <: AbstractSerializer io::I counter::Int table::ObjectIdDict - SerializationState(io::I) = new(io, 0, ObjectIdDict()) + SerializationState{I}(io::I) where I<:IO = new(io, 0, ObjectIdDict()) end SerializationState(io::IO) = SerializationState{typeof(io)}(io) diff --git a/base/set.jl b/base/set.jl index 285a65e9f1af7..55ba8bab1fff0 100644 --- a/base/set.jl +++ b/base/set.jl @@ -3,8 +3,8 @@ type Set{T} <: AbstractSet{T} dict::Dict{T,Void} - Set() = new(Dict{T,Void}()) - Set(itr) = union!(new(Dict{T,Void}()), itr) + Set{T}() where T = new(Dict{T,Void}()) + Set{T}(itr) where T = union!(new(Dict{T,Void}()), itr) end Set() = Set{Any}() Set(itr) = Set{eltype(itr)}(itr) diff --git a/base/sharedarray.jl b/base/sharedarray.jl index db4df9ee06c18..823eb715134f9 100644 --- a/base/sharedarray.jl +++ b/base/sharedarray.jl @@ -23,7 +23,7 @@ type SharedArray{T,N} <: DenseArray{T,N} # a subset of workers. loc_subarr_1d::SubArray{T,1,Array{T,1},Tuple{UnitRange{Int}},true} - function SharedArray(d,p,r,sn,s) + function SharedArray{T,N}(d,p,r,sn,s) where {T,N} new(d,p,r,sn,s,0,view(Array{T}(ntuple(d->0,N)), 1:0)) end end diff --git a/base/show.jl b/base/show.jl index 76ac7e9687179..b9c5bfce9fbef 100644 --- a/base/show.jl +++ b/base/show.jl @@ -13,7 +13,8 @@ dictionary operations such as [`getindex`](@ref), and can also be used as an I/O immutable IOContext{IO_t <: IO} <: AbstractPipe io::IO_t dict::ImmutableDict{Symbol, Any} - function IOContext(io::IO_t, dict::ImmutableDict{Symbol, Any}) + + function IOContext{IO_t}(io::IO_t, dict::ImmutableDict{Symbol, Any}) where IO_t<:IO assert(!(IO_t <: IOContext)) return new(io, dict) end @@ -971,12 +972,18 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int) print(io, head) # `where` syntax - elseif head === :where && length(args) == 2 + elseif head === :where && length(args) > 1 parens = 1 <= prec parens && print(io, "(") show_unquoted(io, args[1], indent, operator_precedence(:(::))) print(io, " where ") - show_unquoted(io, args[2], indent, 1) + if nargs == 2 + show_unquoted(io, args[2], indent, 1) + else + print(io, "{") + show_list(io, args[2:end], ", ", indent) + print(io, "}") + end parens && print(io, ")") elseif head === :import || head === :importall || head === :using diff --git a/base/sparse/cholmod.jl b/base/sparse/cholmod.jl index cec3776140e7c..e26b07143aafd 100644 --- a/base/sparse/cholmod.jl +++ b/base/sparse/cholmod.jl @@ -238,7 +238,7 @@ end type Sparse{Tv<:VTypes} <: AbstractSparseMatrix{Tv,SuiteSparse_long} p::Ptr{C_Sparse{Tv}} - function Sparse(p::Ptr{C_Sparse{Tv}}) + function Sparse{Tv}(p::Ptr{C_Sparse{Tv}}) where Tv<:VTypes if p == C_NULL throw(ArgumentError("sparse matrix construction failed for " * "unknown reasons. Please submit a bug report.")) @@ -246,7 +246,7 @@ type Sparse{Tv<:VTypes} <: AbstractSparseMatrix{Tv,SuiteSparse_long} new(p) end end -Sparse{Tv<:VTypes}(p::Ptr{C_Sparse{Tv}}) = Sparse{Tv}(p) +Sparse(p::Ptr{C_Sparse{Tv}}) where Tv<:VTypes = Sparse{Tv}(p) # Factor @@ -317,7 +317,7 @@ end type Factor{Tv} <: Factorization{Tv} p::Ptr{C_Factor{Tv}} - function Factor(p::Ptr{C_Factor{Tv}}) + function Factor{Tv}(p::Ptr{C_Factor{Tv}}) where Tv if p == C_NULL throw(ArgumentError("factorization construction failed for " * "unknown reasons. Please submit a bug report.")) @@ -325,7 +325,7 @@ type Factor{Tv} <: Factorization{Tv} new(p) end end -Factor{Tv<:VTypes}(p::Ptr{C_Factor{Tv}}) = Factor{Tv}(p) +Factor(p::Ptr{C_Factor{Tv}}) where Tv<:VTypes = Factor{Tv}(p) # Define get similar to get(Nullable) to check pointers. All pointer loads # should be wrapped in get to make sure that SuiteSparse is not called with @@ -344,7 +344,7 @@ end type FactorComponent{Tv,S} <: AbstractMatrix{Tv} F::Factor{Tv} - function FactorComponent(F::Factor{Tv}) + function FactorComponent{Tv,S}(F::Factor{Tv}) where {Tv,S} s = unsafe_load(get(F.p)) if s.is_ll != 0 if !(S == :L || S == :U || S == :PtL || S == :UP) @@ -359,7 +359,7 @@ type FactorComponent{Tv,S} <: AbstractMatrix{Tv} new(F) end end -function FactorComponent{Tv}(F::Factor{Tv}, sym::Symbol) +function FactorComponent(F::Factor{Tv}, sym::Symbol) where Tv FactorComponent{Tv,sym}(F) end diff --git a/base/sparse/sparsematrix.jl b/base/sparse/sparsematrix.jl index 58e8371e86b96..02439922341e2 100644 --- a/base/sparse/sparsematrix.jl +++ b/base/sparse/sparsematrix.jl @@ -12,7 +12,8 @@ immutable SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrix{Tv,Ti} rowval::Vector{Ti} # Row values of nonzeros nzval::Vector{Tv} # Nonzero values - function SparseMatrixCSC(m::Integer, n::Integer, colptr::Vector{Ti}, rowval::Vector{Ti}, nzval::Vector{Tv}) + function SparseMatrixCSC{Tv,Ti}(m::Integer, n::Integer, colptr::Vector{Ti}, rowval::Vector{Ti}, + nzval::Vector{Tv}) where {Tv,Ti<:Integer} m < 0 && throw(ArgumentError("number of rows (m) must be ≥ 0, got $m")) n < 0 && throw(ArgumentError("number of columns (n) must be ≥ 0, got $n")) new(Int(m), Int(n), colptr, rowval, nzval) diff --git a/base/sparse/sparsevector.jl b/base/sparse/sparsevector.jl index 8a4ea93c4e82a..f9478910d66f7 100644 --- a/base/sparse/sparsevector.jl +++ b/base/sparse/sparsevector.jl @@ -14,7 +14,7 @@ immutable SparseVector{Tv,Ti<:Integer} <: AbstractSparseVector{Tv,Ti} nzind::Vector{Ti} # the indices of nonzeros nzval::Vector{Tv} # the values of nonzeros - function SparseVector(n::Integer, nzind::Vector{Ti}, nzval::Vector{Tv}) + function SparseVector{Tv,Ti}(n::Integer, nzind::Vector{Ti}, nzval::Vector{Tv}) where {Tv,Ti<:Integer} n >= 0 || throw(ArgumentError("The number of elements must be non-negative.")) length(nzind) == length(nzval) || throw(ArgumentError("index and value vectors must be the same length")) @@ -22,7 +22,7 @@ immutable SparseVector{Tv,Ti<:Integer} <: AbstractSparseVector{Tv,Ti} end end -SparseVector{Tv,Ti}(n::Integer, nzind::Vector{Ti}, nzval::Vector{Tv}) = +SparseVector(n::Integer, nzind::Vector{Ti}, nzval::Vector{Tv}) where {Tv,Ti} = SparseVector{Tv,Ti}(n, nzind, nzval) ### Basic properties diff --git a/base/sparse/spqr.jl b/base/sparse/spqr.jl index 6f93e2049426c..435a87f1dd195 100644 --- a/base/sparse/spqr.jl +++ b/base/sparse/spqr.jl @@ -54,14 +54,14 @@ type Factorization{Tv<:VTypes} <: Base.LinAlg.Factorization{Tv} m::Int n::Int p::Ptr{C_Factorization{Tv}} - function Factorization(m::Integer, n::Integer, p::Ptr{C_Factorization{Tv}}) + function Factorization{Tv}(m::Integer, n::Integer, p::Ptr{C_Factorization{Tv}}) where Tv<:VTypes if p == C_NULL throw(ArgumentError("factorization failed for unknown reasons. Please submit a bug report.")) end new(m, n, p) end end -Factorization{Tv<:VTypes}(m::Integer, n::Integer, p::Ptr{C_Factorization{Tv}}) = Factorization{Tv}(m, n, p) +Factorization(m::Integer, n::Integer, p::Ptr{C_Factorization{Tv}}) where Tv<:VTypes = Factorization{Tv}(m, n, p) size(F::Factorization) = (F.m, F.n) function size(F::Factorization, i::Integer) diff --git a/base/subarray.jl b/base/subarray.jl index a8cf520e21a7a..672adbe46c7be 100644 --- a/base/subarray.jl +++ b/base/subarray.jl @@ -10,7 +10,7 @@ immutable SubArray{T,N,P,I,L} <: AbstractArray{T,N} indexes::I offset1::Int # for linear indexing and pointer, only valid when L==true stride1::Int # used only for linear indexing - function SubArray(parent, indexes, offset1, stride1) + function SubArray{T,N,P,I,L}(parent, indexes, offset1, stride1) where {T,N,P,I,L} @_inline_meta check_parent_index_match(parent, indexes) new(parent, indexes, offset1, stride1) @@ -21,11 +21,11 @@ function SubArray(parent::AbstractArray, indexes::Tuple) @_inline_meta SubArray(linearindexing(viewindexing(indexes), linearindexing(parent)), parent, ensure_indexable(indexes), index_dimsum(indexes...)) end -function SubArray{P, I, N}(::LinearSlow, parent::P, indexes::I, ::NTuple{N,Any}) +function SubArray(::LinearSlow, parent::P, indexes::I, ::NTuple{N,Any}) where {P,I,N} @_inline_meta SubArray{eltype(P), N, P, I, false}(parent, indexes, 0, 0) end -function SubArray{P, I, N}(::LinearFast, parent::P, indexes::I, ::NTuple{N,Any}) +function SubArray(::LinearFast, parent::P, indexes::I, ::NTuple{N,Any}) where {P,I,N} @_inline_meta # Compute the stride and offset stride1 = compute_stride1(parent, indexes) diff --git a/base/weakkeydict.jl b/base/weakkeydict.jl index cd6128dea8d34..ea28c9805f0ba 100644 --- a/base/weakkeydict.jl +++ b/base/weakkeydict.jl @@ -15,7 +15,7 @@ type WeakKeyDict{K,V} <: Associative{K,V} finalizer::Function # Constructors mirror Dict's - function WeakKeyDict() + function WeakKeyDict{K,V}() where V where K t = new(Dict{Any,V}(), Threads.RecursiveSpinLock(), identity) t.finalizer = function (k) # when a weak key is finalized, remove from dictionary if it is still there @@ -24,22 +24,22 @@ type WeakKeyDict{K,V} <: Associative{K,V} end return t end - function WeakKeyDict(kv) - h = WeakKeyDict{K,V}() - for (k,v) in kv - h[k] = v - end - return h +end +function WeakKeyDict{K,V}(kv) where V where K + h = WeakKeyDict{K,V}() + for (k,v) in kv + h[k] = v end - WeakKeyDict(p::Pair) = setindex!(WeakKeyDict{K,V}(), p.second, p.first) - function WeakKeyDict(ps::Pair...) - h = WeakKeyDict{K,V}() - sizehint!(h, length(ps)) - for p in ps - h[p.first] = p.second - end - return h + return h +end +WeakKeyDict{K,V}(p::Pair) where V where K = setindex!(WeakKeyDict{K,V}(), p.second, p.first) +function WeakKeyDict{K,V}(ps::Pair...) where V where K + h = WeakKeyDict{K,V}() + sizehint!(h, length(ps)) + for p in ps + h[p.first] = p.second end + return h end WeakKeyDict() = WeakKeyDict{Any,Any}() diff --git a/doc/src/manual/constructors.md b/doc/src/manual/constructors.md index ef5479a96ab25..6aa899cf50085 100644 --- a/doc/src/manual/constructors.md +++ b/doc/src/manual/constructors.md @@ -334,19 +334,16 @@ This automatic provision of constructors is equivalent to the following explicit julia> type Point{T<:Real} x::T y::T - Point(x,y) = new(x,y) + Point{T}(x,y) where T<:Real = new(x,y) end -julia> Point{T<:Real}(x::T, y::T) = Point{T}(x,y); +julia> Point(x::T, y::T) where T<:Real = Point{T}(x,y); ``` -Some features of parametric constructor definitions at work here deserve comment. First, inner -constructor declarations always define methods of `Point{T}` rather than methods of the general -`Point` constructor function. Since `Point` is not a concrete type, it makes no sense for it to -even have inner constructor methods at all. Thus, the inner method declaration `Point(x,y) = new(x,y)` -provides an inner constructor method for each value of `T`. It is this method declaration that -defines the behavior of constructor calls with explicit type parameters like `Point{Int64}(1,2)` -and `Point{Float64}(1.0,2.0)`. The outer constructor declaration, on the other hand, defines a +Notice that each definition looks like the form of constructor call that it handles. +The call `Point{Int64}(1,2)` will invoke the definition `Point{T}(x,y)` inside the +`type` block. +The outer constructor declaration, on the other hand, defines a method for the general `Point` constructor which only applies to pairs of values of the same real type. This declaration makes constructor calls without explicit type parameters, like `Point(1,2)` and `Point(1.0,2.5)`, work. Since the method declaration restricts the arguments to being of the @@ -384,7 +381,7 @@ Closest candidates are: Point{T<:Real}(::T<:Real, !Matched::T<:Real) at none:1 ``` -For a much more general way of making all such calls work sensibly, see [Conversion and Promotion](@ref conversion-and-promotion). +For a more general way to make all such calls work sensibly, see [Conversion and Promotion](@ref conversion-and-promotion). At the risk of spoiling the suspense, we can reveal here that all it takes is the following outer method definition to make all calls to the general `Point` constructor work as one would expect: @@ -422,7 +419,7 @@ which implements Julia's [Rational Numbers](@ref): julia> immutable OurRational{T<:Integer} <: Real num::T den::T - function OurRational(num::T, den::T) + function OurRational{T}(num::T, den::T) where T<:Integer if num == 0 && den == 0 error("invalid rational: 0//0") end @@ -433,7 +430,7 @@ julia> immutable OurRational{T<:Integer} <: Real end end -julia> OurRational{T<:Integer}(n::T, d::T) = OurRational{T}(n,d) +julia> OurRational(n::T, d::T) where T<:Integer = OurRational{T}(n,d) OurRational julia> OurRational(n::Integer, d::Integer) = OurRational(promote(n,d)...) @@ -533,7 +530,7 @@ one type to another, you should probably define a `convert` method instead. On the other hand, if your constructor does not represent a lossless conversion, or doesn't represent "conversion" at all, it is better to leave it as a constructor rather than a `convert` method. - For example, the `Array{Int}()` constructor creates a zero-dimensional `Array` of the type `Int`, +For example, the `Array{Int}()` constructor creates a zero-dimensional `Array` of the type `Int`, but is not really a "conversion" from `Int` to an `Array`. ## Outer-only constructors @@ -561,14 +558,14 @@ SummedArray{Int32,Int32}(Int32[1, 2, 3], 6) The problem is that we want `S` to be a larger type than `T`, so that we can sum many elements with less information loss. For example, when `T` is `Int32`, we would like `S` to be `Int64`. Therefore we want to avoid an interface that allows the user to construct instances of the type -`SummedArray{Int32,Int32}`. One way to do this is to provide only an outer constructor for `SummedArray`. -This can be done using method definition by type: +`SummedArray{Int32,Int32}`. One way to do this is to provide a constructor only for `SummedArray`, +but inside the `type` definition block to suppress generation of default constructors: ```jldoctest julia> type SummedArray{T<:Number,S<:Number} data::Vector{T} sum::S - function (::Type{SummedArray}){T}(a::Vector{T}) + function SummedArray(a::Vector{T}) where T S = widen(T) new{T,S}(a, sum(S, a)) end @@ -583,4 +580,5 @@ Closest candidates are: This constructor will be invoked by the syntax `SummedArray(a)`. The syntax `new{T,S}` allows specifying parameters for the type to be constructed, i.e. this call will return a `SummedArray{T,S}`. - +`new{T,S}` can be used in any constructor definition, but for convenience the parameters +to `new{}` are automatically derived from the type being constructed when possible. diff --git a/doc/src/manual/methods.md b/doc/src/manual/methods.md index ec04a1eba4756..42dd84f5c9fc1 100644 --- a/doc/src/manual/methods.md +++ b/doc/src/manual/methods.md @@ -268,11 +268,10 @@ exists, if transiently, until the more specific method is defined. ## Parametric Methods -Method definitions can optionally have type parameters immediately after the method name and before -the parameter tuple: +Method definitions can optionally have type parameters qualifying the signature: ```jldoctest same_typefunc -julia> same_type{T}(x::T, y::T) = true +julia> same_type(x::T, y::T) where {T} = true same_type (generic function with 1 method) julia> same_type(x,y) = false @@ -304,14 +303,17 @@ julia> same_type(Int32(1), Int64(2)) false ``` +Such definitions correspond to methods whose type signatures are `UnionAll` types +(see [UnionAll Types](@ref)). + This kind of definition of function behavior by dispatch is quite common -- idiomatic, even -- -in Julia. Method type parameters are not restricted to being used as the types of parameters: +in Julia. Method type parameters are not restricted to being used as the types of arguments: they can be used anywhere a value would be in the signature of the function or body of the function. Here's an example where the method type parameter `T` is used as the type parameter to the parametric type `Vector{T}` in the method signature: ```jldoctest -julia> myappend{T}(v::Vector{T}, x::T) = [v..., x] +julia> myappend(v::Vector{T}, x::T) where {T} = [v..., x] myappend (generic function with 1 method) julia> myappend([1,2,3],4) @@ -324,7 +326,7 @@ julia> myappend([1,2,3],4) julia> myappend([1,2,3],2.5) ERROR: MethodError: no method matching myappend(::Array{Int64,1}, ::Float64) Closest candidates are: - myappend{T}(::Array{T,1}, !Matched::T) at none:1 + myappend(::Array{T,1}, !Matched::T) where T at none:1 julia> myappend([1.0,2.0,3.0],4.0) 4-element Array{Float64,1}: @@ -336,7 +338,7 @@ julia> myappend([1.0,2.0,3.0],4.0) julia> myappend([1.0,2.0,3.0],4) ERROR: MethodError: no method matching myappend(::Array{Float64,1}, ::Int64) Closest candidates are: - myappend{T}(::Array{T,1}, !Matched::T) at none:1 + myappend(::Array{T,1}, !Matched::T) where T at none:1 ``` As you can see, the type of the appended element must match the element type of the vector it @@ -344,7 +346,7 @@ is appended to, or else a [`MethodError`](@ref) is raised. In the following exam `T` is used as the return value: ```jldoctest -julia> mytypeof{T}(x::T) = T +julia> mytypeof(x::T) where {T} = T mytypeof (generic function with 1 method) julia> mytypeof(1) @@ -358,7 +360,7 @@ Just as you can put subtype constraints on type parameters in type declarations you can also constrain type parameters of methods: ```jldoctest -julia> same_type_numeric{T<:Number}(x::T, y::T) = true +julia> same_type_numeric(x::T, y::T) where {T<:Number} = true same_type_numeric (generic function with 1 method) julia> same_type_numeric(x::Number, y::Number) = false @@ -376,7 +378,7 @@ true julia> same_type_numeric("foo", 2.0) ERROR: MethodError: no method matching same_type_numeric(::String, ::Float64) Closest candidates are: - same_type_numeric{T<:Number}(!Matched::T<:Number, ::T<:Number) at none:1 + same_type_numeric(!Matched::T<:Number, ::T<:Number) where T<:Number at none:1 same_type_numeric(!Matched::Number, ::Number) at none:1 julia> same_type_numeric("foo", "bar") @@ -389,6 +391,13 @@ false The `same_type_numeric` function behaves much like the `same_type` function defined above, but is only defined for pairs of numbers. +Parametric methods allow the same syntax as `where` expressions used to write types +(see [UnionAll Types](@ref)). +If there is only a single parameter, the enclosing curly braces (in `where {T}`) can be omitted, +but are often preferred for clarity. +Multiple parameters can be separated with commas, e.g. `where {T, S<:Real}`, or written using +nested `where`, e.g. `where S<:Real where T`. + Redefining Methods ------------------ diff --git a/examples/ModInts.jl b/examples/ModInts.jl index 3d4130332e404..0effca60b1c0d 100644 --- a/examples/ModInts.jl +++ b/examples/ModInts.jl @@ -7,7 +7,7 @@ import Base: +, -, *, /, inv immutable ModInt{n} <: Integer k::Int - ModInt(k) = new(mod(k,n)) + ModInt{n}(k) where n = new(mod(k,n)) end Base.show{n}(io::IO, k::ModInt{n}) = diff --git a/examples/lru.jl b/examples/lru.jl index 4458032be03b7..a8342d8d1f221 100644 --- a/examples/lru.jl +++ b/examples/lru.jl @@ -39,7 +39,7 @@ type UnboundedLRU{K,V} <: LRU{K,V} ht::Dict q::Vector{CacheItem} - UnboundedLRU() = new(Dict(), similar(Array{CacheItem}(1), 0)) + UnboundedLRU{K,V}() where {K,V} = new(Dict(), similar(Array{CacheItem}(1), 0)) end UnboundedLRU() = UnboundedLRU{Any, Any}() @@ -48,8 +48,8 @@ type BoundedLRU{K,V} <: LRU{K,V} q::Vector{CacheItem} maxsize::Int - BoundedLRU(m) = new(Dict(), similar(Array{CacheItem}(1), 0), m) - BoundedLRU() = BoundedLRU(__MAXCACHE) + BoundedLRU{K,V}(m) where {K,V} = new(Dict(), similar(Array{CacheItem}(1), 0), m) + BoundedLRU{K,V}() where {K,V} = BoundedLRU(__MAXCACHE) end BoundedLRU(m) = BoundedLRU{Any, Any}(m) BoundedLRU() = BoundedLRU{Any, Any}() diff --git a/src/ast.scm b/src/ast.scm index 4c0ae0d0dda70..1e26777396142 100644 --- a/src/ast.scm +++ b/src/ast.scm @@ -83,7 +83,10 @@ ((generator) (string "(" (deparse (cadr e)) " for " (deparse-arglist (cddr e) ", ") ")")) ((where) - (string (deparse (cadr e)) " where " (deparse (caddr e)))) + (string (deparse (cadr e)) " where " + (if (length= e 3) + (deparse (caddr e)) + (deparse (cons 'cell1d (cddr e)))))) ((function for while) (deparse-block (string (car e) " " (deparse (cadr e))) (block-stmts (caddr e)))) diff --git a/src/julia-parser.scm b/src/julia-parser.scm index ae9dbdf71b486..241cbe1ea7618 100644 --- a/src/julia-parser.scm +++ b/src/julia-parser.scm @@ -586,8 +586,8 @@ (if (eq? t 'where) (begin (take-token s) (let ((var (parse-comparison s))) - (loop (if (and (pair? var) (eq? (car var) 'tuple)) - (list* 'where ex (cdr var)) ;; form `x where (T,S)` + (loop (if (and (pair? var) (eq? (car var) 'cell1d)) + (list* 'where ex (cdr var)) ;; form `x where {T,S}` (list 'where ex var)) (peek-token s)))) ex)))) diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 282839fdc0025..69b3920f60fbf 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -754,6 +754,9 @@ (let* ((temp (ctor-signature name params bounds curlyargs sig)) (sig (car temp)) (params (cdr temp))) + (if (pair? params) + (syntax-deprecation #f (string "inner constructor " name "(...)") + (deparse `(where (call (curly ,name ,@params) ...) ,@params)))) `(,keyword ,sig ,(ctor-body body params))))))) ;; rewrite calls to `new( ... )` to `new` expressions on the appropriate diff --git a/test/abstractarray.jl b/test/abstractarray.jl index 9cf12eca837c6..a6a01611559ed 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -174,15 +174,17 @@ type T24Linear{T,N,dims} <: AbstractArray{T,N} v1::T; v2::T; v3::T; v4::T; v5::T; v6::T; v7::T; v8::T v9::T; v10::T; v11::T; v12::T; v13::T; v14::T; v15::T; v16::T v17::T; v18::T; v19::T; v20::T; v21::T; v22::T; v23::T; v24::T - T24Linear() = (prod(dims) == 24 || throw(DimensionMismatch("T24Linear must have 24 elements")); new()) - function T24Linear(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16,v17,v18,v19,v20,v21,v22,v23,v24) - prod(dims) == 24 || throw(DimensionMismatch("T24Linear must have 24 elements")) + T24Linear{T,N,d}() where {T,N,d} = + (prod(d) == 24 || throw(DimensionMismatch("T24Linear must have 24 elements")); new()) + function T24Linear{T,N,d}(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12, + v13,v14,v15,v16,v17,v18,v19,v20,v21,v22,v23,v24) where {T,N,d} + prod(d) == 24 || throw(DimensionMismatch("T24Linear must have 24 elements")) new(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16,v17,v18,v19,v20,v21,v22,v23,v24) end end -T24Linear{T}(::Type{T}, dims::Int...) = T24Linear(T, dims) -T24Linear{T,N}(::Type{T}, dims::NTuple{N,Int}) = T24Linear{T,N,dims}() +T24Linear(::Type{T}, dims::Int...) where T = T24Linear(T, dims) +T24Linear(::Type{T}, dims::NTuple{N,Int}) where {T,N} = T24Linear{T,N,dims}() Base.convert{T,N }(::Type{T24Linear }, X::AbstractArray{T,N}) = convert(T24Linear{T,N}, X) Base.convert{T,N,_}(::Type{T24Linear{T }}, X::AbstractArray{_,N}) = convert(T24Linear{T,N}, X) diff --git a/test/core.jl b/test/core.jl index 7cf9d3b13db31..5946f5bb854d3 100644 --- a/test/core.jl +++ b/test/core.jl @@ -1070,7 +1070,7 @@ end # issue #2562 type Node2562{T} value::T - Node2562(value::T) = new(value) + Node2562{T}(value::T) where T = new(value) end Node2562{T}(value::T, args...) = Node2562{T}(value, args...) makenode2562(value) = Node2562(value) @@ -1080,7 +1080,7 @@ makenode2562(value) = Node2562(value) # issue #2619 type I2619{T} v::T - I2619(v) = new(convert(T,v)) + I2619{T}(v) where T = new(convert(T,v)) end bad2619 = false function i2619() @@ -1266,8 +1266,8 @@ convert_default_should_fail_here() = similar([1],typeof(zero(typeof(rand(2,2)))) type Foo4376{T} x - Foo4376(x::T) = new(x) - Foo4376(a::Foo4376{Int}) = new(a.x) + Foo4376{T}(x::T) where T = new(x) + Foo4376{T}(a::Foo4376{Int}) where T = new(a.x) end @test isa(Foo4376{Float32}(Foo4376{Int}(2)), Foo4376{Float32}) @@ -1671,11 +1671,11 @@ end # issue #6404 type type_2{T <: Integer, N} <: Number x::T - type_2(n::T) = new(n) + type_2{T,N}(n::T) where {T<:Integer,N} = new(n) end type type_1{T <: Number} <: Number x::Vector{T} - type_1(x::Vector{T}) = new(x) + type_1{T}(x::Vector{T}) where T<:Number = new(x) end type_1{T <: Number}(x::Vector{T}) = type_1{T}(x) type_1{T <: Number}(c::T) = type_1{T}([c]) @@ -2848,7 +2848,7 @@ end # issue #11675 immutable T11675{T} x::T - T11675() = new() + T11675{T}() where T = new() end let x = T11675{Union{}}() function f11675(x) @@ -3013,7 +3013,7 @@ failure12003(dt=DATE12003) = Dates.year(dt) # issue #12089 type A12089{K, N} sz::NTuple{N, Int} - A12089(sz::NTuple{N, Int}) = new(sz) + A12089{K,N}(sz::NTuple{N, Int}) where {K,N} = new(sz) end A12089{-1, 1}((1,)) diff --git a/test/inference.jl b/test/inference.jl index b13a34d720aa0..fa7a790070774 100644 --- a/test/inference.jl +++ b/test/inference.jl @@ -77,7 +77,7 @@ end immutable Hanoi5906{T} <: Outer5906{T} a::T succ :: Outer5906{Inner5906{T}} - Hanoi5906(a) = new(a, Empty5906{Inner5906{T}}()) + Hanoi5906{T}(a) where T = new(a, Empty5906{Inner5906{T}}()) end function f5906{T}(h::Hanoi5906{T}) diff --git a/test/keywordargs.jl b/test/keywordargs.jl index 6aabb120731a0..efe02e48f5faa 100644 --- a/test/keywordargs.jl +++ b/test/keywordargs.jl @@ -173,7 +173,7 @@ end # issue #4801 type T4801{X} - T4801(;k=0) = new() + T4801{X}(;k=0) where X = new() end @test isa(T4801{Any}(k=0), T4801{Any}) diff --git a/test/reflection.jl b/test/reflection.jl index b3a8d72d71975..6797de0fe8136 100644 --- a/test/reflection.jl +++ b/test/reflection.jl @@ -282,7 +282,7 @@ let ex = :(a + b) end foo13825{T, N}(::Array{T,N}, ::Array, ::Vector) = nothing @test startswith(string(first(methods(foo13825))), - "foo13825{T, N}(::Array{T,N}, ::Array, ::Array{T,1} where T)") + "foo13825(::Array{T,N}, ::Array, ::Array{T,1} where T)") type TLayout x::Int8 diff --git a/test/replutil.jl b/test/replutil.jl index 3e4967643e4f6..105c1164c5b39 100644 --- a/test/replutil.jl +++ b/test/replutil.jl @@ -56,8 +56,8 @@ method_c2(x::Int32, y::Int32, z::Int32) = true method_c2{T<:Real}(x::T, y::T, z::T) = true Base.show_method_candidates(buf, Base.MethodError(method_c2,(1., 1., 2))) -color = "\e[0m\nClosest candidates are:\n method_c2(\e[1m\e[31m::Int32\e[0m, ::Float64, ::Any...)$cfile$(c2line+2)\n method_c2(\e[1m\e[31m::Int32\e[0m, ::Any...)$cfile$(c2line+1)\n method_c2{T<:Real}(::T<:Real, ::T<:Real, \e[1m\e[31m::T<:Real\e[0m)$cfile$(c2line+5)\n ...\e[0m" -no_color = no_color = "\nClosest candidates are:\n method_c2(!Matched::Int32, ::Float64, ::Any...)$cfile$(c2line+2)\n method_c2(!Matched::Int32, ::Any...)$cfile$(c2line+1)\n method_c2{T<:Real}(::T<:Real, ::T<:Real, !Matched::T<:Real)$cfile$(c2line+5)\n ..." +color = "\e[0m\nClosest candidates are:\n method_c2(\e[1m\e[31m::Int32\e[0m, ::Float64, ::Any...)$cfile$(c2line+2)\n method_c2(\e[1m\e[31m::Int32\e[0m, ::Any...)$cfile$(c2line+1)\n method_c2(::T<:Real, ::T<:Real, \e[1m\e[31m::T<:Real\e[0m)$cfile$(c2line+5)\n ...\e[0m" +no_color = no_color = "\nClosest candidates are:\n method_c2(!Matched::Int32, ::Float64, ::Any...)$cfile$(c2line+2)\n method_c2(!Matched::Int32, ::Any...)$cfile$(c2line+1)\n method_c2(::T<:Real, ::T<:Real, !Matched::T<:Real) where T<:Real$cfile$(c2line+5)\n ..." test_have_color(buf, color, no_color) c3line = @__LINE__ + 1 @@ -102,12 +102,12 @@ PR16155line2 = @__LINE__ + 1 (::Type{T}){T<:PR16155}(arg::Any) = "replace call-to-convert method from sysimg" Base.show_method_candidates(buf, MethodError(PR16155,(1.0, 2.0, Int64(3)))) -test_have_color(buf, "\e[0m\nClosest candidates are:\n $(curmod_prefix)PR16155(::Any, ::Any)$cfile$PR16155line\n $(curmod_prefix)PR16155(\e[1m\e[31m::Int64\e[0m, ::Any)$cfile$PR16155line\n $(curmod_prefix)PR16155{T<:$(curmod_prefix)PR16155}(::Any)$cfile$PR16155line2\n ...\e[0m", - "\nClosest candidates are:\n $(curmod_prefix)PR16155(::Any, ::Any)$cfile$PR16155line\n $(curmod_prefix)PR16155(!Matched::Int64, ::Any)$cfile$PR16155line\n $(curmod_prefix)PR16155{T<:$(curmod_prefix)PR16155}(::Any)$cfile$PR16155line2\n ...") +test_have_color(buf, "\e[0m\nClosest candidates are:\n $(curmod_prefix)PR16155(::Any, ::Any)$cfile$PR16155line\n $(curmod_prefix)PR16155(\e[1m\e[31m::Int64\e[0m, ::Any)$cfile$PR16155line\n $(curmod_prefix)PR16155(::Any) where T<:$(curmod_prefix)PR16155$cfile$PR16155line2\n ...\e[0m", + "\nClosest candidates are:\n $(curmod_prefix)PR16155(::Any, ::Any)$cfile$PR16155line\n $(curmod_prefix)PR16155(!Matched::Int64, ::Any)$cfile$PR16155line\n $(curmod_prefix)PR16155(::Any) where T<:$(curmod_prefix)PR16155$cfile$PR16155line2\n ...") Base.show_method_candidates(buf, MethodError(PR16155,(Int64(3), 2.0, Int64(3)))) -test_have_color(buf, "\e[0m\nClosest candidates are:\n $(curmod_prefix)PR16155(::Int64, ::Any)$cfile$PR16155line\n $(curmod_prefix)PR16155(::Any, ::Any)$cfile$PR16155line\n $(curmod_prefix)PR16155{T<:$(curmod_prefix)PR16155}(::Any)$cfile$PR16155line2\n ...\e[0m", - "\nClosest candidates are:\n $(curmod_prefix)PR16155(::Int64, ::Any)$cfile$PR16155line\n $(curmod_prefix)PR16155(::Any, ::Any)$cfile$PR16155line\n $(curmod_prefix)PR16155{T<:$(curmod_prefix)PR16155}(::Any)$cfile$PR16155line2\n ...") +test_have_color(buf, "\e[0m\nClosest candidates are:\n $(curmod_prefix)PR16155(::Int64, ::Any)$cfile$PR16155line\n $(curmod_prefix)PR16155(::Any, ::Any)$cfile$PR16155line\n $(curmod_prefix)PR16155(::Any) where T<:$(curmod_prefix)PR16155$cfile$PR16155line2\n ...\e[0m", + "\nClosest candidates are:\n $(curmod_prefix)PR16155(::Int64, ::Any)$cfile$PR16155line\n $(curmod_prefix)PR16155(::Any, ::Any)$cfile$PR16155line\n $(curmod_prefix)PR16155(::Any) where T<:$(curmod_prefix)PR16155$cfile$PR16155line2\n ...") c6line = @__LINE__ method_c6(; x=1) = x @@ -373,7 +373,7 @@ let err_str, @test sprint(show, which(EightBitType, Tuple{})) == "$(curmod_prefix)EightBitType() in $curmod_str at $sp:$(method_defs_lineno + 2)" @test sprint(show, which(reinterpret(EightBitType, 0x54), Tuple{})) == "(::$(curmod_prefix)EightBitType)() in $curmod_str at $sp:$(method_defs_lineno + 3)" @test sprint(show, which(EightBitTypeT, Tuple{})) == "(::Type{$(curmod_prefix)EightBitTypeT})() in $curmod_str at $sp:$(method_defs_lineno + 4)" - @test sprint(show, which(EightBitTypeT{Int32}, Tuple{})) == "(::Type{$(curmod_prefix)EightBitTypeT{T}}){T}() in $curmod_str at $sp:$(method_defs_lineno + 5)" + @test sprint(show, which(EightBitTypeT{Int32}, Tuple{})) == "(::Type{$(curmod_prefix)EightBitTypeT{T}})() where T in $curmod_str at $sp:$(method_defs_lineno + 5)" @test sprint(show, which(reinterpret(EightBitTypeT{Int32}, 0x54), Tuple{})) == "(::$(curmod_prefix)EightBitTypeT)() in $curmod_str at $sp:$(method_defs_lineno + 6)" @test startswith(sprint(show, which(getfield(Base, Symbol("@doc")), Tuple{Vararg{Any}})), "@doc(x...) in Core at boot.jl:") @test startswith(sprint(show, which(FunctionLike(), Tuple{})), "(::$(curmod_prefix)FunctionLike)() in $curmod_str at $sp:$(method_defs_lineno + 7)") diff --git a/test/show.jl b/test/show.jl index ca2c20997c3b7..bbf65fc40f476 100644 --- a/test/show.jl +++ b/test/show.jl @@ -499,7 +499,7 @@ test_mt(show_f1, "show_f1(x...)") test_mt(show_f2, "show_f2(x...)") test_mt(show_f3, "show_f3(x...)") test_mt(show_f4, "show_f4(x::Vararg{Any,3})") -test_mt(show_f5, "show_f5{T, N}(A::AbstractArray{T,N}, indexes::Vararg{$Int,N})") +test_mt(show_f5, "show_f5(A::AbstractArray{T,N}, indexes::Vararg{$Int,N})") # Issue #15525, printing of vcat @test sprint(show, :([a;])) == ":([a;])" diff --git a/test/vecelement.jl b/test/vecelement.jl index 10ea4c5d8e899..17fc162855e94 100644 --- a/test/vecelement.jl +++ b/test/vecelement.jl @@ -40,7 +40,7 @@ b = Bunch((VecElement(1.0), VecElement(2.0))) immutable Herd{N,T} elts::NTuple{N,Base.VecElement{T}} - Herd(elts::NTuple{N,T}) = new(ntuple(i->Base.VecElement{T}(elts[i]), N)) + Herd{N,T}(elts::NTuple{N,T}) where {N,T} = new(ntuple(i->Base.VecElement{T}(elts[i]), N)) end function check{N,T}(x::Herd{N,T}) diff --git a/test/worlds.jl b/test/worlds.jl index 725204b7d730b..d9f54d662ed8b 100644 --- a/test/worlds.jl +++ b/test/worlds.jl @@ -66,7 +66,7 @@ A265(fld::Int) = A265(Float64(fld)) type B265{T} field1::T # dummy arg is present to prevent (::Type{T}){T}(arg) from matching the test calls - B265(field1::Any, dummy::Void) = new(field1) # prevent generation of outer ctor + B265{T}(field1::Any, dummy::Void) where T = new(field1) # prevent generation of outer ctor end # define some constructors B265(x::Int, dummy::Void) = B265{Int}(x, dummy)