From f0a91f7e344ca62d0fc8840e1e6a0730aaca8160 Mon Sep 17 00:00:00 2001 From: Andy Ferris Date: Thu, 22 Jun 2017 00:19:25 -0700 Subject: [PATCH 1/2] Use Val(x) and f(::Val{x}) Replaces `f(Val{x})` on call sites with `f(Val(x))`, using a new `@pure` function `Val(x) = Val{x}()`. This simplifies the method definitions from `f(::Type{Val{x}}) where x` to `f(::Val{x}) where x`. This form also has the advantage that multiple singleton instances can be put in a tuple and inference will work (similarly with multiple-return functions). --- NEWS.md | 6 +++++ base/abstractarray.jl | 46 +++++++++++++++++++-------------------- base/abstractarraymath.jl | 4 ++-- base/array.jl | 2 +- base/bitarray.jl | 2 +- base/broadcast.jl | 20 ++++++++--------- base/deprecated.jl | 32 +++++++++++++++++++++++---- base/essentials.jl | 29 ++++++++++++++++++------ base/intfuncs.jl | 12 +++++----- base/linalg/arnoldi.jl | 2 +- base/linalg/cholesky.jl | 38 ++++++++++++++++---------------- base/linalg/dense.jl | 2 +- base/linalg/generic.jl | 2 +- base/linalg/lu.jl | 34 ++++++++++++++--------------- base/linalg/qr.jl | 30 ++++++++++++------------- base/linalg/triangular.jl | 4 ++-- base/math.jl | 2 +- base/mmap.jl | 4 ++-- base/multidimensional.jl | 38 ++++++++++++++++---------------- base/permuteddimsarray.jl | 4 ++-- base/precompile.jl | 2 +- base/promotion.jl | 4 ++-- base/reshapedarray.jl | 8 +++---- base/sparse/spqr.jl | 4 ++-- base/subarray.jl | 10 ++++----- base/sysimg.jl | 4 ++-- base/tuple.jl | 18 +++++++-------- src/julia-syntax.scm | 2 +- src/rtutils.c | 2 +- test/abstractarray.jl | 4 ++-- test/arrayops.jl | 14 ++++++------ test/bitarray.jl | 6 ++--- test/core.jl | 10 ++++----- test/dimensionful.jl | 4 ++-- test/inference.jl | 4 ++-- test/linalg/cholesky.jl | 12 +++++----- test/linalg/diagonal.jl | 2 +- test/linalg/generic.jl | 4 ++-- test/linalg/qr.jl | 14 ++++++------ test/linalg/special.jl | 4 ++-- test/numbers.jl | 2 +- test/reflection.jl | 6 ++--- test/subarray.jl | 2 +- test/tuple.jl | 22 +++++++++---------- 44 files changed, 261 insertions(+), 216 deletions(-) diff --git a/NEWS.md b/NEWS.md index e1e29273d0bbc..5c2bb2513dc84 100644 --- a/NEWS.md +++ b/NEWS.md @@ -86,6 +86,12 @@ Library improvements * `@test isequal(x, y)` and `@test isapprox(x, y)` now prints an evaluated expression when the test fails ([#22296]). + * Uses of `Val{c}` in `Base` has been replaced with `Val{c}()`, which is now easily + accessible via the `@pure` constructor `Val(c)`. Functions are defined as + `f(::Val{c}) = ...` and called by `f(Val(c))`. Notable affected functions include: + `ntuple`, `Base.literal_pow`, `sqrtm`, `lufact`, `lufact!`, `qrfact`, `qrfact!`, + `cholfact`, `cholfact!`, `_broadcast!`, `reshape`, `cat` and `cat_t`. + Compiler/Runtime improvements ----------------------------- diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 63ef9ab76b6ec..6f4afcdb8bc79 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -28,7 +28,7 @@ julia> size(A,3,2) """ size(t::AbstractArray{T,N}, d) where {T,N} = d <= N ? size(t)[d] : 1 size(x, d1::Integer, d2::Integer, dx::Vararg{Integer, N}) where {N} = - (size(x, d1), size(x, d2), ntuple(k->size(x, dx[k]), Val{N})...) + (size(x, d1), size(x, d2), ntuple(k->size(x, dx[k]), Val(N))...) """ indices(A, d) @@ -954,13 +954,13 @@ function _getindex(::IndexCartesian, A::AbstractArray{T,N}, I::Vararg{Int, N}) w getindex(A, I...) end _to_subscript_indices(A::AbstractArray, i::Int) = (@_inline_meta; _unsafe_ind2sub(A, i)) -_to_subscript_indices(A::AbstractArray{T,N}) where {T,N} = (@_inline_meta; fill_to_length((), 1, Val{N})) # TODO: DEPRECATE FOR #14770 +_to_subscript_indices(A::AbstractArray{T,N}) where {T,N} = (@_inline_meta; fill_to_length((), 1, Val(N))) # TODO: DEPRECATE FOR #14770 _to_subscript_indices(A::AbstractArray{T,0}) where {T} = () # TODO: REMOVE FOR #14770 _to_subscript_indices(A::AbstractArray{T,0}, i::Int) where {T} = () # TODO: REMOVE FOR #14770 _to_subscript_indices(A::AbstractArray{T,0}, I::Int...) where {T} = () # TODO: DEPRECATE FOR #14770 function _to_subscript_indices(A::AbstractArray{T,N}, I::Int...) where {T,N} # TODO: DEPRECATE FOR #14770 @_inline_meta - J, Jrem = IteratorsMD.split(I, Val{N}) + J, Jrem = IteratorsMD.split(I, Val(N)) _to_subscript_indices(A, J, Jrem) end _to_subscript_indices(A::AbstractArray, J::Tuple, Jrem::Tuple{}) = @@ -1203,7 +1203,7 @@ cat_shape(dims, shape::Tuple) = shape _cshp(ndim::Int, ::Tuple{}, ::Tuple{}, ::Tuple{}) = () _cshp(ndim::Int, ::Tuple{}, ::Tuple{}, nshape) = nshape -_cshp(ndim::Int, dims, ::Tuple{}, ::Tuple{}) = ntuple(b -> 1, Val{length(dims)}) +_cshp(ndim::Int, dims, ::Tuple{}, ::Tuple{}) = ntuple(b -> 1, Val(length(dims))) @inline _cshp(ndim::Int, dims, shape, ::Tuple{}) = (shape[1] + dims[1], _cshp(ndim + 1, tail(dims), tail(shape), ())...) @inline _cshp(ndim::Int, dims, ::Tuple{}, nshape) = @@ -1226,7 +1226,7 @@ end _cs(d, a, b) = (a == b ? a : throw(DimensionMismatch( "mismatch in dimension $d (expected $a got $b)"))) -dims2cat(::Type{Val{n}}) where {n} = ntuple(i -> (i == n), Val{n}) +dims2cat(::Val{n}) where {n} = ntuple(i -> (i == n), Val(n)) dims2cat(dims) = ntuple(i -> (i in dims), maximum(dims)) cat(dims, X...) = cat_t(dims, promote_eltypeof(X...), X...) @@ -1290,7 +1290,7 @@ julia> vcat(c...) 4 5 6 ``` """ -vcat(X...) = cat(Val{1}, X...) +vcat(X...) = cat(Val(1), X...) """ hcat(A...) @@ -1331,28 +1331,28 @@ julia> hcat(c...) 3 6 ``` """ -hcat(X...) = cat(Val{2}, X...) +hcat(X...) = cat(Val(2), X...) -typed_vcat(T::Type, X...) = cat_t(Val{1}, T, X...) -typed_hcat(T::Type, X...) = cat_t(Val{2}, T, X...) +typed_vcat(T::Type, X...) = cat_t(Val(1), T, X...) +typed_hcat(T::Type, X...) = cat_t(Val(2), T, X...) cat(catdims, A::AbstractArray{T}...) where {T} = cat_t(catdims, T, A...) # The specializations for 1 and 2 inputs are important # especially when running with --inline=no, see #11158 -vcat(A::AbstractArray) = cat(Val{1}, A) -vcat(A::AbstractArray, B::AbstractArray) = cat(Val{1}, A, B) -vcat(A::AbstractArray...) = cat(Val{1}, A...) -hcat(A::AbstractArray) = cat(Val{2}, A) -hcat(A::AbstractArray, B::AbstractArray) = cat(Val{2}, A, B) -hcat(A::AbstractArray...) = cat(Val{2}, A...) - -typed_vcat(T::Type, A::AbstractArray) = cat_t(Val{1}, T, A) -typed_vcat(T::Type, A::AbstractArray, B::AbstractArray) = cat_t(Val{1}, T, A, B) -typed_vcat(T::Type, A::AbstractArray...) = cat_t(Val{1}, T, A...) -typed_hcat(T::Type, A::AbstractArray) = cat_t(Val{2}, T, A) -typed_hcat(T::Type, A::AbstractArray, B::AbstractArray) = cat_t(Val{2}, T, A, B) -typed_hcat(T::Type, A::AbstractArray...) = cat_t(Val{2}, T, A...) +vcat(A::AbstractArray) = cat(Val(1), A) +vcat(A::AbstractArray, B::AbstractArray) = cat(Val(1), A, B) +vcat(A::AbstractArray...) = cat(Val(1), A...) +hcat(A::AbstractArray) = cat(Val(2), A) +hcat(A::AbstractArray, B::AbstractArray) = cat(Val(2), A, B) +hcat(A::AbstractArray...) = cat(Val(2), A...) + +typed_vcat(T::Type, A::AbstractArray) = cat_t(Val(1), T, A) +typed_vcat(T::Type, A::AbstractArray, B::AbstractArray) = cat_t(Val(1), T, A, B) +typed_vcat(T::Type, A::AbstractArray...) = cat_t(Val(1), T, A...) +typed_hcat(T::Type, A::AbstractArray) = cat_t(Val(2), T, A) +typed_hcat(T::Type, A::AbstractArray, B::AbstractArray) = cat_t(Val(2), T, A, B) +typed_hcat(T::Type, A::AbstractArray...) = cat_t(Val(2), T, A...) # 2d horizontal and vertical concatenation @@ -1721,7 +1721,7 @@ _sub2ind_vec(i) = () function ind2sub(inds::Union{DimsInteger{N},Indices{N}}, ind::AbstractVector{<:Integer}) where N M = length(ind) - t = ntuple(n->similar(ind),Val{N}) + t = ntuple(n->similar(ind),Val(N)) for (i,idx) in enumerate(IndexLinear(), ind) sub = ind2sub(inds, idx) for j = 1:N diff --git a/base/abstractarraymath.jl b/base/abstractarraymath.jl index 0430293b46737..3815098bceeea 100644 --- a/base/abstractarraymath.jl +++ b/base/abstractarraymath.jl @@ -368,8 +368,8 @@ julia> repeat([1 2; 3 4], inner=(2, 1), outer=(1, 3)) ``` """ function repeat(A::AbstractArray; - inner=ntuple(n->1, Val{ndims(A)}), - outer=ntuple(n->1, Val{ndims(A)})) + inner=ntuple(n->1, Val(ndims(A))), + outer=ntuple(n->1, Val(ndims(A)))) return _repeat(A, rep_kw2tup(inner), rep_kw2tup(outer)) end diff --git a/base/array.jl b/base/array.jl index 56664a53ae4d4..f37c8b6ba889d 100644 --- a/base/array.jl +++ b/base/array.jl @@ -85,7 +85,7 @@ end size(a::Array, d) = arraysize(a, d) size(a::Vector) = (arraysize(a,1),) size(a::Matrix) = (arraysize(a,1), arraysize(a,2)) -size(a::Array{<:Any,N}) where {N} = (@_inline_meta; ntuple(M -> size(a, M), Val{N})) +size(a::Array{<:Any,N}) where {N} = (@_inline_meta; ntuple(M -> size(a, M), Val(N))) asize_from(a::Array, n) = n > ndims(a) ? () : (arraysize(a,n), asize_from(a, n+1)...) diff --git a/base/bitarray.jl b/base/bitarray.jl index e746f27f7d4ca..3a9014122a2f4 100644 --- a/base/bitarray.jl +++ b/base/bitarray.jl @@ -480,7 +480,7 @@ reshape(B::BitArray, dims::Tuple{Vararg{Int}}) = _bitreshape(B, dims) function _bitreshape(B::BitArray, dims::NTuple{N,Int}) where N prod(dims) == length(B) || throw(DimensionMismatch("new dimensions $(dims) must be consistent with array size $(length(B))")) - Br = BitArray{N}(ntuple(i->0,Val{N})...) + Br = BitArray{N}(ntuple(i->0,Val(N))...) Br.chunks = B.chunks Br.len = prod(dims) N != 1 && (Br.dims = dims) diff --git a/base/broadcast.jl b/base/broadcast.jl index b796ee3a22ba9..acb371e9e921f 100644 --- a/base/broadcast.jl +++ b/base/broadcast.jl @@ -134,7 +134,7 @@ Base.@propagate_inbounds _broadcast_getindex(::Any, A, I) = A[I] ## Broadcasting core # nargs encodes the number of As arguments (which matches the number # of keeps). The first two type parameters are to ensure specialization. -@generated function _broadcast!(f, B::AbstractArray, keeps::K, Idefaults::ID, A::AT, Bs::BT, ::Type{Val{N}}, iter) where {K,ID,AT,BT,N} +@generated function _broadcast!(f, B::AbstractArray, keeps::K, Idefaults::ID, A::AT, Bs::BT, ::Val{N}, iter) where {K,ID,AT,BT,N} nargs = N + 1 quote $(Expr(:meta, :inline)) @@ -157,7 +157,7 @@ end # For BitArray outputs, we cache the result in a "small" Vector{Bool}, # and then copy in chunks into the output -@generated function _broadcast!(f, B::BitArray, keeps::K, Idefaults::ID, A::AT, Bs::BT, ::Type{Val{N}}, iter) where {K,ID,AT,BT,N} +@generated function _broadcast!(f, B::BitArray, keeps::K, Idefaults::ID, A::AT, Bs::BT, ::Val{N}, iter) where {K,ID,AT,BT,N} nargs = N + 1 quote $(Expr(:meta, :inline)) @@ -207,12 +207,12 @@ as in `broadcast!(f, A, A, B)` to perform `A[:] = broadcast(f, A, B)`. @boundscheck check_broadcast_indices(shape, A, Bs...) keeps, Idefaults = map_newindexer(shape, A, Bs) iter = CartesianRange(shape) - _broadcast!(f, C, keeps, Idefaults, A, Bs, Val{N}, iter) + _broadcast!(f, C, keeps, Idefaults, A, Bs, Val(N), iter) return C end # broadcast with computed element type -@generated function _broadcast!(f, B::AbstractArray, keeps::K, Idefaults::ID, As::AT, ::Type{Val{nargs}}, iter, st, count) where {K,ID,AT,nargs} +@generated function _broadcast!(f, B::AbstractArray, keeps::K, Idefaults::ID, As::AT, ::Val{nargs}, iter, st, count) where {K,ID,AT,nargs} quote $(Expr(:meta, :noinline)) # destructure the keeps and As tuples @@ -238,7 +238,7 @@ end new[II] = B[II] end new[I] = V - return _broadcast!(f, new, keeps, Idefaults, As, Val{nargs}, iter, st, count+1) + return _broadcast!(f, new, keeps, Idefaults, As, Val(nargs), iter, st, count+1) end count += 1 end @@ -259,12 +259,12 @@ function broadcast_t(f, ::Type{Any}, shape, iter, As...) B = similar(Array{typeof(val)}, shape) end B[I] = val - return _broadcast!(f, B, keeps, Idefaults, As, Val{nargs}, iter, st, 1) + return _broadcast!(f, B, keeps, Idefaults, As, Val(nargs), iter, st, 1) end @inline function broadcast_t(f, T, shape, iter, A, Bs::Vararg{Any,N}) where N C = similar(Array{T}, shape) keeps, Idefaults = map_newindexer(shape, A, Bs) - _broadcast!(f, C, keeps, Idefaults, A, Bs, Val{N}, iter) + _broadcast!(f, C, keeps, Idefaults, A, Bs, Val(N), iter) return C end @@ -275,7 +275,7 @@ end @inline function broadcast_t(f, ::Type{Bool}, shape, iter, A, Bs::Vararg{Any,N}) where N C = similar(BitArray, shape) keeps, Idefaults = map_newindexer(shape, A, Bs) - _broadcast!(f, C, keeps, Idefaults, A, Bs, Val{N}, iter) + _broadcast!(f, C, keeps, Idefaults, A, Bs, Val(N), iter) return C end @@ -335,9 +335,9 @@ end @inline broadcast_c(f, ::Type{Tuple}, A, Bs...) = tuplebroadcast(f, first_tuple(A, Bs...), A, Bs...) @inline tuplebroadcast(f, ::NTuple{N,Any}, As...) where {N} = - ntuple(k -> f(tuplebroadcast_getargs(As, k)...), Val{N}) + ntuple(k -> f(tuplebroadcast_getargs(As, k)...), Val(N)) @inline tuplebroadcast(f, ::NTuple{N,Any}, ::Type{T}, As...) where {N,T} = - ntuple(k -> f(T, tuplebroadcast_getargs(As, k)...), Val{N}) + ntuple(k -> f(T, tuplebroadcast_getargs(As, k)...), Val(N)) first_tuple(A::Tuple, Bs...) = A @inline first_tuple(A, Bs...) = first_tuple(Bs...) tuplebroadcast_getargs(::Tuple{}, k) = () diff --git a/base/deprecated.jl b/base/deprecated.jl index d972540aa3626..978892ad82732 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -1354,12 +1354,12 @@ end @deprecate versioninfo(io::IO, verbose::Bool) versioninfo(io, verbose=verbose) # PR #22188 -@deprecate cholfact!(A::StridedMatrix, uplo::Symbol, ::Type{Val{false}}) cholfact!(Hermitian(A, uplo), Val{false}) +@deprecate cholfact!(A::StridedMatrix, uplo::Symbol, ::Type{Val{false}}) cholfact!(Hermitian(A, uplo), Val(false)) @deprecate cholfact!(A::StridedMatrix, uplo::Symbol) cholfact!(Hermitian(A, uplo)) -@deprecate cholfact(A::StridedMatrix, uplo::Symbol, ::Type{Val{false}}) cholfact(Hermitian(A, uplo), Val{false}) +@deprecate cholfact(A::StridedMatrix, uplo::Symbol, ::Type{Val{false}}) cholfact(Hermitian(A, uplo), Val(false)) @deprecate cholfact(A::StridedMatrix, uplo::Symbol) cholfact(Hermitian(A, uplo)) -@deprecate cholfact!(A::StridedMatrix, uplo::Symbol, ::Type{Val{true}}; tol = 0.0) cholfact!(Hermitian(A, uplo), Val{true}, tol = tol) -@deprecate cholfact(A::StridedMatrix, uplo::Symbol, ::Type{Val{true}}; tol = 0.0) cholfact(Hermitian(A, uplo), Val{true}, tol = tol) +@deprecate cholfact!(A::StridedMatrix, uplo::Symbol, ::Type{Val{true}}; tol = 0.0) cholfact!(Hermitian(A, uplo), Val(true), tol = tol) +@deprecate cholfact(A::StridedMatrix, uplo::Symbol, ::Type{Val{true}}; tol = 0.0) cholfact(Hermitian(A, uplo), Val(true), tol = tol) # PR #22245 @deprecate isposdef(A::AbstractMatrix, UL::Symbol) isposdef(Hermitian(A, UL)) @@ -1519,6 +1519,30 @@ function replace(s::AbstractString, pat, f, n::Integer) end end +# PR #22475 +@deprecate ntuple{N}(f, ::Type{Val{N}}) ntuple(f, Val(N)) +@deprecate fill_to_length{N}(t, val, ::Type{Val{N}}) fill_to_length(t, val, Val(N)) false +@deprecate literal_pow{N}(a, b, ::Type{Val{N}}) literal_pow(a, b, Val(N)) false +@eval IteratorsMD @deprecate split{n}(t, V::Type{Val{n}}) split(t, Val(n)) false +@deprecate sqrtm{T,realmatrix}(A::UpperTriangular{T},::Type{Val{realmatrix}}) sqrtm(A, Val(realmatrix)) +@deprecate lufact(A::AbstractMatrix, ::Type{Val{false}}) lufact(A, Val(false)) +@deprecate lufact(A::AbstractMatrix, ::Type{Val{true}}) lufact(A, Val(true)) +@deprecate lufact!(A::AbstractMatrix, ::Type{Val{false}}) lufact!(A, Val(false)) +@deprecate lufact!(A::AbstractMatrix, ::Type{Val{true}}) lufact!(A, Val(true)) +@deprecate qrfact(A::AbstractMatrix, ::Type{Val{false}}) qrfact(A, Val(false)) +@deprecate qrfact(A::AbstractMatrix, ::Type{Val{true}}) qrfact(A, Val(true)) +@deprecate qrfact!(A::AbstractMatrix, ::Type{Val{false}}) qrfact!(A, Val(false)) +@deprecate qrfact!(A::AbstractMatrix, ::Type{Val{true}}) qrfact!(A, Val(true)) +@deprecate cholfact(A::AbstractMatrix, ::Type{Val{false}}) cholfact(A, Val(false)) +@deprecate cholfact(A::AbstractMatrix, ::Type{Val{true}}; tol = 0.0) cholfact(A, Val(true); tol = tol) +@deprecate cholfact!(A::AbstractMatrix, ::Type{Val{false}}) cholfact!(A, Val(false)) +@deprecate cholfact!(A::AbstractMatrix, ::Type{Val{true}}; tol = 0.0) cholfact!(A, Val(true); tol = tol) +@deprecate cat{N}(::Type{Val{N}}, A::AbstractArray...) cat(Val(N), A...) +@deprecate cat{N}(::Type{Val{N}}, A::SparseArrays._SparseConcatGroup...) cat(Val(N), A...) +@deprecate cat{N}(::Type{Val{N}}, A::SparseArrays._DenseConcatGroup...) cat(Val(N), A...) +@deprecate cat_t{N,T}(::Type{Val{N}}, ::Type{T}, A, B) cat_t(Val(N), T, A, B) false +@deprecate reshape{N}(A::AbstractArray, ::Type{Val{N}}) reshape(A, Val(N)) + # END 0.7 deprecations # BEGIN 1.0 deprecations diff --git a/base/essentials.jl b/base/essentials.jl index 6f3b24e784d99..1184415d7f943 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -313,18 +313,33 @@ struct Colon end const (:) = Colon() -# For passing constants through type inference """ - Val{c} + Val(c) -Create a "value type" out of `c`, which must be an `isbits` value. The intent of this -construct is to be able to dispatch on constants, e.g., `f(Val{false})` allows you to -dispatch directly (at compile-time) to an implementation `f(::Type{Val{false}})`, without -having to test the boolean value at runtime. +Return `Val{c}()`, which contains no run-time data. Types like this can be used to +pass the information between functions through the value `c`, which must be an `isbits` +value. The intent of this construct is to be able to dispatch on constants directly (at +compile time) without having to test the value of the constant at run time. + +# Examples +```jldoctest +julia> f(::Val{true}) = "Good" +f (generic function with 1 method) + +julia> f(::Val{false}) = "Bad" +f (generic function with 2 methods) + +julia> f(Val(true)) +"Good" +``` """ -struct Val{T} +struct Val{x} end +Val(x) = (@_pure_meta; Val{x}()) + +show(io::IO, ::Val{x}) where {x} = print(io, "Val($x)") + # used by interpolating quote and some other things in the front end function vector_any(xs::ANY...) n = length(xs) diff --git a/base/intfuncs.jl b/base/intfuncs.jl index 82f5db4b2fa45..0d0c2af9d5ed0 100644 --- a/base/intfuncs.jl +++ b/base/intfuncs.jl @@ -198,14 +198,14 @@ end ^(x::Number, p::Integer) = power_by_squaring(x,p) ^(x, p::Integer) = power_by_squaring(x,p) -# x^p for any literal integer p is lowered to Base.literal_pow(^, x, Val{p}) +# x^p for any literal integer p is lowered to Base.literal_pow(^, x, Val(p)) # to enable compile-time optimizations specialized to p. # However, we still need a fallback that calls the function ^ which may either # mean Base.^ or something else, depending on context. # We mark these @inline since if the target is marked @inline, # we want to make sure that gets propagated, # even if it is over the inlining threshold. -@inline literal_pow(f, x, ::Type{Val{p}}) where {p} = f(x,p) +@inline literal_pow(f, x, ::Val{p}) where {p} = f(x,p) # Restrict inlining to hardware-supported arithmetic types, which # are fast enough to benefit from inlining. @@ -216,10 +216,10 @@ const HWNumber = Union{HWReal, Complex{<:HWReal}, Rational{<:HWReal}} # numeric types. In terms of Val we can do it much more simply. # (The first argument prevents unexpected behavior if a function ^ # is defined that is not equal to Base.^) -@inline literal_pow(::typeof(^), x::HWNumber, ::Type{Val{0}}) = one(x) -@inline literal_pow(::typeof(^), x::HWNumber, ::Type{Val{1}}) = x -@inline literal_pow(::typeof(^), x::HWNumber, ::Type{Val{2}}) = x*x -@inline literal_pow(::typeof(^), x::HWNumber, ::Type{Val{3}}) = x*x*x +@inline literal_pow(::typeof(^), x::HWNumber, ::Val{0}) = one(x) +@inline literal_pow(::typeof(^), x::HWNumber, ::Val{1}) = x +@inline literal_pow(::typeof(^), x::HWNumber, ::Val{2}) = x*x +@inline literal_pow(::typeof(^), x::HWNumber, ::Val{3}) = x*x*x # b^p mod m diff --git a/base/linalg/arnoldi.jl b/base/linalg/arnoldi.jl index 73b25f8d892dc..c77b571122b0d 100644 --- a/base/linalg/arnoldi.jl +++ b/base/linalg/arnoldi.jl @@ -339,7 +339,7 @@ function A_mul_B!(y::StridedVector{T}, A::AtA_or_AAt{T}, x::StridedVector{T}) wh return A_mul_B!(y, A.A, A.buffer) end end -size(A::AtA_or_AAt) = ntuple(i -> min(size(A.A)...), Val{2}) +size(A::AtA_or_AAt) = ntuple(i -> min(size(A.A)...), Val(2)) ishermitian(s::AtA_or_AAt) = true diff --git a/base/linalg/cholesky.jl b/base/linalg/cholesky.jl index c42a5325aa8eb..c19d710067cc7 100644 --- a/base/linalg/cholesky.jl +++ b/base/linalg/cholesky.jl @@ -10,10 +10,10 @@ # In the methods below, LAPACK is called when possible, i.e. StridedMatrices with Float32, # Float64, Complex{Float32}, and Complex{Float64} element types. For other element or # matrix types, the unblocked Julia implementation in _chol! is used. For cholfact -# and cholfact! pivoting is supported through a Val{Bool} argument. A type argument is +# and cholfact! pivoting is supported through a Val(Bool) argument. A type argument is # necessary for type stability since the output of cholfact and cholfact! is either # Cholesky or PivotedCholesky. The latter is only -# supported for the four LAPACK element types. For other types, e.g. BigFloats Val{true} will +# supported for the four LAPACK element types. For other types, e.g. BigFloats Val(true) will # give an error. It is required that the input is Hermitian (including real symmetric) either # through the Hermitian and Symmetric views or exact symmetric or Hermitian elements which # is checked for and an error is thrown if the check fails. @@ -208,7 +208,7 @@ chol(x::Number, args...) = ((C, info) = _chol!(x, nothing); @assertposdef C info # cholfact!. Destructive methods for computing Cholesky factorization of real symmetric # or Hermitian matrix ## No pivoting (default) -function cholfact!(A::RealHermSymComplexHerm, ::Type{Val{false}}=Val{false}) +function cholfact!(A::RealHermSymComplexHerm, ::Val{false}=Val(false)) if A.uplo == 'U' CU, info = _chol!(A.data, UpperTriangular) Cholesky(CU.data, 'U', info) @@ -220,7 +220,7 @@ end ### for StridedMatrices, check that matrix is symmetric/Hermitian """ - cholfact!(A, Val{false}) -> Cholesky + cholfact!(A, Val(false)) -> Cholesky The same as [`cholfact`](@ref), but saves space by overwriting the input `A`, instead of creating a copy. An [`InexactError`](@ref) exception is thrown if @@ -239,49 +239,49 @@ julia> cholfact!(A) ERROR: InexactError() ``` """ -function cholfact!(A::StridedMatrix, ::Type{Val{false}}=Val{false}) +function cholfact!(A::StridedMatrix, ::Val{false}=Val(false)) ishermitian(A) || non_hermitian_error("cholfact!") - return cholfact!(Hermitian(A), Val{false}) + return cholfact!(Hermitian(A), Val(false)) end ## With pivoting ### BLAS/LAPACK element types function cholfact!(A::RealHermSymComplexHerm{<:BlasReal,<:StridedMatrix}, - ::Type{Val{true}}; tol = 0.0) + ::Val{true}; tol = 0.0) AA, piv, rank, info = LAPACK.pstrf!(A.uplo, A.data, tol) return CholeskyPivoted{eltype(AA),typeof(AA)}(AA, A.uplo, piv, rank, tol, info) end ### Non BLAS/LAPACK element types (generic). Since generic fallback for pivoted Cholesky ### is not implemented yet we throw an error -cholfact!(A::RealHermSymComplexHerm{<:Real}, ::Type{Val{true}}; +cholfact!(A::RealHermSymComplexHerm{<:Real}, ::Val{true}; tol = 0.0) = throw(ArgumentError("generic pivoted Cholesky factorization is not implemented yet")) ### for StridedMatrices, check that matrix is symmetric/Hermitian """ - cholfact!(A, Val{true}; tol = 0.0) -> CholeskyPivoted + cholfact!(A, Val(true); tol = 0.0) -> CholeskyPivoted The same as [`cholfact`](@ref), but saves space by overwriting the input `A`, instead of creating a copy. An [`InexactError`](@ref) exception is thrown if the factorization produces a number not representable by the element type of `A`, e.g. for integer types. """ -function cholfact!(A::StridedMatrix, ::Type{Val{true}}; tol = 0.0) +function cholfact!(A::StridedMatrix, ::Val{true}; tol = 0.0) ishermitian(A) || non_hermitian_error("cholfact!") - return cholfact!(Hermitian(A), Val{true}; tol = tol) + return cholfact!(Hermitian(A), Val(true); tol = tol) end # cholfact. Non-destructive methods for computing Cholesky factorization of real symmetric # or Hermitian matrix ## No pivoting (default) -cholfact(A::RealHermSymComplexHerm{<:Real,<:StridedMatrix}, ::Type{Val{false}}=Val{false}) = +cholfact(A::RealHermSymComplexHerm{<:Real,<:StridedMatrix}, ::Val{false}=Val(false)) = cholfact!(copy_oftype(A, promote_type(typeof(chol(one(eltype(A)))),Float32))) ### for StridedMatrices, check that matrix is symmetric/Hermitian """ - cholfact(A, Val{false}) -> Cholesky + cholfact(A, Val(false)) -> Cholesky Compute the Cholesky factorization of a dense symmetric positive definite matrix `A` and return a `Cholesky` factorization. The matrix `A` can either be a [`Symmetric`](@ref) or [`Hermitian`](@ref) @@ -319,20 +319,20 @@ julia> C[:L] * C[:U] == A true ``` """ -function cholfact(A::StridedMatrix, ::Type{Val{false}}=Val{false}) +function cholfact(A::StridedMatrix, ::Val{false}=Val(false)) ishermitian(A) || non_hermitian_error("cholfact") return cholfact(Hermitian(A)) end ## With pivoting -cholfact(A::RealHermSymComplexHerm{<:Real,<:StridedMatrix}, ::Type{Val{true}}; tol = 0.0) = +cholfact(A::RealHermSymComplexHerm{<:Real,<:StridedMatrix}, ::Val{true}; tol = 0.0) = cholfact!(copy_oftype(A, promote_type(typeof(chol(one(eltype(A)))),Float32)), - Val{true}; tol = tol) + Val(true); tol = tol) ### for StridedMatrices, check that matrix is symmetric/Hermitian """ - cholfact(A, Val{true}; tol = 0.0) -> CholeskyPivoted + cholfact(A, Val(true); tol = 0.0) -> CholeskyPivoted Compute the pivoted Cholesky factorization of a dense symmetric positive semi-definite matrix `A` and return a `CholeskyPivoted` factorization. The matrix `A` can either be a [`Symmetric`](@ref) @@ -343,9 +343,9 @@ The following functions are available for `PivotedCholesky` objects: The argument `tol` determines the tolerance for determining the rank. For negative values, the tolerance is the machine precision. """ -function cholfact(A::StridedMatrix, ::Type{Val{true}}; tol = 0.0) +function cholfact(A::StridedMatrix, ::Val{true}; tol = 0.0) ishermitian(A) || non_hermitian_error("cholfact") - return cholfact(Hermitian(A), Val{true}; tol = tol) + return cholfact(Hermitian(A), Val(true); tol = tol) end ## Number diff --git a/base/linalg/dense.jl b/base/linalg/dense.jl index ab2dac2d1dbe8..7ed1c8f9a027e 100644 --- a/base/linalg/dense.jl +++ b/base/linalg/dense.jl @@ -780,7 +780,7 @@ function factorize(A::StridedMatrix{T}) where T end return lufact(A) end - qrfact(A, Val{true}) + qrfact(A, Val(true)) end ## Moore-Penrose pseudoinverse diff --git a/base/linalg/generic.jl b/base/linalg/generic.jl index 82c8dab165336..13c90b4469b34 100644 --- a/base/linalg/generic.jl +++ b/base/linalg/generic.jl @@ -831,7 +831,7 @@ function (\)(A::AbstractMatrix, B::AbstractVecOrMat) end return lufact(A) \ B end - return qrfact(A,Val{true}) \ B + return qrfact(A,Val(true)) \ B end (\)(a::AbstractVector, b::AbstractArray) = reshape(a, length(a), 1) \ b diff --git a/base/linalg/lu.jl b/base/linalg/lu.jl index ca93cc69fb202..a0c85a8a9a96b 100644 --- a/base/linalg/lu.jl +++ b/base/linalg/lu.jl @@ -12,28 +12,28 @@ end LU(factors::AbstractMatrix{T}, ipiv::Vector{BlasInt}, info::BlasInt) where {T} = LU{T,typeof(factors)}(factors, ipiv, info) # StridedMatrix -function lufact!(A::StridedMatrix{T}, pivot::Union{Type{Val{false}}, Type{Val{true}}} = Val{true}) where T<:BlasFloat - if pivot === Val{false} +function lufact!(A::StridedMatrix{T}, pivot::Union{Val{false}, Val{true}} = Val(true)) where T<:BlasFloat + if pivot === Val(false) return generic_lufact!(A, pivot) end lpt = LAPACK.getrf!(A) return LU{T,typeof(A)}(lpt[1], lpt[2], lpt[3]) end -function lufact!(A::HermOrSym, pivot::Union{Type{Val{false}}, Type{Val{true}}} = Val{true}) +function lufact!(A::HermOrSym, pivot::Union{Val{false}, Val{true}} = Val(true)) copytri!(A.data, A.uplo, isa(A, Hermitian)) lufact!(A.data, pivot) end """ - lufact!(A, pivot=Val{true}) -> LU + lufact!(A, pivot=Val(true)) -> LU `lufact!` is the same as [`lufact`](@ref), but saves space by overwriting the input `A`, instead of creating a copy. An [`InexactError`](@ref) exception is thrown if the factorization produces a number not representable by the element type of `A`, e.g. for integer types. """ -lufact!(A::StridedMatrix, pivot::Union{Type{Val{false}}, Type{Val{true}}} = Val{true}) = generic_lufact!(A, pivot) -function generic_lufact!(A::StridedMatrix{T}, ::Type{Val{Pivot}} = Val{true}) where {T,Pivot} +lufact!(A::StridedMatrix, pivot::Union{Val{false}, Val{true}} = Val(true)) = generic_lufact!(A, pivot) +function generic_lufact!(A::StridedMatrix{T}, ::Val{Pivot} = Val(true)) where {T,Pivot} m, n = size(A) minmn = min(m,n) info = 0 @@ -83,12 +83,12 @@ end # floating point types doesn't have to be promoted for LU, but should default to pivoting lufact(A::Union{AbstractMatrix{T}, AbstractMatrix{Complex{T}}}, - pivot::Union{Type{Val{false}}, Type{Val{true}}} = Val{true}) where {T<:AbstractFloat} = + pivot::Union{Val{false}, Val{true}} = Val(true)) where {T<:AbstractFloat} = lufact!(copy(A), pivot) # for all other types we must promote to a type which is stable under division """ - lufact(A [,pivot=Val{true}]) -> F::LU + lufact(A [,pivot=Val(true)]) -> F::LU Compute the LU factorization of `A`. @@ -139,7 +139,7 @@ julia> F[:L] * F[:U] == A[F[:p], :] true ``` """ -function lufact(A::AbstractMatrix{T}, pivot::Union{Type{Val{false}}, Type{Val{true}}}) where T +function lufact(A::AbstractMatrix{T}, pivot::Union{Val{false}, Val{true}}) where T S = typeof(zero(T)/one(T)) AA = similar(A, S, size(A)) copy!(AA, A) @@ -150,13 +150,13 @@ function lufact(A::AbstractMatrix{T}) where T S = typeof(zero(T)/one(T)) AA = similar(A, S, size(A)) copy!(AA, A) - F = lufact!(AA, Val{false}) + F = lufact!(AA, Val(false)) if issuccess(F) return F else AA = similar(A, S, size(A)) copy!(AA, A) - return lufact!(AA, Val{true}) + return lufact!(AA, Val(true)) end end @@ -166,11 +166,11 @@ lufact(F::LU) = F lu(x::Number) = (one(x), x, 1) """ - lu(A, pivot=Val{true}) -> L, U, p + lu(A, pivot=Val(true)) -> L, U, p Compute the LU factorization of `A`, such that `A[p,:] = L*U`. By default, pivoting is used. This can be overridden by passing -`Val{false}` for the second argument. +`Val(false)` for the second argument. See also [`lufact`](@ref). @@ -189,7 +189,7 @@ julia> A[p, :] == L * U true ``` """ -function lu(A::AbstractMatrix, pivot::Union{Type{Val{false}}, Type{Val{true}}} = Val{true}) +function lu(A::AbstractMatrix, pivot::Union{Val{false}, Val{true}} = Val(true)) F = lufact(A, pivot) F[:L], F[:U], F[:p] end @@ -326,7 +326,7 @@ end # Tridiagonal # See dgttrf.f -function lufact!(A::Tridiagonal{T}, pivot::Union{Type{Val{false}}, Type{Val{true}}} = Val{true}) where T +function lufact!(A::Tridiagonal{T}, pivot::Union{Val{false}, Val{true}} = Val(true)) where T n = size(A, 1) info = 0 ipiv = Vector{BlasInt}(n) @@ -341,7 +341,7 @@ function lufact!(A::Tridiagonal{T}, pivot::Union{Type{Val{false}}, Type{Val{true end for i = 1:n-2 # pivot or not? - if pivot === Val{false} || abs(d[i]) >= abs(dl[i]) + if pivot === Val(false) || abs(d[i]) >= abs(dl[i]) # No interchange if d[i] != 0 fact = dl[i]/d[i] @@ -364,7 +364,7 @@ function lufact!(A::Tridiagonal{T}, pivot::Union{Type{Val{false}}, Type{Val{true end if n > 1 i = n-1 - if pivot === Val{false} || abs(d[i]) >= abs(dl[i]) + if pivot === Val(false) || abs(d[i]) >= abs(dl[i]) if d[i] != 0 fact = dl[i]/d[i] dl[i] = fact diff --git a/base/linalg/qr.jl b/base/linalg/qr.jl index ca380455e4c84..6cdd2d0dd3ede 100644 --- a/base/linalg/qr.jl +++ b/base/linalg/qr.jl @@ -194,26 +194,26 @@ function qrfactPivotedUnblocked!(A::StridedMatrix) end # LAPACK version -qrfact!(A::StridedMatrix{<:BlasFloat}, ::Type{Val{false}}) = QRCompactWY(LAPACK.geqrt!(A, min(minimum(size(A)), 36))...) -qrfact!(A::StridedMatrix{<:BlasFloat}, ::Type{Val{true}}) = QRPivoted(LAPACK.geqp3!(A)...) -qrfact!(A::StridedMatrix{<:BlasFloat}) = qrfact!(A, Val{false}) +qrfact!(A::StridedMatrix{<:BlasFloat}, ::Val{false}) = QRCompactWY(LAPACK.geqrt!(A, min(minimum(size(A)), 36))...) +qrfact!(A::StridedMatrix{<:BlasFloat}, ::Val{true}) = QRPivoted(LAPACK.geqp3!(A)...) +qrfact!(A::StridedMatrix{<:BlasFloat}) = qrfact!(A, Val(false)) # Generic fallbacks """ - qrfact!(A, pivot=Val{false}) + qrfact!(A, pivot=Val(false)) `qrfact!` is the same as [`qrfact`](@ref) when `A` is a subtype of `StridedMatrix`, but saves space by overwriting the input `A`, instead of creating a copy. An [`InexactError`](@ref) exception is thrown if the factorization produces a number not representable by the element type of `A`, e.g. for integer types. """ -qrfact!(A::StridedMatrix, ::Type{Val{false}}) = qrfactUnblocked!(A) -qrfact!(A::StridedMatrix, ::Type{Val{true}}) = qrfactPivotedUnblocked!(A) -qrfact!(A::StridedMatrix) = qrfact!(A, Val{false}) +qrfact!(A::StridedMatrix, ::Val{false}) = qrfactUnblocked!(A) +qrfact!(A::StridedMatrix, ::Val{true}) = qrfactPivotedUnblocked!(A) +qrfact!(A::StridedMatrix) = qrfact!(A, Val(false)) """ - qrfact(A, pivot=Val{false}) -> F + qrfact(A, pivot=Val(false)) -> F Compute the QR factorization of the matrix `A`: an orthogonal (or unitary if `A` is complex-valued) matrix `Q`, and an upper triangular matrix `R` such that @@ -224,7 +224,7 @@ A = Q R The returned object `F` stores the factorization in a packed format: - - if `pivot == Val{true}` then `F` is a [`QRPivoted`](@ref) object, + - if `pivot == Val(true)` then `F` is a [`QRPivoted`](@ref) object, - otherwise if the element type of `A` is a BLAS type ([`Float32`](@ref), [`Float64`](@ref), `Complex64` or `Complex128`), then `F` is a [`QRCompactWY`](@ref) object, @@ -283,21 +283,21 @@ end qrfact(x::Number) = qrfact(fill(x,1,1)) """ - qr(A, pivot=Val{false}; thin::Bool=true) -> Q, R, [p] + qr(A, pivot=Val(false); thin::Bool=true) -> Q, R, [p] Compute the (pivoted) QR factorization of `A` such that either `A = Q*R` or `A[:,p] = Q*R`. Also see [`qrfact`](@ref). The default is to compute a thin factorization. Note that `R` is not extended with zeros when the full `Q` is requested. """ -qr(A::Union{Number, AbstractMatrix}, pivot::Union{Type{Val{false}}, Type{Val{true}}}=Val{false}; thin::Bool=true) = +qr(A::Union{Number, AbstractMatrix}, pivot::Union{Val{false}, Val{true}}=Val(false); thin::Bool=true) = _qr(A, pivot, thin=thin) -function _qr(A::Union{Number, AbstractMatrix}, ::Type{Val{false}}; thin::Bool=true) - F = qrfact(A, Val{false}) +function _qr(A::Union{Number, AbstractMatrix}, ::Val{false}; thin::Bool=true) + F = qrfact(A, Val(false)) full(getq(F), thin=thin), F[:R]::Matrix{eltype(F)} end -function _qr(A::Union{Number, AbstractMatrix}, ::Type{Val{true}}; thin::Bool=true) - F = qrfact(A, Val{true}) +function _qr(A::Union{Number, AbstractMatrix}, ::Val{true}; thin::Bool=true) + F = qrfact(A, Val(true)) full(getq(F), thin=thin), F[:R]::Matrix{eltype(F)}, F[:p]::Vector{BlasInt} end diff --git a/base/linalg/triangular.jl b/base/linalg/triangular.jl index 27a671abacf4c..23925928cff90 100644 --- a/base/linalg/triangular.jl +++ b/base/linalg/triangular.jl @@ -2126,9 +2126,9 @@ function sqrtm(A::UpperTriangular) end end end - sqrtm(A,Val{realmatrix}) + sqrtm(A,Val(realmatrix)) end -function sqrtm(A::UpperTriangular{T},::Type{Val{realmatrix}}) where {T,realmatrix} +function sqrtm(A::UpperTriangular{T},::Val{realmatrix}) where {T,realmatrix} B = A.data n = checksquare(B) t = realmatrix ? typeof(sqrt(zero(T))) : typeof(sqrt(complex(zero(T)))) diff --git a/base/math.jl b/base/math.jl index 454b6e4cdc9fe..57750d555c510 100644 --- a/base/math.jl +++ b/base/math.jl @@ -710,7 +710,7 @@ end @inline ^(x::Float64, y::Integer) = x ^ Float64(y) @inline ^(x::Float32, y::Integer) = x ^ Float32(y) @inline ^(x::Float16, y::Integer) = Float16(Float32(x) ^ Float32(y)) -@inline literal_pow(::typeof(^), x::Float16, ::Type{Val{p}}) where {p} = Float16(literal_pow(^,Float32(x),Val{p})) +@inline literal_pow(::typeof(^), x::Float16, ::Val{p}) where {p} = Float16(literal_pow(^,Float32(x),Val(p))) function angle_restrict_symm(theta) const P1 = 4 * 7.8539812564849853515625e-01 diff --git a/base/mmap.jl b/base/mmap.jl index eaac57e30b4df..22e8dc3110201 100644 --- a/base/mmap.jl +++ b/base/mmap.jl @@ -104,7 +104,7 @@ function mmap(io::IO, len = prod(dims) * sizeof(T) len >= 0 || throw(ArgumentError("requested size must be ≥ 0, got $len")) - len == 0 && return Array{T}(ntuple(x->0,Val{N})) + len == 0 && return Array{T}(ntuple(x->0,Val(N))) len < typemax(Int) - PAGESIZE || throw(ArgumentError("requested size must be < $(typemax(Int)-PAGESIZE), got $len")) offset >= 0 || throw(ArgumentError("requested offset must be ≥ 0, got $offset")) @@ -177,7 +177,7 @@ function mmap(io::IOStream, ::Type{<:BitArray}, dims::NTuple{N,Integer}, throw(ArgumentError("the given file does not contain a valid BitArray of size $(join(dims, 'x')) (open with \"r+\" mode to override)")) end end - B = BitArray{N}(ntuple(i->0,Val{N})...) + B = BitArray{N}(ntuple(i->0,Val(N))...) B.chunks = chunks B.len = n if N != 1 diff --git a/base/multidimensional.jl b/base/multidimensional.jl index ffb5f61923db1..ca5a6f74a412a 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -68,7 +68,7 @@ module IteratorsMD CartesianIndex(index::Integer...) = CartesianIndex(index) CartesianIndex{N}(index::Vararg{Integer,N}) where {N} = CartesianIndex{N}(index) # Allow passing tuples smaller than N - CartesianIndex{N}(index::Tuple) where {N} = CartesianIndex{N}(fill_to_length(index, 1, Val{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 @@ -91,9 +91,9 @@ module IteratorsMD # zeros and ones zero(::CartesianIndex{N}) where {N} = zero(CartesianIndex{N}) - zero(::Type{CartesianIndex{N}}) where {N} = CartesianIndex(ntuple(x -> 0, Val{N})) + zero(::Type{CartesianIndex{N}}) where {N} = CartesianIndex(ntuple(x -> 0, Val(N))) one(::CartesianIndex{N}) where {N} = one(CartesianIndex{N}) - one(::Type{CartesianIndex{N}}) where {N} = CartesianIndex(ntuple(x -> 1, Val{N})) + one(::Type{CartesianIndex{N}}) where {N} = CartesianIndex(ntuple(x -> 1, Val(N))) # arithmetic, min/max @inline (-)(index::CartesianIndex{N}) where {N} = @@ -249,18 +249,18 @@ module IteratorsMD end # Split out the first N elements of a tuple - @inline split(t, V::Type{<:Val}) = _split((), t, V) - @inline _split(tN, trest, V) = _split((tN..., trest[1]), tail(trest), V) + @inline split(t, V::Val) = _split((), t, V) + @inline _split(tN, trest, V::Val) = _split((tN..., trest[1]), tail(trest), V) # exit either when we've exhausted the input tuple or when tN has length N - @inline _split(tN::NTuple{N,Any}, ::Tuple{}, ::Type{Val{N}}) where {N} = tN, () # ambig. - @inline _split(tN, ::Tuple{}, ::Type{Val{N}}) where {N} = tN, () - @inline _split(tN::NTuple{N,Any}, trest, ::Type{Val{N}}) where {N} = tN, trest + @inline _split(tN::NTuple{N,Any}, ::Tuple{}, ::Val{N}) where {N} = tN, () # ambig. + @inline _split(tN, ::Tuple{}, ::Val{N}) where {N} = tN, () + @inline _split(tN::NTuple{N,Any}, trest, ::Val{N}) where {N} = tN, trest - @inline function split(I::CartesianIndex, V::Type{<:Val}) + @inline function split(I::CartesianIndex, V::Val) i, j = split(I.I, V) CartesianIndex(i), CartesianIndex(j) end - function split(R::CartesianRange, V::Type{<:Val}) + function split(R::CartesianRange, V::Val) istart, jstart = split(first(R), V) istop, jstop = split(last(R), V) CartesianRange(istart, istop), CartesianRange(jstart, jstop) @@ -309,7 +309,7 @@ end end @inline function checkbounds_indices(::Type{Bool}, IA::Tuple, I::Tuple{AbstractArray{CartesianIndex{N}},Vararg{Any}}) where N - IA1, IArest = IteratorsMD.split(IA, Val{N}) + IA1, IArest = IteratorsMD.split(IA, Val(N)) checkindex(Bool, IA1, I[1]) & checkbounds_indices(Bool, IArest, tail(I)) end @@ -329,7 +329,7 @@ end (map(x->true, i1.I)..., index_ndims(I...)...) end @inline function index_ndims(i1::AbstractArray{CartesianIndex{N}}, I...) where N - (ntuple(x->true, Val{N})..., index_ndims(I...)...) + (ntuple(x->true, Val(N))..., index_ndims(I...)...) end index_ndims() = () @@ -339,7 +339,7 @@ index_ndims() = () @inline index_dimsum(::Colon, I...) = (true, index_dimsum(I...)...) @inline index_dimsum(::AbstractArray{Bool}, I...) = (true, index_dimsum(I...)...) @inline function index_dimsum(::AbstractArray{<:Any,N}, I...) where N - (ntuple(x->true, Val{N})..., index_dimsum(I...)...) + (ntuple(x->true, Val(N))..., index_dimsum(I...)...) end index_dimsum() = () @@ -420,7 +420,7 @@ end @inline checkbounds_indices(::Type{Bool},IA::Tuple{Any},I::Tuple{LogicalIndex{Int,AbstractArray{Bool,N}}}) where {N} = checkindex(Bool, IA[1], I[1]) @inline function checkbounds_indices(::Type{Bool}, IA::Tuple, I::Tuple{LogicalIndex{Int,AbstractArray{Bool,N}}}) where N - IA1, IArest = IteratorsMD.split(IA, Val{N}) + IA1, IArest = IteratorsMD.split(IA, Val(N)) checkindex(Bool, IA1, I[1]) end @inline checkbounds(::Type{Bool}, A::AbstractArray, I::LogicalIndex{<:Any,<:AbstractArray{Bool,1}}) = @@ -443,12 +443,12 @@ to_indices(A, I::Tuple{}) = () to_indices(A, inds, (I[1].I..., tail(I)...)) # But for arrays of CartesianIndex, we just skip the appropriate number of inds @inline function to_indices(A, inds, I::Tuple{AbstractArray{CartesianIndex{N}}, Vararg{Any}}) where N - _, indstail = IteratorsMD.split(inds, Val{N}) + _, indstail = IteratorsMD.split(inds, Val(N)) (to_index(A, I[1]), to_indices(A, indstail, tail(I))...) end # And boolean arrays behave similarly; they also skip their number of dimensions @inline function to_indices(A, inds, I::Tuple{AbstractArray{Bool, N}, Vararg{Any}}) where N - _, indstail = IteratorsMD.split(inds, Val{N}) + _, indstail = IteratorsMD.split(inds, Val(N)) (to_index(A, I[1]), to_indices(A, indstail, tail(I))...) end # As an optimization, we allow trailing Array{Bool} and BitArray to be linear over trailing dimensions @@ -488,7 +488,7 @@ _maybe_reshape(::IndexLinear, A::AbstractArray, I...) = A _maybe_reshape(::IndexCartesian, A::AbstractVector, I...) = A @inline _maybe_reshape(::IndexCartesian, A::AbstractArray, I...) = __maybe_reshape(A, index_ndims(I...)) @inline __maybe_reshape(A::AbstractArray{T,N}, ::NTuple{N,Any}) where {T,N} = A -@inline __maybe_reshape(A::AbstractArray, ::NTuple{N,Any}) where {N} = reshape(A, Val{N}) +@inline __maybe_reshape(A::AbstractArray, ::NTuple{N,Any}) where {N} = reshape(A, Val(N)) function _unsafe_getindex(::IndexStyle, A::AbstractArray, I::Vararg{Union{Real, AbstractArray}, N}) where N # This is specifically not inlined to prevent excessive allocations in type unstable code @@ -897,7 +897,7 @@ See also [`circshift`](@ref). dest === src && throw(ArgumentError("dest and src must be separate arrays")) inds = indices(src) indices(dest) == inds || throw(ArgumentError("indices of src and dest must match (got $inds and $(indices(dest)))")) - _circshift!(dest, (), src, (), inds, fill_to_length(shiftamt, 0, Val{N})) + _circshift!(dest, (), src, (), inds, fill_to_length(shiftamt, 0, Val(N))) end circshift!(dest::AbstractArray, src, shiftamt) = circshift!(dest, src, (shiftamt...,)) @@ -1240,7 +1240,7 @@ end @generated function findn(B::BitArray{N}) where N quote nnzB = countnz(B) - I = ntuple(x->Vector{Int}(nnzB), Val{$N}) + I = ntuple(x->Vector{Int}(nnzB), Val($N)) if nnzB > 0 count = 1 @nloops $N i B begin diff --git a/base/permuteddimsarray.jl b/base/permuteddimsarray.jl index fd69695edda96..84f345d8a3417 100644 --- a/base/permuteddimsarray.jl +++ b/base/permuteddimsarray.jl @@ -60,7 +60,7 @@ Base.pointer(A::PermutedDimsArray, i::Integer) = throw(ArgumentError("pointer(A, function Base.strides(A::PermutedDimsArray{T,N,perm}) where {T,N,perm} s = strides(parent(A)) - ntuple(d->s[perm[d]], Val{N}) + ntuple(d->s[perm[d]], Val(N)) end @inline function Base.getindex(A::PermutedDimsArray{T,N,perm,iperm}, I::Vararg{Int,N}) where {T,N,perm,iperm} @@ -74,7 +74,7 @@ end val end -@inline genperm(I::NTuple{N,Any}, perm::Dims{N}) where {N} = ntuple(d -> I[perm[d]], Val{N}) +@inline genperm(I::NTuple{N,Any}, perm::Dims{N}) where {N} = ntuple(d -> I[perm[d]], Val(N)) @inline genperm(I, perm::AbstractVector{Int}) = genperm(I, (perm...,)) """ diff --git a/base/precompile.jl b/base/precompile.jl index 2587bec08e738..dc456608c4255 100644 --- a/base/precompile.jl +++ b/base/precompile.jl @@ -624,7 +624,7 @@ precompile(Tuple{typeof(Base.cat_indices), String, Int64}) precompile(Tuple{typeof(Base.cat_size), String, Int64}) precompile(Tuple{typeof(Base.setindex!), Array{Any, 1}, String, Base.UnitRange{Int64}}) precompile(Tuple{typeof(Base._cat), Array{Any, 1}, Tuple{Int64}, Tuple{Bool}, String, Array{Any, 1}, String}) -precompile(Tuple{typeof(Base.cat_t), Type{Base.Val{1}}, Type{Any}, String, Array{Any, 1}, String}) +precompile(Tuple{typeof(Base.cat_t), Base.Val{1}, Type{Any}, String, Array{Any, 1}, String}) precompile(Tuple{typeof(Base.Sort.searchsortedfirst), Array{String, 1}, String, Int64, Int64, Base.Order.ForwardOrdering}) precompile(Tuple{typeof(Base.Sort.searchsortedlast), Array{String, 1}, String, Int64, Int64, Base.Order.ForwardOrdering}) precompile(Tuple{typeof(Base.Sort.searchsorted), Array{String, 1}, String, Int64, Int64, Base.Order.ForwardOrdering}) diff --git a/base/promotion.jl b/base/promotion.jl index e5f2bdd6f80de..b2d163ecd1614 100644 --- a/base/promotion.jl +++ b/base/promotion.jl @@ -257,9 +257,9 @@ end Exponentiation operator. If `x` is a matrix, computes matrix exponentiation. If `y` is an `Int` literal (e.g. `2` in `x^2` or `-3` in `x^-3`), the Julia code -`x^y` is transformed by the compiler to `Base.literal_pow(^, x, Val{y})`, to +`x^y` is transformed by the compiler to `Base.literal_pow(^, x, Val(y))`, to enable compile-time specialization on the value of the exponent. -(As a default fallback we have `Base.literal_pow(^, x, Val{y}) = ^(x,y)`, +(As a default fallback we have `Base.literal_pow(^, x, Val(y)) = ^(x,y)`, where usually `^ == Base.^` unless `^` has been defined in the calling namespace.) diff --git a/base/reshapedarray.jl b/base/reshapedarray.jl index a0faae35cea02..44b01c413d8c2 100644 --- a/base/reshapedarray.jl +++ b/base/reshapedarray.jl @@ -112,9 +112,9 @@ end @noinline _throw_reshape_colon_dimmismatch(A, dims) = throw(DimensionMismatch("array size $(length(A)) must be divisible by the product of the new dimensions $dims")) -reshape(parent::AbstractArray{T,N}, ndims::Type{Val{N}}) where {T,N} = parent -function reshape(parent::AbstractArray, ndims::Type{Val{N}}) where N - reshape(parent, rdims(Val{N}, indices(parent))) +reshape(parent::AbstractArray{T,N}, ndims::Val{N}) where {T,N} = parent +function reshape(parent::AbstractArray, ndims::Val{N}) where N + reshape(parent, rdims(Val(N), indices(parent))) end # Move elements from inds to out until out reaches the desired @@ -122,7 +122,7 @@ end # product of trailing dims into the last element rdims_trailing(l, inds...) = length(l) * rdims_trailing(inds...) rdims_trailing(l) = length(l) -rdims(out::Type{Val{N}}, inds::Tuple) where {N} = rdims(ntuple(i -> OneTo(1), Val{N}), inds) +rdims(out::Val{N}, inds::Tuple) where {N} = rdims(ntuple(i -> OneTo(1), Val(N)), inds) rdims(out::Tuple{}, inds::Tuple{}) = () # N == 0, M == 0 rdims(out::Tuple{}, inds::Tuple{Any}) = throw(ArgumentError("new dimensions cannot be empty")) # N == 0 rdims(out::Tuple{}, inds::NTuple{M,Any}) where {M} = throw(ArgumentError("new dimensions cannot be empty")) # N == 0 diff --git a/base/sparse/spqr.jl b/base/sparse/spqr.jl index c7a88f7a1ea7c..a507c8cdcbf22 100644 --- a/base/sparse/spqr.jl +++ b/base/sparse/spqr.jl @@ -137,7 +137,7 @@ function qmult(method::Integer, QR::Factorization{Tv}, X::Dense{Tv}) where Tv<:V end -qrfact(A::SparseMatrixCSC, ::Type{Val{true}}) = factorize(ORDERING_DEFAULT, DEFAULT_TOL, Sparse(A, 0)) +qrfact(A::SparseMatrixCSC, ::Val{true}) = factorize(ORDERING_DEFAULT, DEFAULT_TOL, Sparse(A, 0)) """ qrfact(A) -> SPQR.Factorization @@ -147,7 +147,7 @@ The main application of this type is to solve least squares problems with [`\\`] calls the C library SPQR and a few additional functions from the library are wrapped but not exported. """ -qrfact(A::SparseMatrixCSC) = qrfact(A, Val{true}) +qrfact(A::SparseMatrixCSC) = qrfact(A, Val(true)) # With a real lhs and complex rhs with the same precision, we can reinterpret # the complex rhs as a real rhs with twice the number of columns diff --git a/base/subarray.jl b/base/subarray.jl index 3a1b3ddf4d256..d9371201294b5 100644 --- a/base/subarray.jl +++ b/base/subarray.jl @@ -73,10 +73,10 @@ parentindexes(a::AbstractArray) = ntuple(i->OneTo(size(a,i)), ndims(a)) # indices that end up getting passed to it, so we store the parent as a # ReshapedArray view if necessary. The trouble is that arrays of `CartesianIndex` # can make the number of effective indices not equal to length(I). -_maybe_reshape_parent(A::AbstractArray, ::NTuple{1, Bool}) = reshape(A, Val{1}) -_maybe_reshape_parent(A::AbstractArray{<:Any,1}, ::NTuple{1, Bool}) = reshape(A, Val{1}) +_maybe_reshape_parent(A::AbstractArray, ::NTuple{1, Bool}) = reshape(A, Val(1)) +_maybe_reshape_parent(A::AbstractArray{<:Any,1}, ::NTuple{1, Bool}) = reshape(A, Val(1)) _maybe_reshape_parent(A::AbstractArray{<:Any,N}, ::NTuple{N, Bool}) where {N} = A -_maybe_reshape_parent(A::AbstractArray, ::NTuple{N, Bool}) where {N} = reshape(A, Val{N}) # TODO: DEPRECATE FOR #14770 +_maybe_reshape_parent(A::AbstractArray, ::NTuple{N, Bool}) where {N} = reshape(A, Val(N)) # TODO: DEPRECATE FOR #14770 """ view(A, inds...) @@ -238,7 +238,7 @@ substrides(s, parent, dim, I::Tuple{Any, Vararg{Any}}) = throw(ArgumentError("st stride(V::SubArray, d::Integer) = d <= ndims(V) ? strides(V)[d] : strides(V)[end] * size(V)[end] compute_stride1(parent::AbstractArray, I::NTuple{N,Any}) where {N} = - (@_inline_meta; compute_stride1(1, fill_to_length(indices(parent), OneTo(1), Val{N}), I)) + (@_inline_meta; compute_stride1(1, fill_to_length(indices(parent), OneTo(1), Val(N)), I)) compute_stride1(s, inds, I::Tuple{}) = s compute_stride1(s, inds, I::Tuple{ScalarIndex, Vararg{Any}}) = (@_inline_meta; compute_stride1(s*unsafe_length(inds[1]), tail(inds), tail(I))) @@ -272,7 +272,7 @@ compute_offset1(parent, stride1::Integer, dims, inds, I::Tuple) = function compute_linindex(parent, I::NTuple{N,Any}) where N @_inline_meta - IP = fill_to_length(indices(parent), OneTo(1), Val{N}) + IP = fill_to_length(indices(parent), OneTo(1), Val(N)) compute_linindex(1, 1, IP, I) end function compute_linindex(f, s, IP::Tuple, I::Tuple{ScalarIndex, Vararg{Any}}) diff --git a/base/sysimg.jl b/base/sysimg.jl index 3bd151ca209b4..aaad45cc63727 100644 --- a/base/sysimg.jl +++ b/base/sysimg.jl @@ -220,7 +220,7 @@ include("broadcast.jl") importall .Broadcast # define the real ntuple functions -@generated function ntuple(f::F, ::Type{Val{N}}) where {F,N} +@generated function ntuple(f::F, ::Val{N}) where {F,N} Core.typeassert(N, Int) (N >= 0) || return :(throw($(ArgumentError(string("tuple length should be ≥0, got ", N))))) return quote @@ -229,7 +229,7 @@ importall .Broadcast @ncall $N tuple t end end -@generated function fill_to_length(t::Tuple, val, ::Type{Val{N}}) where {N} +@generated function fill_to_length(t::Tuple, val, ::Val{N}) where {N} M = length(t.parameters) M > N && return :(throw($(ArgumentError("input tuple of length $M, requested $N")))) return quote diff --git a/base/tuple.jl b/base/tuple.jl index f78502525a839..eb035a1e882c7 100644 --- a/base/tuple.jl +++ b/base/tuple.jl @@ -128,10 +128,10 @@ function _ntuple(f, n) end # inferrable ntuple (enough for bootstrapping) -ntuple(f, ::Type{Val{0}}) = () -ntuple(f, ::Type{Val{1}}) = (@_inline_meta; (f(1),)) -ntuple(f, ::Type{Val{2}}) = (@_inline_meta; (f(1), f(2))) -ntuple(f, ::Type{Val{3}}) = (@_inline_meta; (f(1), f(2), f(3))) +ntuple(f, ::Val{0}) = () +ntuple(f, ::Val{1}) = (@_inline_meta; (f(1),)) +ntuple(f, ::Val{2}) = (@_inline_meta; (f(1), f(2))) +ntuple(f, ::Val{3}) = (@_inline_meta; (f(1), f(2), f(3))) # 1 argument function map(f, t::Tuple{}) = () @@ -187,11 +187,11 @@ end # type-stable padding -fill_to_length(t::NTuple{N,Any}, val, ::Type{Val{N}}) where {N} = t -fill_to_length(t::Tuple{}, val, ::Type{Val{1}}) = (val,) -fill_to_length(t::Tuple{Any}, val, ::Type{Val{2}}) = (t..., val) -fill_to_length(t::Tuple{}, val, ::Type{Val{2}}) = (val, val) -#function fill_to_length(t::Tuple, val, ::Type{Val{N}}) where {N} +fill_to_length(t::NTuple{N,Any}, val, ::Val{N}) where {N} = t +fill_to_length(t::Tuple{}, val, ::Val{1}) = (val,) +fill_to_length(t::Tuple{Any}, val, ::Val{2}) = (t..., val) +fill_to_length(t::Tuple{}, val, ::Val{2}) = (val, val) +#function fill_to_length(t::Tuple, val, ::Val{N}) where {N} # @_inline_meta # return (t..., ntuple(i -> val, N - length(t))...) #end diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 03821caa2abba..52cf9fd004375 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -2143,7 +2143,7 @@ ((and (eq? f '^) (length= e 4) (integer? (cadddr e))) (expand-forms - `(call (top literal_pow) ^ ,(caddr e) (call (core apply_type) (top Val) ,(cadddr e))))) + `(call (top literal_pow) ^ ,(caddr e) (call (call (core apply_type) (top Val) ,(cadddr e)))))) ((and (eq? f '*) (length= e 4)) (expand-transposed-op diff --git a/src/rtutils.c b/src/rtutils.c index f6a1e4cb68083..6320cbf19e9fe 100644 --- a/src/rtutils.c +++ b/src/rtutils.c @@ -1018,7 +1018,7 @@ void jl_depwarn_partial_indexing(size_t n) } if (!depwarn_func) { jl_safe_printf("WARNING: Partial linear indexing is deprecated. Use " - "`reshape(A, Val{%zd})` to make the dimensionality of the array match " + "`reshape(A, Val(%zd))` to make the dimensionality of the array match " "the number of indices\n", n); return; } diff --git a/test/abstractarray.jl b/test/abstractarray.jl index 24a181a58b76b..616528dd3bd9b 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -341,7 +341,7 @@ function test_scalar_indexing{T}(::Type{T}, shape, ::Type{TestAbstractArray}) @test C == B == A C = T(Int, shape) i=0 - C2 = reshape(C, Val{2}) + C2 = reshape(C, Val(2)) for i2 = 1:size(C2, 2) for i1 = 1:size(C2, 1) i += 1 @@ -351,7 +351,7 @@ function test_scalar_indexing{T}(::Type{T}, shape, ::Type{TestAbstractArray}) @test C == B == A C = T(Int, shape) i=0 - C3 = reshape(C, Val{3}) + C3 = reshape(C, Val(3)) for i3 = 1:size(C3, 3) for i2 = 1:size(C3, 2) for i1 = 1:size(C3, 1) diff --git a/test/arrayops.jl b/test/arrayops.jl index 5aa2c59c093ac..90e377fa0124f 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -130,12 +130,12 @@ end @test length(reshape(s, length(s))) == 0 end end -@testset "reshape(a, Val{N})" begin +@testset "reshape(a, Val(N))" begin a = ones(Int,3,3) s = view(a, 1:2, 1:2) for N in (1,3) - @test isa(reshape(a, Val{N}), Array{Int,N}) - @test isa(reshape(s, Val{N}), Base.ReshapedArray{Int,N}) + @test isa(reshape(a, Val(N)), Array{Int,N}) + @test isa(reshape(s, Val(N)), Base.ReshapedArray{Int,N}) end end @testset "reshape with colon" begin @@ -224,7 +224,7 @@ end @test A[2:6] == [2:6;] @test A[1:3,2,2:4] == cat(2,46:48,86:88,126:128) @test A[:,7:-3:1,5] == [191 176 161; 192 177 162; 193 178 163; 194 179 164; 195 180 165] - @test reshape(A, Val{2})[:,3:9] == reshape(11:45,5,7) + @test reshape(A, Val(2))[:,3:9] == reshape(11:45,5,7) rng = (2,2:3,2:2:5) tmp = zeros(Int,map(maximum,rng)...) tmp[rng...] = A[rng...] @@ -258,7 +258,7 @@ end B[4,[2,3]] = 7 @test B == [0 23 1 24 0; 11 12 13 14 15; 0 21 3 22 0; 0 7 7 0 0] - @test isequal(reshape(reshape(1:27, 3, 3, 3), Val{2})[1,:], [1, 4, 7, 10, 13, 16, 19, 22, 25]) + @test isequal(reshape(reshape(1:27, 3, 3, 3), Val(2))[1,:], [1, 4, 7, 10, 13, 16, 19, 22, 25]) a = [3, 5, -7, 6] b = [4, 6, 2, -7, 1] @@ -1474,11 +1474,11 @@ end @test a[:, [CartesianIndex()], :, :] == (@view a[:, [CartesianIndex()], :, :]) == reshape(a, 3, 1, 4, 5) @test a[:, :, [CartesianIndex()], :] == (@view a[:, :, [CartesianIndex()], :]) == reshape(a, 3, 4, 1, 5) @test a[:, :, :, [CartesianIndex()]] == (@view a[:, :, :, [CartesianIndex()]]) == reshape(a, 3, 4, 5, 1) - a2 = reshape(a, Val{2}) + a2 = reshape(a, Val(2)) @test a2[[CartesianIndex()], :, :] == (@view a2[[CartesianIndex()], :, :]) == reshape(a, 1, 3, 20) @test a2[:, [CartesianIndex()], :] == (@view a2[:, [CartesianIndex()], :]) == reshape(a, 3, 1, 20) @test a2[:, :, [CartesianIndex()]] == (@view a2[:, :, [CartesianIndex()]]) == reshape(a, 3, 20, 1) - a1 = reshape(a, Val{1}) + a1 = reshape(a, Val(1)) @test a1[[CartesianIndex()], :] == (@view a1[[CartesianIndex()], :]) == reshape(a, 1, 60) @test a1[:, [CartesianIndex()]] == (@view a1[:, [CartesianIndex()]]) == reshape(a, 60, 1) diff --git a/test/bitarray.jl b/test/bitarray.jl index 4babea7771545..3e6a480c5a981 100644 --- a/test/bitarray.jl +++ b/test/bitarray.jl @@ -140,9 +140,9 @@ timesofar("conversions") @check_bit_operation reshape(b1, (n2,n1)) BitMatrix @test_throws DimensionMismatch reshape(b1, (1,n1)) - @test @inferred(reshape(b1, n1*n2)) == @inferred(reshape(b1, (n1*n2,))) == @inferred(reshape(b1, Val{1})) == @inferred(reshape(b1, :)) - @test @inferred(reshape(b1, n1, n2)) === @inferred(reshape(b1, Val{2})) === b1 - @test @inferred(reshape(b1, n2, :)) == @inferred(reshape(b1, (n2, n1))) != @inferred(reshape(b1, Val{2})) + @test @inferred(reshape(b1, n1*n2)) == @inferred(reshape(b1, (n1*n2,))) == @inferred(reshape(b1, Val(1))) == @inferred(reshape(b1, :)) + @test @inferred(reshape(b1, n1, n2)) === @inferred(reshape(b1, Val(2))) === b1 + @test @inferred(reshape(b1, n2, :)) == @inferred(reshape(b1, (n2, n1))) != @inferred(reshape(b1, Val(2))) b1 = bitrand(s1, s2, s3, s4) @check_bit_operation reshape(b1, (s3,s1,s2,s4)) BitArray{4} diff --git a/test/core.jl b/test/core.jl index a1df02b58b57d..d0a022a2adffd 100644 --- a/test/core.jl +++ b/test/core.jl @@ -660,14 +660,14 @@ let @test ===(g(a),a) end -# dispatch using Val{T}. See discussion in #9452 for instances vs types +# dispatch using Val{T}. See discussion in #9452, #22475 for instances vs types let local firstlast - firstlast(::Type{Val{true}}) = "First" - firstlast(::Type{Val{false}}) = "Last" + firstlast(::Val{true}) = "First" + firstlast(::Val{false}) = "Last" - @test firstlast(Val{true}) == "First" - @test firstlast(Val{false}) == "Last" + @test firstlast(Val(true)) == "First" + @test firstlast(Val(false)) == "Last" end # x::Vararg{Any} declarations diff --git a/test/dimensionful.jl b/test/dimensionful.jl index d55defc19e159..2fde8c7f2ae0d 100644 --- a/test/dimensionful.jl +++ b/test/dimensionful.jl @@ -57,7 +57,7 @@ for op in (:(==), :(!=), :<, :<=, :isless, :isequal) end # generated functions to allow type inference of the value of the exponent: for (f,op) in ((:_plus,:+),(:_minus,:-),(:_times,:*),(:_div,://)) - @eval @generated function $f{T,p,q}(v::T, ::Furlong{p}, ::Union{Furlong{q},Type{Val{q}}}) + @eval @generated function $f{T,p,q}(v::T, ::Furlong{p}, ::Union{Furlong{q},Val{q}}) s = $op(p, q) :(Furlong{$(canonical_p(s)),$T}(v)) end @@ -76,4 +76,4 @@ for op in (:rem, :mod) $op{p}(x::Furlong{p}, y::Number) = Furlong{p}($op(x.val, y)) end end -Base.sqrt(x::Furlong) = _div(sqrt(x.val), x, Val{2}) +Base.sqrt(x::Furlong) = _div(sqrt(x.val), x, Val(2)) diff --git a/test/inference.jl b/test/inference.jl index 94f71bea76c08..c0b10a6c7ac68 100644 --- a/test/inference.jl +++ b/test/inference.jl @@ -924,8 +924,8 @@ end # demonstrate that inference must converge # while doing constant propagation Base.@pure plus1(x) = x + 1 -f21933(x::Val{T}) where {T} = f(Val{plus1(T)}()) -@code_typed f21933(Val{1}()) +f21933(x::Val{T}) where {T} = f(Val(plus1(T))) +@code_typed f21933(Val(1)) Base.return_types(f21933, (Val{1},)) function count_specializations(method::Method) diff --git a/test/linalg/cholesky.jl b/test/linalg/cholesky.jl index dce15ce0d776c..a90fe73b80e88 100644 --- a/test/linalg/cholesky.jl +++ b/test/linalg/cholesky.jl @@ -133,9 +133,9 @@ using Base.LinAlg: BlasComplex, BlasFloat, BlasReal, QRPivoted, PosDefException #pivoted upper Cholesky if eltya != BigFloat - cz = cholfact(Hermitian(zeros(eltya,n,n)), Val{true}) + cz = cholfact(Hermitian(zeros(eltya,n,n)), Val(true)) @test_throws Base.LinAlg.RankDeficientException Base.LinAlg.chkfullrank(cz) - cpapd = cholfact(apdh, Val{true}) + cpapd = cholfact(apdh, Val(true)) @test rank(cpapd) == n @test all(diff(diag(real(cpapd.factors))).<=0.) # diagonal should be non-increasing if isreal(apd) @@ -176,11 +176,11 @@ using Base.LinAlg: BlasComplex, BlasFloat, BlasReal, QRPivoted, PosDefException if eltya != BigFloat && eltyb != BigFloat # Note! Need to implement pivoted Cholesky decomposition in julia - cpapd = cholfact(apdh, Val{true}) + cpapd = cholfact(apdh, Val(true)) @test norm(apd * (cpapd\b) - b)/norm(b) <= ε*κ*n # Ad hoc, revisit @test norm(apd * (cpapd\b[1:n]) - b[1:n])/norm(b[1:n]) <= ε*κ*n - lpapd = cholfact(apdhL, Val{true}) + lpapd = cholfact(apdhL, Val(true)) @test norm(apd * (lpapd\b) - b)/norm(b) <= ε*κ*n # Ad hoc, revisit @test norm(apd * (lpapd\b[1:n]) - b[1:n])/norm(b[1:n]) <= ε*κ*n @@ -252,7 +252,7 @@ end 0.25336108035924787 + 0.975317836492159im 0.0628393808469436 - 0.1253397353973715im 0.11192755545114 - 0.1603741874112385im 0.8439562576196216 + 1.0850814110398734im -1.0568488936791578 - 0.06025820467086475im 0.12696236014017806 - 0.09853584666755086im] - cholfact(Hermitian(apd, :L), Val{true}) \ b + cholfact(Hermitian(apd, :L), Val(true)) \ b r = factorize(apd)[:U] E = abs.(apd - r'*r) ε = eps(abs(float(one(Complex64)))) @@ -274,7 +274,7 @@ end end @testset "fail for non-BLAS element types" begin - @test_throws ArgumentError cholfact!(Hermitian(rand(Float16, 5,5)), Val{true}) + @test_throws ArgumentError cholfact!(Hermitian(rand(Float16, 5,5)), Val(true)) end @testset "throw for non positive definite matrix" begin diff --git a/test/linalg/diagonal.jl b/test/linalg/diagonal.jl index 93eee20640f3f..64c6de02af80b 100644 --- a/test/linalg/diagonal.jl +++ b/test/linalg/diagonal.jl @@ -344,7 +344,7 @@ end D = Diagonal(randn(5)) Q = qrfact(randn(5, 5))[:Q] @test D * Q' == Array(D) * Q' - Q = qrfact(randn(5, 5), Val{true})[:Q] + Q = qrfact(randn(5, 5), Val(true))[:Q] @test_throws MethodError A_mul_B!(Q, D) end diff --git a/test/linalg/generic.jl b/test/linalg/generic.jl index a05ed80f01703..6089f1324e024 100644 --- a/test/linalg/generic.jl +++ b/test/linalg/generic.jl @@ -335,13 +335,13 @@ Base.transpose(a::ModInt{n}) where {n} = a # see Issue 20978 A = [ModInt{2}(1) ModInt{2}(0); ModInt{2}(1) ModInt{2}(1)] b = [ModInt{2}(1), ModInt{2}(0)] -@test A*(lufact(A, Val{false})\b) == b +@test A*(lufact(A, Val(false))\b) == b # Needed for pivoting: Base.abs(a::ModInt{n}) where {n} = a Base.:<(a::ModInt{n}, b::ModInt{n}) where {n} = a.k < b.k -@test A*(lufact(A, Val{true})\b) == b +@test A*(lufact(A, Val(true))\b) == b # test that the fallback throws properly for AbstractArrays with dimension > 2 @test_throws ErrorException ctranspose(rand(2,2,2,2)) diff --git a/test/linalg/qr.jl b/test/linalg/qr.jl index 2de9f65fa774c..84fe7462aaa01 100644 --- a/test/linalg/qr.jl +++ b/test/linalg/qr.jl @@ -65,8 +65,8 @@ debug && println("QR decomposition (without pivoting)") @test sprint(show,qra) == "$(typeof(qra)) with factors Q and R:\n$qstring\n$rstring" debug && println("Thin QR decomposition (without pivoting)") - qra = @inferred qrfact(a[:,1:n1], Val{false}) - @inferred qr(a[:,1:n1], Val{false}) + qra = @inferred qrfact(a[:,1:n1], Val(false)) + @inferred qr(a[:,1:n1], Val(false)) q,r = qra[:Q], qra[:R] @test_throws KeyError qra[:Z] @test q'*full(q, thin=false) ≈ eye(n) @@ -82,8 +82,8 @@ debug && println("Thin QR decomposition (without pivoting)") end debug && println("(Automatic) Fat (pivoted) QR decomposition") - @inferred qrfact(a, Val{true}) - @inferred qr(a, Val{true}) + @inferred qrfact(a, Val(true)) + @inferred qr(a, Val(true)) qrpa = factorize(a[1:n1,:]) q,r = qrpa[:Q], qrpa[:R] @@ -134,7 +134,7 @@ debug && println("Matmul with QR factorizations") @test_throws DimensionMismatch Base.LinAlg.A_mul_B!(q,zeros(eltya,n1+1)) @test_throws DimensionMismatch Base.LinAlg.Ac_mul_B!(q,zeros(eltya,n1+1)) - qra = qrfact(a[:,1:n1], Val{false}) + qra = qrfact(a[:,1:n1], Val(false)) q, r = qra[:Q], qra[:R] @test A_mul_B!(full(q, thin=false)',q) ≈ eye(n) @test_throws DimensionMismatch A_mul_B!(eye(eltya,n+1),q) @@ -149,8 +149,8 @@ end # Because transpose(x) == x @test_throws ErrorException transpose(qrfact(randn(3,3))) @test_throws ErrorException ctranspose(qrfact(randn(3,3))) -@test_throws ErrorException transpose(qrfact(randn(3,3), Val{false})) -@test_throws ErrorException ctranspose(qrfact(randn(3,3), Val{false})) +@test_throws ErrorException transpose(qrfact(randn(3,3), Val(false))) +@test_throws ErrorException ctranspose(qrfact(randn(3,3), Val(false))) @test_throws ErrorException transpose(qrfact(big.(randn(3,3)))) @test_throws ErrorException ctranspose(qrfact(big.(randn(3,3)))) diff --git a/test/linalg/special.jl b/test/linalg/special.jl index 2301ce9cdc22d..fb7896a6c2dd0 100644 --- a/test/linalg/special.jl +++ b/test/linalg/special.jl @@ -117,10 +117,10 @@ for typ in [UpperTriangular,LowerTriangular,Base.LinAlg.UnitUpperTriangular,Base a = rand(n,n) atri = typ(a) b = rand(n,n) - qrb = qrfact(b,Val{true}) + qrb = qrfact(b,Val(true)) @test Base.LinAlg.A_mul_Bc(atri,qrb[:Q]) ≈ full(atri) * qrb[:Q]' @test Base.LinAlg.A_mul_Bc!(copy(atri),qrb[:Q]) ≈ full(atri) * qrb[:Q]' - qrb = qrfact(b,Val{false}) + qrb = qrfact(b,Val(false)) @test Base.LinAlg.A_mul_Bc(atri,qrb[:Q]) ≈ full(atri) * qrb[:Q]' @test Base.LinAlg.A_mul_Bc!(copy(atri),qrb[:Q]) ≈ full(atri) * qrb[:Q]' end diff --git a/test/numbers.jl b/test/numbers.jl index 2015e5bf61fe3..e99aa5be4006c 100644 --- a/test/numbers.jl +++ b/test/numbers.jl @@ -2916,7 +2916,7 @@ struct PR20889; x; end ^(::PR20530, p::Int) = 1 ^(t::PR20889, b) = t.x + b ^(t::PR20889, b::Integer) = t.x + b -Base.literal_pow{p}(::typeof(^), ::PR20530, ::Type{Val{p}}) = 2 +Base.literal_pow{p}(::typeof(^), ::PR20530, ::Val{p}) = 2 @testset "literal powers" begin x = PR20530() p = 2 diff --git a/test/reflection.jl b/test/reflection.jl index 5a85bb31c729f..fee79bd8b545d 100644 --- a/test/reflection.jl +++ b/test/reflection.jl @@ -501,9 +501,9 @@ fLargeTable() = 4 @test length(methods(fLargeTable, Tuple{})) == 1 @test fLargeTable(1im, 2im) == 4 @test fLargeTable(1.0im, 2.0im) == 5 -@test_throws MethodError fLargeTable(Val{1}(), Val{1}()) -@test fLargeTable(Val{1}(), 1) == 1 -@test fLargeTable(1, Val{1}()) == 2 +@test_throws MethodError fLargeTable(Val(1), Val(1)) +@test fLargeTable(Val(1), 1) == 1 +@test fLargeTable(1, Val(1)) == 2 # issue #15280 function f15280(x) end diff --git a/test/subarray.jl b/test/subarray.jl index fb2d8d8300017..36d60f5f3452e 100644 --- a/test/subarray.jl +++ b/test/subarray.jl @@ -47,7 +47,7 @@ ensure_iterable(t::Tuple{Union{Number, CartesianIndex}, Vararg{Any}}) = ((t[1],) ensure_iterable(t::Tuple{Any, Vararg{Any}}) = (t[1], ensure_iterable(Base.tail(t))...) index_ndims(t::Tuple) = tup2val(Base.index_ndims(t)) -tup2val{N}(::NTuple{N}) = Val{N} +tup2val{N}(::NTuple{N}) = Val(N) # To avoid getting confused by manipulations that are implemented for SubArrays, # it's good to copy the contents to an Array. This version protects against diff --git a/test/tuple.jl b/test/tuple.jl index 925cb9dfa0357..1497cab5e6c40 100644 --- a/test/tuple.jl +++ b/test/tuple.jl @@ -104,8 +104,8 @@ end @testset "fill to length" begin ## filling to specified length - @test @inferred(Base.fill_to_length((1,2,3), -1, Val{5})) == (1,2,3,-1,-1) - @test_throws ArgumentError Base.fill_to_length((1,2,3), -1, Val{2}) + @test @inferred(Base.fill_to_length((1,2,3), -1, Val(5))) == (1,2,3,-1,-1) + @test_throws ArgumentError Base.fill_to_length((1,2,3), -1, Val(2)) end @testset "iterating" begin @@ -239,17 +239,17 @@ end end @testset "ntuple" begin - @test @inferred(ntuple(abs2, Val{0})) == () - @test @inferred(ntuple(abs2, Val{2})) == (1, 4) - @test @inferred(ntuple(abs2, Val{3})) == (1, 4, 9) - @test @inferred(ntuple(abs2, Val{4})) == (1, 4, 9, 16) - @test @inferred(ntuple(abs2, Val{5})) == (1, 4, 9, 16, 25) - @test @inferred(ntuple(abs2, Val{6})) == (1, 4, 9, 16, 25, 36) + @test @inferred(ntuple(abs2, Val(0))) == () + @test @inferred(ntuple(abs2, Val(2))) == (1, 4) + @test @inferred(ntuple(abs2, Val(3))) == (1, 4, 9) + @test @inferred(ntuple(abs2, Val(4))) == (1, 4, 9, 16) + @test @inferred(ntuple(abs2, Val(5))) == (1, 4, 9, 16, 25) + @test @inferred(ntuple(abs2, Val(6))) == (1, 4, 9, 16, 25, 36) # issue #21697 - @test_throws ArgumentError ntuple(abs2, Val{-1}) + @test_throws ArgumentError ntuple(abs2, Val(-1)) # issue #12854 - @test_throws TypeError ntuple(identity, Val{1:2}) + @test_throws TypeError ntuple(identity, Val(1:2)) for n = 0:20 t = ntuple(identity, n) @@ -263,7 +263,7 @@ end # PR #21446 for n = 0:15 - @test ntuple(identity, Val{n}) == ntuple(identity, n) + @test ntuple(identity, Val(n)) == ntuple(identity, n) end end From 2be13f3dee9c8c34fdce781f76f4a9b5134bf89e Mon Sep 17 00:00:00 2001 From: Andy Ferris Date: Wed, 5 Jul 2017 22:02:02 +1000 Subject: [PATCH 2/2] Update manual for Val(x) instance usage --- doc/src/manual/performance-tips.md | 27 ++++++++++++++------------- doc/src/manual/types.md | 23 ++++++++++++----------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/doc/src/manual/performance-tips.md b/doc/src/manual/performance-tips.md index 7eec3d59137b8..5d2b45ac58ff3 100644 --- a/doc/src/manual/performance-tips.md +++ b/doc/src/manual/performance-tips.md @@ -645,7 +645,7 @@ loaded from an input file that might contain either integers, floats, strings, o ## Types with values-as-parameters -Let's say you want to create an `N`-dimensional array that has size 3 along each axis. Such arrays +Let's say you want to create an `N`-dimensional array that has size 3 along each axis. Such arrays can be created like this: ```jldoctest @@ -685,37 +685,37 @@ slow. Now, one very good way to solve such problems is by using the [function-barrier technique](@ref kernal-functions). However, in some cases you might want to eliminate the type-instability altogether. In such cases, -one approach is to pass the dimensionality as a parameter, for example through `Val{T}` (see +one approach is to pass the dimensionality as a parameter, for example through `Val{T}()` (see ["Value types"](@ref)): ```jldoctest -julia> function array3(fillval, ::Type{Val{N}}) where N - fill(fillval, ntuple(d->3, Val{N})) +julia> function array3(fillval, ::Val{N}) where N + fill(fillval, ntuple(d->3, Val(N))) end array3 (generic function with 1 method) -julia> array3(5.0, Val{2}) +julia> array3(5.0, Val(2)) 3×3 Array{Float64,2}: 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.0 ``` -Julia has a specialized version of `ntuple` that accepts a `Val{::Int}` as the second parameter; -by passing `N` as a type-parameter, you make its "value" known to the compiler. Consequently, -this version of `array3` allows the compiler to predict the return type. +Julia has a specialized version of `ntuple` that accepts a `Val{::Int}` instance as the second +parameter; by passing `N` as a type-parameter, you make its "value" known to the compiler. +Consequently, this version of `array3` allows the compiler to predict the return type. However, making use of such techniques can be surprisingly subtle. For example, it would be of no help if you called `array3` from a function like this: ```julia function call_array3(fillval, n) - A = array3(fillval, Val{n}) + A = array3(fillval, Val(n)) end ``` -Here, you've created the same problem all over again: the compiler can't guess the type of `n`, -so it doesn't know the type of `Val{n}`. Attempting to use `Val`, but doing so incorrectly, can +Here, you've created the same problem all over again: the compiler can't guess what `n` is, +so it doesn't know the *type* of `Val(n)`. Attempting to use `Val`, but doing so incorrectly, can easily make performance *worse* in many situations. (Only in situations where you're effectively combining `Val` with the function-barrier trick, to make the kernel function more efficient, should code like the above be used.) @@ -724,13 +724,14 @@ An example of correct usage of `Val` would be: ```julia function filter3(A::AbstractArray{T,N}) where {T,N} - kernel = array3(1, Val{N}) + kernel = array3(1, Val(N)) filter(A, kernel) end ``` In this example, `N` is passed as a parameter, so its "value" is known to the compiler. Essentially, -`Val{T}` works only when `T` is either hard-coded (`Val{3}`) or already specified in the type-domain. +`Val(T)` works only when `T` is either hard-coded/literal (`Val(3)`) or already specified in the +type-domain. ## The dangers of abusing multiple dispatch (aka, more on types with values-as-parameters) diff --git a/doc/src/manual/types.md b/doc/src/manual/types.md index 281070a7e8d77..bdc29c9f8b8db 100644 --- a/doc/src/manual/types.md +++ b/doc/src/manual/types.md @@ -1260,37 +1260,38 @@ floating-point numbers, tuples, etc.) as type parameters. A common example is t parameter in `Array{T,N}`, where `T` is a type (e.g., [`Float64`](@ref)) but `N` is just an `Int`. You can create your own custom types that take values as parameters, and use them to control dispatch -of custom types. By way of illustration of this idea, let's introduce a parametric type, `Val{T}`, -which serves as a customary way to exploit this technique for cases where you don't need a more -elaborate hierarchy. +of custom types. By way of illustration of this idea, let's introduce a parametric type, `Val{x}`, +and a constructor `Val(x) = Val{x}()`, which serves as a customary way to exploit this technique +for cases where you don't need a more elaborate hierarchy. `Val` is defined as: ```jldoctest valtype -julia> struct Val{T} +julia> struct Val{x} end +Base.@pure Val(x) = Val{x}() ``` There is no more to the implementation of `Val` than this. Some functions in Julia's standard -library accept `Val` types as arguments, and you can also use it to write your own functions. +library accept `Val` instances as arguments, and you can also use it to write your own functions. For example: ```jldoctest valtype -julia> firstlast(::Type{Val{true}}) = "First" +julia> firstlast(::Val{true}) = "First" firstlast (generic function with 1 method) -julia> firstlast(::Type{Val{false}}) = "Last" +julia> firstlast(::Val{false}) = "Last" firstlast (generic function with 2 methods) -julia> firstlast(Val{true}) +julia> firstlast(Val(true)) "First" -julia> firstlast(Val{false}) +julia> firstlast(Val(false)) "Last" ``` -For consistency across Julia, the call site should always pass a `Val`*type* rather than creating -an *instance*, i.e., use `foo(Val{:bar})` rather than `foo(Val{:bar}())`. +For consistency across Julia, the call site should always pass a `Val`*instance* rather than using +a *type*, i.e., use `foo(Val(:bar))` rather than `foo(Val{:bar})`. It's worth noting that it's extremely easy to mis-use parametric "value" types, including `Val`; in unfavorable cases, you can easily end up making the performance of your code much *worse*.