From 77bf87cff8340574c12d63b921f3087ea30eca4c Mon Sep 17 00:00:00 2001 From: Jan Weidner Date: Tue, 23 Feb 2021 16:29:41 +0100 Subject: [PATCH 01/16] add Always --- base/exports.jl | 1 + base/operators.jl | 32 ++++++++++++++++++++++++++++++++ test/operators.jl | 10 ++++++++++ 3 files changed, 43 insertions(+) diff --git a/base/exports.jl b/base/exports.jl index 440b28fb155b2..c5f973fd889b7 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -21,6 +21,7 @@ export AbstractUnitRange, AbstractVector, AbstractVecOrMat, + Always, Array, AbstractMatch, AbstractPattern, diff --git a/base/operators.jl b/base/operators.jl index 6f5a8ea2a7762..0907b4eb0dd5e 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -915,6 +915,38 @@ julia> [1:5;] |> x->x.^2 |> sum |> inv """ |>(x, f) = f(x) +# always +""" + f = Always(value) + +Create a callable `f` such that `f(args...; kw...) === value` holds. + +# Examples + +```jldoctest +julia> f = Always(42); + +julia> f(1) +42 + +julia> f("hello", x=32) +42 +``` + +!!! compat "Julia 1.7" + Always requires at least Julia 1.7. +""" +struct Always{V} <: Function + value::V +end + +(obj::Always)(args...; kw...) = obj.value +function show(io::IO, obj::Always) + show(io, Always) + print(io, "(") + show(io, obj.value) + print(io, ")") +end # function composition """ diff --git a/test/operators.jl b/test/operators.jl index 7b7711037cfb7..d9194525a2bed 100644 --- a/test/operators.jl +++ b/test/operators.jl @@ -279,3 +279,13 @@ a = rand(3, 3) @test transpose(a) === a'ᵀ @test [Base.afoldl(+, 1:i...) for i = 1:40] == [i * (i + 1) ÷ 2 for i = 1:40] + +@testset "Always" begin + @test @inferred(Always(1)() ) === 1 + @test @inferred(Always(1)(23) ) === 1 + @test @inferred(Always("a")(2,3)) == "a" + @test @inferred(Always(1)(x=1, y=2)) === 1 + val = [1,2,3] + @test Always(val)(1) === val + @test sprint(show, Always(1)) == "Always(1)" +end From 9cf3efc29be0677568254cfa8314cf9c7059e62a Mon Sep 17 00:00:00 2001 From: Jan Weidner Date: Wed, 24 Feb 2021 09:11:29 +0100 Subject: [PATCH 02/16] use Always in some places --- base/abstractarray.jl | 4 ++-- base/dict.jl | 2 +- test/arrayops.jl | 18 +++++++++--------- test/iterators.jl | 6 +++--- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index afd550a08cba9..0814d82e5ba74 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -1810,7 +1810,7 @@ function hvcat(nbc::Integer, as...) mod(n,nbc) != 0 && throw(ArgumentError("number of arrays $n is not a multiple of the requested number of block columns $nbc")) nbr = div(n,nbc) - hvcat(ntuple(i->nbc, nbr), as...) + hvcat(ntuple(Always(nbc), nbr), as...) end """ @@ -2112,7 +2112,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(Always(similar(ind)),Val(N)) for (i,idx) in pairs(IndexLinear(), ind) sub = _ind2sub(inds, idx) for j = 1:N diff --git a/base/dict.jl b/base/dict.jl index cc5c9efb6ada8..1bd34d8c22274 100644 --- a/base/dict.jl +++ b/base/dict.jl @@ -797,7 +797,7 @@ function iterate(d::ImmutableDict{K,V}, t=d) where {K, V} !isdefined(t, :parent) && return nothing (Pair{K,V}(t.key, t.value), t.parent) end -length(t::ImmutableDict) = count(x->true, t) +length(t::ImmutableDict) = count(Always(true), t) isempty(t::ImmutableDict) = !isdefined(t, :parent) empty(::ImmutableDict, ::Type{K}, ::Type{V}) where {K, V} = ImmutableDict{K,V}() diff --git a/test/arrayops.jl b/test/arrayops.jl index 5a08a7334e132..d579eae52fb9d 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -1153,17 +1153,17 @@ end # issue #5177 c = fill(1,2,3,4) - m1 = mapslices(x-> fill(1,2,3), c, dims=[1,2]) - m2 = mapslices(x-> fill(1,2,4), c, dims=[1,3]) - m3 = mapslices(x-> fill(1,3,4), c, dims=[2,3]) + m1 = mapslices(Always(fill(1,2,3)), c, dims=[1,2]) + m2 = mapslices(Always(fill(1,2,4)), c, dims=[1,3]) + m3 = mapslices(Always(fill(1,3,4)), c, dims=[2,3]) @test size(m1) == size(m2) == size(m3) == size(c) - n1 = mapslices(x-> fill(1,6), c, dims=[1,2]) - n2 = mapslices(x-> fill(1,6), c, dims=[1,3]) - n3 = mapslices(x-> fill(1,6), c, dims=[2,3]) - n1a = mapslices(x-> fill(1,1,6), c, dims=[1,2]) - n2a = mapslices(x-> fill(1,1,6), c, dims=[1,3]) - n3a = mapslices(x-> fill(1,1,6), c, dims=[2,3]) + n1 = mapslices(Always(fill(1,6) ), c, dims=[1,2]) + n2 = mapslices(Always(fill(1,6) ), c, dims=[1,3]) + n3 = mapslices(Always(fill(1,6) ), c, dims=[2,3]) + n1a = mapslices(Always(fill(1,1,6)), c, dims=[1,2]) + n2a = mapslices(Always(fill(1,1,6)), c, dims=[1,3]) + n3a = mapslices(Always(fill(1,1,6)), c, dims=[2,3]) @test size(n1a) == (1,6,4) && size(n2a) == (1,3,6) && size(n3a) == (2,1,6) @test size(n1) == (6,1,4) && size(n2) == (6,3,1) && size(n3) == (2,6,1) diff --git a/test/iterators.jl b/test/iterators.jl index f4432c9d831cd..7a14a9ac7b2fe 100644 --- a/test/iterators.jl +++ b/test/iterators.jl @@ -198,7 +198,7 @@ end @test collect(takewhile(<(4),1:10)) == [1,2,3] @test collect(takewhile(<(4),Iterators.countfrom(1))) == [1,2,3] @test collect(takewhile(<(4),5:10)) == [] - @test collect(takewhile(_->true,5:10)) == 5:10 + @test collect(takewhile(Always(true),5:10)) == 5:10 @test collect(takewhile(isodd,[1,1,2,3])) == [1,1] @test collect(takewhile(<(2), takewhile(<(3), [1,1,2,3]))) == [1,1] end @@ -209,8 +209,8 @@ end @test collect(dropwhile(<(4), 1:10)) == 4:10 @test collect(dropwhile(<(4), 1:10)) isa Vector{Int} @test isempty(dropwhile(<(4), [])) - @test collect(dropwhile(_->false,1:3)) == 1:3 - @test isempty(dropwhile(_->true, 1:3)) + @test collect(dropwhile(Always(false),1:3)) == 1:3 + @test isempty(dropwhile(Always(true), 1:3)) @test collect(dropwhile(isodd,[1,1,2,3])) == [2,3] @test collect(dropwhile(iseven,dropwhile(isodd,[1,1,2,3]))) == [3] end From 115333bcbac5130f75df4297b360e0765f11f3d5 Mon Sep 17 00:00:00 2001 From: Jan Weidner Date: Sat, 27 Feb 2021 19:03:08 +0100 Subject: [PATCH 03/16] fix --- base/abstractarray.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 0814d82e5ba74..fdb285a7659fd 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -2112,7 +2112,7 @@ _sub2ind_vec(i) = () function _ind2sub(inds::Union{DimsInteger{N},Indices{N}}, ind::AbstractVector{<:Integer}) where N M = length(ind) - t = ntuple(Always(similar(ind)),Val(N)) + t = ntuple(n->similar(ind),Val(N)) for (i,idx) in pairs(IndexLinear(), ind) sub = _ind2sub(inds, idx) for j = 1:N From 2496bb0138e67f4cd821bc462271bc37a37878f7 Mon Sep 17 00:00:00 2001 From: Jan Weidner Date: Sat, 27 Feb 2021 19:17:41 +0100 Subject: [PATCH 04/16] rename Always to Returns --- base/abstractarray.jl | 2 +- base/dict.jl | 2 +- base/exports.jl | 2 +- base/operators.jl | 14 +++++++------- test/arrayops.jl | 18 +++++++++--------- test/iterators.jl | 6 +++--- test/operators.jl | 14 +++++++------- 7 files changed, 29 insertions(+), 29 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index fdb285a7659fd..cfaace3bab23e 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -1810,7 +1810,7 @@ function hvcat(nbc::Integer, as...) mod(n,nbc) != 0 && throw(ArgumentError("number of arrays $n is not a multiple of the requested number of block columns $nbc")) nbr = div(n,nbc) - hvcat(ntuple(Always(nbc), nbr), as...) + hvcat(ntuple(Returns(nbc), nbr), as...) end """ diff --git a/base/dict.jl b/base/dict.jl index 1bd34d8c22274..1c176a2eab864 100644 --- a/base/dict.jl +++ b/base/dict.jl @@ -797,7 +797,7 @@ function iterate(d::ImmutableDict{K,V}, t=d) where {K, V} !isdefined(t, :parent) && return nothing (Pair{K,V}(t.key, t.value), t.parent) end -length(t::ImmutableDict) = count(Always(true), t) +length(t::ImmutableDict) = count(Returns(true), t) isempty(t::ImmutableDict) = !isdefined(t, :parent) empty(::ImmutableDict, ::Type{K}, ::Type{V}) where {K, V} = ImmutableDict{K,V}() diff --git a/base/exports.jl b/base/exports.jl index c5f973fd889b7..3c3b74bc5a6dc 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -21,7 +21,6 @@ export AbstractUnitRange, AbstractVector, AbstractVecOrMat, - Always, Array, AbstractMatch, AbstractPattern, @@ -71,6 +70,7 @@ export Rational, Regex, RegexMatch, + Returns, RoundFromZero, RoundDown, RoundingMode, diff --git a/base/operators.jl b/base/operators.jl index 0907b4eb0dd5e..0afd96f301d9d 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -917,14 +917,14 @@ julia> [1:5;] |> x->x.^2 |> sum |> inv # always """ - f = Always(value) + f = Returns(value) Create a callable `f` such that `f(args...; kw...) === value` holds. # Examples ```jldoctest -julia> f = Always(42); +julia> f = Returns(42); julia> f(1) 42 @@ -934,15 +934,15 @@ julia> f("hello", x=32) ``` !!! compat "Julia 1.7" - Always requires at least Julia 1.7. + Returns requires at least Julia 1.7. """ -struct Always{V} <: Function +struct Returns{V} <: Function value::V end -(obj::Always)(args...; kw...) = obj.value -function show(io::IO, obj::Always) - show(io, Always) +(obj::Returns)(args...; kw...) = obj.value +function show(io::IO, obj::Returns) + show(io, Returns) print(io, "(") show(io, obj.value) print(io, ")") diff --git a/test/arrayops.jl b/test/arrayops.jl index d579eae52fb9d..e922e31509fd2 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -1153,17 +1153,17 @@ end # issue #5177 c = fill(1,2,3,4) - m1 = mapslices(Always(fill(1,2,3)), c, dims=[1,2]) - m2 = mapslices(Always(fill(1,2,4)), c, dims=[1,3]) - m3 = mapslices(Always(fill(1,3,4)), c, dims=[2,3]) + m1 = mapslices(Returns(fill(1,2,3)), c, dims=[1,2]) + m2 = mapslices(Returns(fill(1,2,4)), c, dims=[1,3]) + m3 = mapslices(Returns(fill(1,3,4)), c, dims=[2,3]) @test size(m1) == size(m2) == size(m3) == size(c) - n1 = mapslices(Always(fill(1,6) ), c, dims=[1,2]) - n2 = mapslices(Always(fill(1,6) ), c, dims=[1,3]) - n3 = mapslices(Always(fill(1,6) ), c, dims=[2,3]) - n1a = mapslices(Always(fill(1,1,6)), c, dims=[1,2]) - n2a = mapslices(Always(fill(1,1,6)), c, dims=[1,3]) - n3a = mapslices(Always(fill(1,1,6)), c, dims=[2,3]) + n1 = mapslices(Returns(fill(1,6) ), c, dims=[1,2]) + n2 = mapslices(Returns(fill(1,6) ), c, dims=[1,3]) + n3 = mapslices(Returns(fill(1,6) ), c, dims=[2,3]) + n1a = mapslices(Returns(fill(1,1,6)), c, dims=[1,2]) + n2a = mapslices(Returns(fill(1,1,6)), c, dims=[1,3]) + n3a = mapslices(Returns(fill(1,1,6)), c, dims=[2,3]) @test size(n1a) == (1,6,4) && size(n2a) == (1,3,6) && size(n3a) == (2,1,6) @test size(n1) == (6,1,4) && size(n2) == (6,3,1) && size(n3) == (2,6,1) diff --git a/test/iterators.jl b/test/iterators.jl index 7a14a9ac7b2fe..6229033f9933d 100644 --- a/test/iterators.jl +++ b/test/iterators.jl @@ -198,7 +198,7 @@ end @test collect(takewhile(<(4),1:10)) == [1,2,3] @test collect(takewhile(<(4),Iterators.countfrom(1))) == [1,2,3] @test collect(takewhile(<(4),5:10)) == [] - @test collect(takewhile(Always(true),5:10)) == 5:10 + @test collect(takewhile(Returns(true),5:10)) == 5:10 @test collect(takewhile(isodd,[1,1,2,3])) == [1,1] @test collect(takewhile(<(2), takewhile(<(3), [1,1,2,3]))) == [1,1] end @@ -209,8 +209,8 @@ end @test collect(dropwhile(<(4), 1:10)) == 4:10 @test collect(dropwhile(<(4), 1:10)) isa Vector{Int} @test isempty(dropwhile(<(4), [])) - @test collect(dropwhile(Always(false),1:3)) == 1:3 - @test isempty(dropwhile(Always(true), 1:3)) + @test collect(dropwhile(Returns(false),1:3)) == 1:3 + @test isempty(dropwhile(Returns(true), 1:3)) @test collect(dropwhile(isodd,[1,1,2,3])) == [2,3] @test collect(dropwhile(iseven,dropwhile(isodd,[1,1,2,3]))) == [3] end diff --git a/test/operators.jl b/test/operators.jl index d9194525a2bed..0e2b28c8b8e70 100644 --- a/test/operators.jl +++ b/test/operators.jl @@ -280,12 +280,12 @@ a = rand(3, 3) @test [Base.afoldl(+, 1:i...) for i = 1:40] == [i * (i + 1) ÷ 2 for i = 1:40] -@testset "Always" begin - @test @inferred(Always(1)() ) === 1 - @test @inferred(Always(1)(23) ) === 1 - @test @inferred(Always("a")(2,3)) == "a" - @test @inferred(Always(1)(x=1, y=2)) === 1 +@testset "Returns" begin + @test @inferred(Returns(1)() ) === 1 + @test @inferred(Returns(1)(23) ) === 1 + @test @inferred(Returns("a")(2,3)) == "a" + @test @inferred(Returns(1)(x=1, y=2)) === 1 val = [1,2,3] - @test Always(val)(1) === val - @test sprint(show, Always(1)) == "Always(1)" + @test Returns(val)(1) === val + @test sprint(show, Returns(1)) == "Returns(1)" end From d48bba001280197b43ed7d28809acb3c5ddc7b2c Mon Sep 17 00:00:00 2001 From: Jan Weidner Date: Sat, 27 Feb 2021 19:32:41 +0100 Subject: [PATCH 05/16] add more Returns tests, improve inference --- base/operators.jl | 2 ++ test/operators.jl | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/base/operators.jl b/base/operators.jl index 0afd96f301d9d..8de621530299d 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -938,6 +938,8 @@ julia> f("hello", x=32) """ struct Returns{V} <: Function value::V + Returns{V}(value) where {V} = new{V}(value) + Returns(value) = new{Core.Typeof(value)}(value) end (obj::Returns)(args...; kw...) = obj.value diff --git a/test/operators.jl b/test/operators.jl index 0e2b28c8b8e70..cec50d916ab7b 100644 --- a/test/operators.jl +++ b/test/operators.jl @@ -285,6 +285,10 @@ a = rand(3, 3) @test @inferred(Returns(1)(23) ) === 1 @test @inferred(Returns("a")(2,3)) == "a" @test @inferred(Returns(1)(x=1, y=2)) === 1 + @test @inferred(Returns(Int)()) === Int + @test @inferred(Returns(Returns(1))()) === Returns(1) + f = @inferred Returns(Int) + @inferred f(1,2) val = [1,2,3] @test Returns(val)(1) === val @test sprint(show, Returns(1)) == "Returns(1)" From e63045aa91967dddf5cf8d2b25dc511061aa09a2 Mon Sep 17 00:00:00 2001 From: Jan Weidner Date: Tue, 2 Mar 2021 05:55:57 +0100 Subject: [PATCH 06/16] Update base/operators.jl Co-authored-by: Jeff Bezanson --- base/operators.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/operators.jl b/base/operators.jl index 8de621530299d..4f1535017608f 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -944,7 +944,7 @@ end (obj::Returns)(args...; kw...) = obj.value function show(io::IO, obj::Returns) - show(io, Returns) + show(io, typeof(obj)) print(io, "(") show(io, obj.value) print(io, ")") From 1726aba097b24dd39f80f75b63a5c05aa51ae6ef Mon Sep 17 00:00:00 2001 From: Jan Weidner Date: Tue, 2 Mar 2021 08:08:11 +0100 Subject: [PATCH 07/16] add Returns to News.md --- NEWS.md | 1 + base/operators.jl | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 4f9c315659ae5..8eb44e21cf83d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -34,6 +34,7 @@ New library functions * `isunordered(x)` returns true if `x` is value that is normally unordered, such as `NaN` or `missing`. * New macro `Base.@invokelatest f(args...; kwargs...)` provides a convenient way to call `Base.invokelatest(f, args...; kwargs...)` ([#37971]) * New macro `Base.@invoke f(arg1::T1, arg2::T2; kwargs...)` provides an easier syntax to call `invoke(f, Tuple{T1,T2}; kwargs...)` ([#38438]) +* New function/type `Returns(value)` that creates a function, which returns `value` for any arguments ([ #39794]) New library features -------------------- diff --git a/base/operators.jl b/base/operators.jl index 4f1535017608f..eb315940bed5c 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -915,7 +915,6 @@ julia> [1:5;] |> x->x.^2 |> sum |> inv """ |>(x, f) = f(x) -# always """ f = Returns(value) @@ -931,6 +930,9 @@ julia> f(1) julia> f("hello", x=32) 42 + +julia> f.value +42 ``` !!! compat "Julia 1.7" From 5c15726e38d47a561018e08421703a89a5130da8 Mon Sep 17 00:00:00 2001 From: Jan Weidner Date: Tue, 2 Mar 2021 19:34:02 +0100 Subject: [PATCH 08/16] replace more lambdas by Returns --- base/abstractarray.jl | 6 +++--- base/abstractarraymath.jl | 8 ++++---- base/array.jl | 2 +- test/arrayops.jl | 2 +- test/cartesian.jl | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index cfaace3bab23e..7f6a66853b192 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -1604,7 +1604,7 @@ _cat_size_shape(dims, shape) = 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(Returns(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) = @@ -2238,9 +2238,9 @@ function mapslices(f, A::AbstractArray; dims) end nextra = max(0, length(dims)-ndims(r1)) if eltype(Rsize) == Int - Rsize[dims] = [size(r1)..., ntuple(d->1, nextra)...] + Rsize[dims] = [size(r1)..., ntuple(Returns(1), nextra)...] else - Rsize[dims] = [axes(r1)..., ntuple(d->OneTo(1), nextra)...] + Rsize[dims] = [axes(r1)..., ntuple(Returns(OneTo(1)), nextra)...] end R = similar(r1, tuple(Rsize...,)) diff --git a/base/abstractarraymath.jl b/base/abstractarraymath.jl index 953c190ab12ef..7e88baaa0d840 100644 --- a/base/abstractarraymath.jl +++ b/base/abstractarraymath.jl @@ -123,7 +123,7 @@ julia> selectdim(A, 2, 3) @noinline function _selectdim(A, d, i, idxs) d >= 1 || throw(ArgumentError("dimension must be ≥ 1, got $d")) nd = ndims(A) - d > nd && (i == 1 || throw(BoundsError(A, (ntuple(k->Colon(),d-1)..., i)))) + d > nd && (i == 1 || throw(BoundsError(A, (ntuple(Returns(Colon()),d-1)..., i)))) return view(A, idxs...) end @@ -225,7 +225,7 @@ function repeat(A::AbstractArray, counts...) end """ - repeat(A::AbstractArray; inner=ntuple(x->1, ndims(A)), outer=ntuple(x->1, ndims(A))) + repeat(A::AbstractArray; inner=ntuple(Returns(1), ndims(A)), outer=ntuple(Returns(1), ndims(A))) Construct an array by repeating the entries of `A`. The i-th element of `inner` specifies the number of times that the individual entries of the i-th dimension of `A` should be @@ -491,7 +491,7 @@ julia> collect(eachslice(M, dims=2)) length(dims) == 1 || throw(ArgumentError("only single dimensions are supported")) dim = first(dims) dim <= ndims(A) || throw(DimensionMismatch("A doesn't have $dim dimensions")) - inds_before = ntuple(d->(:), dim-1) - inds_after = ntuple(d->(:), ndims(A)-dim) + inds_before = ntuple(Returns(:), dim-1) + inds_after = ntuple(Returns(:), ndims(A)-dim) return (view(A, inds_before..., i, inds_after...) for i in axes(A, dim)) end diff --git a/base/array.jl b/base/array.jl index e680d035897be..afaa3b5f19d6b 100644 --- a/base/array.jl +++ b/base/array.jl @@ -1734,7 +1734,7 @@ function vcat(arrays::Vector{T}...) where T return arr end -_cat(n::Integer, x::Integer...) = reshape([x...], (ntuple(x->1, n-1)..., length(x))) +_cat(n::Integer, x::Integer...) = reshape([x...], (ntuple(Returns(1), n-1)..., length(x))) ## find ## diff --git a/test/arrayops.jl b/test/arrayops.jl index e922e31509fd2..44893fdd1a48b 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -1799,7 +1799,7 @@ end A = reshape(a, tuple(shp...)) @test mdsum(A) == 55 @test mdsum2(A) == 55 - B = view(A, ntuple(i->Colon(), i)...) + B = view(A, ntuple(Returns(:), i)...) @test mdsum(B) == 55 @test mdsum2(B) == 55 insert!(shp, 2, 1) diff --git a/test/cartesian.jl b/test/cartesian.jl index af0bc466e3d04..036c10883d451 100644 --- a/test/cartesian.jl +++ b/test/cartesian.jl @@ -407,5 +407,5 @@ end end # issue #39705 -f39705() = Base.Cartesian.@nany 0 _ -> true +f39705() = Base.Cartesian.@nany 0 Returns(true) @test f39705() === false From 26385878708ea9773bcaf6e918028869815eb442 Mon Sep 17 00:00:00 2001 From: Jan Weidner Date: Wed, 3 Mar 2021 08:59:17 +0100 Subject: [PATCH 09/16] replace more lambdas by Returns in base --- base/bitarray.jl | 2 +- base/env.jl | 2 +- base/expr.jl | 2 +- base/iterators.jl | 4 ++-- base/multidimensional.jl | 12 ++++++------ base/reshapedarray.jl | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/base/bitarray.jl b/base/bitarray.jl index 6175a492cac75..556166b6cad0b 100644 --- a/base/bitarray.jl +++ b/base/bitarray.jl @@ -482,7 +482,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}(undef, ntuple(i->0,Val(N))...) + Br = BitArray{N}(undef, ntuple(Returns(0),Val(N))...) Br.chunks = B.chunks Br.len = prod(dims) N != 1 && (Br.dims = dims) diff --git a/base/env.jl b/base/env.jl index 8f5256f25915e..b87d00670e772 100644 --- a/base/env.jl +++ b/base/env.jl @@ -77,7 +77,7 @@ variable may result in an uppercase `ENV` key.) const ENV = EnvDict() getindex(::EnvDict, k::AbstractString) = access_env(k->throw(KeyError(k)), k) -get(::EnvDict, k::AbstractString, def) = access_env(k->def, k) +get(::EnvDict, k::AbstractString, def) = access_env(Returns(def), k) get(f::Callable, ::EnvDict, k::AbstractString) = access_env(k->f(), k) in(k::AbstractString, ::KeySet{String, EnvDict}) = _hasenv(k) pop!(::EnvDict, k::AbstractString) = (v = ENV[k]; _unsetenv(k); v) diff --git a/base/expr.jl b/base/expr.jl index 38a1c4e7089cb..291b976f9eaa3 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -360,7 +360,7 @@ end findmeta(ex::Array{Any,1}) = findmeta_block(ex) -function findmeta_block(exargs, argsmatch=args->true) +function findmeta_block(exargs, argsmatch=Returns(true)) for i = 1:length(exargs) a = exargs[i] if isa(a, Expr) diff --git a/base/iterators.jl b/base/iterators.jl index eebffed16dcfb..6def14ff2046b 100644 --- a/base/iterators.jl +++ b/base/iterators.jl @@ -326,7 +326,7 @@ eltype(::Type{Zip{Is}}) where {Is<:Tuple} = Tuple{ntuple(n -> eltype(fieldtype(I #eltype(::Type{Zip{Tuple{}}}) = Tuple{} #eltype(::Type{Zip{Tuple{A}}}) where {A} = Tuple{eltype(A)} #eltype(::Type{Zip{Tuple{A, B}}}) where {A, B} = Tuple{eltype(A), eltype(B)} -@inline isdone(z::Zip) = _zip_any_isdone(z.is, Base.map(_ -> (), z.is)) +@inline isdone(z::Zip) = _zip_any_isdone(z.is, Base.map(Returns(()), z.is)) @inline isdone(z::Zip, ss) = _zip_any_isdone(z.is, Base.map(tuple, ss)) @inline function _zip_any_isdone(is, ss) d1 = isdone(is[1], ss[1]...) @@ -335,7 +335,7 @@ eltype(::Type{Zip{Is}}) where {Is<:Tuple} = Tuple{ntuple(n -> eltype(fieldtype(I end @inline _zip_any_isdone(::Tuple{}, ::Tuple{}) = false -@propagate_inbounds iterate(z::Zip) = _zip_iterate_all(z.is, Base.map(_ -> (), z.is)) +@propagate_inbounds iterate(z::Zip) = _zip_iterate_all(z.is, Base.map(Returns(()), z.is)) @propagate_inbounds iterate(z::Zip, ss) = _zip_iterate_all(z.is, Base.map(tuple, ss)) # This first queries isdone from every iterator. If any gives true, it immediately returns diff --git a/base/multidimensional.jl b/base/multidimensional.jl index 32d66c4c54cda..e32645c2fa915 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -104,9 +104,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(Returns(0), Val(N))) oneunit(::CartesianIndex{N}) where {N} = oneunit(CartesianIndex{N}) - oneunit(::Type{CartesianIndex{N}}) where {N} = CartesianIndex(ntuple(x -> 1, Val(N))) + oneunit(::Type{CartesianIndex{N}}) where {N} = CartesianIndex(ntuple(Returns(1), Val(N))) # arithmetic, min/max @inline (-)(index::CartesianIndex{N}) where {N} = @@ -457,7 +457,7 @@ module IteratorsMD # Split out the first N elements of a tuple @inline function split(t, V::Val) - ref = ntuple(d->true, V) # create a reference tuple of length N + ref = ntuple(Returns(true), V) # create a reference tuple of length N _split1(t, ref), _splitrest(t, ref) end @inline _split1(t, ref) = (t[1], _split1(tail(t), tail(ref))...) @@ -684,10 +684,10 @@ checkindex(::Type{Bool}, inds::Tuple, I::CartesianIndices) = all(checkindex.(Boo # rather than returning N, it returns an NTuple{N,Bool} so the result is inferrable @inline index_ndims(i1, I...) = (true, index_ndims(I...)...) @inline function index_ndims(i1::CartesianIndex, I...) - (map(x->true, i1.I)..., index_ndims(I...)...) + (map(Returns(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(Returns(true), Val(N))..., index_ndims(I...)...) end index_ndims() = () @@ -697,7 +697,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(Returns(true), Val(N))..., index_dimsum(I...)...) end index_dimsum() = () diff --git a/base/reshapedarray.jl b/base/reshapedarray.jl index d9a9f4eafaa80..671dd2d86a840 100644 --- a/base/reshapedarray.jl +++ b/base/reshapedarray.jl @@ -146,7 +146,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::Val{N}, inds::Tuple) where {N} = rdims(ntuple(i -> OneTo(1), Val(N)), inds) +rdims(out::Val{N}, inds::Tuple) where {N} = rdims(ntuple(Returns(OneTo(1)), Val(N)), inds) rdims(out::Tuple{}, inds::Tuple{}) = () # N == 0, M == 0 rdims(out::Tuple{}, inds::Tuple{Any}) = () rdims(out::Tuple{}, inds::NTuple{M,Any}) where {M} = () From acb0d2ea978aeb97f01ad8db4458e17e781fa781 Mon Sep 17 00:00:00 2001 From: Jan Weidner Date: Wed, 3 Mar 2021 10:10:07 +0100 Subject: [PATCH 10/16] revert some Returns that cause bootstrap issues --- base/bitarray.jl | 2 +- base/expr.jl | 2 +- base/iterators.jl | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/base/bitarray.jl b/base/bitarray.jl index 556166b6cad0b..6175a492cac75 100644 --- a/base/bitarray.jl +++ b/base/bitarray.jl @@ -482,7 +482,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}(undef, ntuple(Returns(0),Val(N))...) + Br = BitArray{N}(undef, ntuple(i->0,Val(N))...) Br.chunks = B.chunks Br.len = prod(dims) N != 1 && (Br.dims = dims) diff --git a/base/expr.jl b/base/expr.jl index 291b976f9eaa3..38a1c4e7089cb 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -360,7 +360,7 @@ end findmeta(ex::Array{Any,1}) = findmeta_block(ex) -function findmeta_block(exargs, argsmatch=Returns(true)) +function findmeta_block(exargs, argsmatch=args->true) for i = 1:length(exargs) a = exargs[i] if isa(a, Expr) diff --git a/base/iterators.jl b/base/iterators.jl index 6def14ff2046b..eebffed16dcfb 100644 --- a/base/iterators.jl +++ b/base/iterators.jl @@ -326,7 +326,7 @@ eltype(::Type{Zip{Is}}) where {Is<:Tuple} = Tuple{ntuple(n -> eltype(fieldtype(I #eltype(::Type{Zip{Tuple{}}}) = Tuple{} #eltype(::Type{Zip{Tuple{A}}}) where {A} = Tuple{eltype(A)} #eltype(::Type{Zip{Tuple{A, B}}}) where {A, B} = Tuple{eltype(A), eltype(B)} -@inline isdone(z::Zip) = _zip_any_isdone(z.is, Base.map(Returns(()), z.is)) +@inline isdone(z::Zip) = _zip_any_isdone(z.is, Base.map(_ -> (), z.is)) @inline isdone(z::Zip, ss) = _zip_any_isdone(z.is, Base.map(tuple, ss)) @inline function _zip_any_isdone(is, ss) d1 = isdone(is[1], ss[1]...) @@ -335,7 +335,7 @@ eltype(::Type{Zip{Is}}) where {Is<:Tuple} = Tuple{ntuple(n -> eltype(fieldtype(I end @inline _zip_any_isdone(::Tuple{}, ::Tuple{}) = false -@propagate_inbounds iterate(z::Zip) = _zip_iterate_all(z.is, Base.map(Returns(()), z.is)) +@propagate_inbounds iterate(z::Zip) = _zip_iterate_all(z.is, Base.map(_ -> (), z.is)) @propagate_inbounds iterate(z::Zip, ss) = _zip_iterate_all(z.is, Base.map(tuple, ss)) # This first queries isdone from every iterator. If any gives true, it immediately returns From b4e832f0fd1597d213f5d8ffc4ba4b815466ee38 Mon Sep 17 00:00:00 2001 From: Jan Weidner Date: Wed, 3 Mar 2021 10:33:09 +0100 Subject: [PATCH 11/16] Change lambdas to Returns in test --- test/abstractarray.jl | 16 ++++++------ test/arrayops.jl | 4 +-- test/bitarray.jl | 54 ++++++++++++++++++++------------------- test/ccall.jl | 2 +- test/channels.jl | 4 +-- test/core.jl | 8 +++--- test/generic_map_tests.jl | 2 +- test/iterators.jl | 4 +-- test/offsetarray.jl | 2 +- test/reduce.jl | 4 +-- test/show.jl | 2 +- test/subarray.jl | 8 +++--- test/tuple.jl | 2 +- 13 files changed, 57 insertions(+), 55 deletions(-) diff --git a/test/abstractarray.jl b/test/abstractarray.jl index dd24dc28364c7..539af360bae2a 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -299,10 +299,10 @@ function test_scalar_indexing(::Type{T}, shape, ::Type{TestAbstractArray}) where B = T(A) @test A == B # Test indexing up to 5 dimensions - trailing5 = CartesianIndex(ntuple(x->1, max(ndims(B)-5, 0))) - trailing4 = CartesianIndex(ntuple(x->1, max(ndims(B)-4, 0))) - trailing3 = CartesianIndex(ntuple(x->1, max(ndims(B)-3, 0))) - trailing2 = CartesianIndex(ntuple(x->1, max(ndims(B)-2, 0))) + trailing5 = CartesianIndex(ntuple(Returns(1), max(ndims(B)-5, 0))) + trailing4 = CartesianIndex(ntuple(Returns(1), max(ndims(B)-4, 0))) + trailing3 = CartesianIndex(ntuple(Returns(1), max(ndims(B)-3, 0))) + trailing2 = CartesianIndex(ntuple(Returns(1), max(ndims(B)-2, 0))) i=0 for i5 = 1:size(B, 5) for i4 = 1:size(B, 4) @@ -419,10 +419,10 @@ function test_vector_indexing(::Type{T}, shape, ::Type{TestAbstractArray}) where N = prod(shape) A = reshape(Vector(1:N), shape) B = T(A) - trailing5 = CartesianIndex(ntuple(x->1, max(ndims(B)-5, 0))) - trailing4 = CartesianIndex(ntuple(x->1, max(ndims(B)-4, 0))) - trailing3 = CartesianIndex(ntuple(x->1, max(ndims(B)-3, 0))) - trailing2 = CartesianIndex(ntuple(x->1, max(ndims(B)-2, 0))) + trailing5 = CartesianIndex(ntuple(Returns(1), max(ndims(B)-5, 0))) + trailing4 = CartesianIndex(ntuple(Returns(1), max(ndims(B)-4, 0))) + trailing3 = CartesianIndex(ntuple(Returns(1), max(ndims(B)-3, 0))) + trailing2 = CartesianIndex(ntuple(Returns(1), max(ndims(B)-2, 0))) idxs = rand(1:N, 3, 3, 3) @test B[idxs] == A[idxs] == idxs @test B[vec(idxs)] == A[vec(idxs)] == vec(idxs) diff --git a/test/arrayops.jl b/test/arrayops.jl index 08e3de11dceae..b212f63aaa746 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -1659,7 +1659,7 @@ end Nmax = 3 # TODO: go up to CARTESIAN_DIMS+2 (currently this exposes problems) for N = 1:Nmax #indexing with (UnitRange, UnitRange, UnitRange) - args = ntuple(d->UnitRange{Int}, N) + args = ntuple(Returns(UnitRange{Int}), N) @test Base.return_types(getindex, Tuple{Array{Float32, N}, args...}) == [Array{Float32, N}] @test Base.return_types(getindex, Tuple{BitArray{N}, args...}) == Any[BitArray{N}] @test Base.return_types(setindex!, Tuple{Array{Float32, N}, Array{Int, 1}, args...}) == [Array{Float32, N}] @@ -1786,7 +1786,7 @@ end @test mdsum(A) == 15 @test mdsum2(A) == 15 AA = reshape(aa, tuple(2, shp...)) - B = view(AA, 1:1, ntuple(i->Colon(), i)...) + B = view(AA, 1:1, ntuple(Returns(:), i)...) @test isa(Base.IndexStyle(B), Base.IteratorsMD.IndexCartesian) @test mdsum(B) == 15 @test mdsum2(B) == 15 diff --git a/test/bitarray.jl b/test/bitarray.jl index f246942452020..a5591fca26de7 100644 --- a/test/bitarray.jl +++ b/test/bitarray.jl @@ -1180,8 +1180,8 @@ timesofar("datamove") @check_bit_operation findfirst(x->x, b1) Union{Int,Nothing} @check_bit_operation findfirst(x->!x, b1) Union{Int,Nothing} - @check_bit_operation findfirst(x->true, b1) Union{Int,Nothing} - @check_bit_operation findfirst(x->false, b1) Union{Int,Nothing} + @check_bit_operation findfirst(Returns(true ), b1) Union{Int,Nothing} + @check_bit_operation findfirst(Returns(false), b1) Union{Int,Nothing} @check_bit_operation findall(b1) Vector{Int} end @@ -1275,49 +1275,51 @@ timesofar("find") @test_throws BoundsError findprevnot(b2, 1001) @test_throws BoundsError findprev(!, b2, 1001) @test_throws BoundsError findprev(identity, b1, 1001) - @test_throws BoundsError findprev(x->false, b1, 1001) - @test_throws BoundsError findprev(x->true, b1, 1001) + @test_throws BoundsError findprev(Returns(false), b1, 1001) + @test_throws BoundsError findprev(Returns(true ), b1, 1001) @test findprev(b1, 1000) == findprevnot(b2, 1000) == findprev(!, b2, 1000) == 777 @test findprev(b1, 777) == findprevnot(b2, 777) == findprev(!, b2, 777) == 777 @test findprev(b1, 776) == findprevnot(b2, 776) == findprev(!, b2, 776) == 77 @test findprev(b1, 77) == findprevnot(b2, 77) == findprev(!, b2, 77) == 77 @test findprev(b1, 76) == findprevnot(b2, 76) == findprev(!, b2, 76) == nothing @test findprev(b1, -1) == findprevnot(b2, -1) == findprev(!, b2, -1) == nothing - @test findprev(identity, b1, -1) == findprev(x->false, b1, -1) == findprev(x->true, b1, -1) == nothing + @test findprev(identity, b1, -1) == nothing + @test findprev(Returns(false), b1, -1) == nothing + @test findprev(Returns(true), b1, -1) == nothing @test_throws BoundsError findnext(b1, -1) @test_throws BoundsError findnextnot(b2, -1) @test_throws BoundsError findnext(!, b2, -1) @test_throws BoundsError findnext(identity, b1, -1) - @test_throws BoundsError findnext(x->false, b1, -1) - @test_throws BoundsError findnext(x->true, b1, -1) + @test_throws BoundsError findnext(Returns(false), b1, -1) + @test_throws BoundsError findnext(Returns(true), b1, -1) @test findnext(b1, 1) == findnextnot(b2, 1) == findnext(!, b2, 1) == 77 @test findnext(b1, 77) == findnextnot(b2, 77) == findnext(!, b2, 77) == 77 @test findnext(b1, 78) == findnextnot(b2, 78) == findnext(!, b2, 78) == 777 @test findnext(b1, 777) == findnextnot(b2, 777) == findnext(!, b2, 777) == 777 @test findnext(b1, 778) == findnextnot(b2, 778) == findnext(!, b2, 778) == nothing @test findnext(b1, 1001) == findnextnot(b2, 1001) == findnext(!, b2, 1001) == nothing - @test findnext(identity, b1, 1001) == findnext(x->false, b1, 1001) == findnext(x->true, b1, 1001) == nothing + @test findnext(identity, b1, 1001) == findnext(Returns(false), b1, 1001) == findnext(Returns(true), b1, 1001) == nothing @test findlast(b1) == Base.findlastnot(b2) == 777 @test findfirst(b1) == Base.findfirstnot(b2) == 77 b0 = BitVector() - @test findprev(x->true, b0, -1) == nothing - @test_throws BoundsError findprev(x->true, b0, 1) - @test_throws BoundsError findnext(x->true, b0, -1) - @test findnext(x->true, b0, 1) == nothing + @test findprev(Returns(true), b0, -1) == nothing + @test_throws BoundsError findprev(Returns(true), b0, 1) + @test_throws BoundsError findnext(Returns(true), b0, -1) + @test findnext(Returns(true), b0, 1) == nothing b1 = falses(10) - @test findprev(x->true, b1, 5) == 5 - @test findnext(x->true, b1, 5) == 5 - @test findprev(x->true, b1, -1) == nothing - @test findnext(x->true, b1, 11) == nothing - @test findprev(x->false, b1, 5) == nothing - @test findnext(x->false, b1, 5) == nothing - @test findprev(x->false, b1, -1) == nothing - @test findnext(x->false, b1, 11) == nothing - @test_throws BoundsError findprev(x->true, b1, 11) - @test_throws BoundsError findnext(x->true, b1, -1) + @test findprev(Returns(true), b1, 5) == 5 + @test findnext(Returns(true), b1, 5) == 5 + @test findprev(Returns(true), b1, -1) == nothing + @test findnext(Returns(true), b1, 11) == nothing + @test findprev(Returns(false), b1, 5) == nothing + @test findnext(Returns(false), b1, 5) == nothing + @test findprev(Returns(false), b1, -1) == nothing + @test findnext(Returns(false), b1, 11) == nothing + @test_throws BoundsError findprev(Returns(true), b1, 11) + @test_throws BoundsError findnext(Returns(true), b1, -1) @testset "issue 32568" for T = (UInt, BigInt) for x = (1, 2) @@ -1382,8 +1384,8 @@ timesofar("reductions") b2 = bitrand(l) @test map(~, b1) == map(x->~x, b1) == broadcast(~, b1) @test map(identity, b1) == map(x->x, b1) == b1 - @test map(zero, b1) == map(x->false, b1) == falses(l) - @test map(one, b1) == map(x->true, b1) == trues(l) + @test map(zero, b1) == map(Returns(false), b1) == falses(l) + @test map(one, b1) == map(Returns(true), b1) == trues(l) @test map(&, b1, b2) == map((x,y)->x&y, b1, b2) == broadcast(&, b1, b2) @test map(|, b1, b2) == map((x,y)->x|y, b1, b2) == broadcast(|, b1, b2) @@ -1407,8 +1409,8 @@ timesofar("reductions") @test map!(~, b, b1) == map!(x->~x, b, b1) == broadcast(~, b1) == b @test map!(!, b, b1) == map!(x->!x, b, b1) == broadcast(~, b1) == b @test map!(identity, b, b1) == map!(x->x, b, b1) == b1 == b - @test map!(zero, b, b1) == map!(x->false, b, b1) == falses(l) == b - @test map!(one, b, b1) == map!(x->true, b, b1) == trues(l) == b + @test map!(zero, b, b1) == map!(Returns(false), b, b1) == falses(l) == b + @test map!(one, b, b1) == map!(Returns(true), b, b1) == trues(l) == b @test map!(&, b, b1, b2) == map!((x,y)->x&y, b, b1, b2) == broadcast(&, b1, b2) == b @test map!(|, b, b1, b2) == map!((x,y)->x|y, b, b1, b2) == broadcast(|, b1, b2) == b diff --git a/test/ccall.jl b/test/ccall.jl index 8cb376c805611..88f693150eead 100644 --- a/test/ccall.jl +++ b/test/ccall.jl @@ -842,7 +842,7 @@ function check_code_trampoline(f, t, n::Int) @nospecialize(f, t) @test Base.return_types(f, t) == Any[Any] llvm = sprint(code_llvm, f, t) - @test count(x -> true, eachmatch(r"@jl_get_cfunction_trampoline\(", llvm)) == n + @test count(Returns(true), eachmatch(r"@jl_get_cfunction_trampoline\(", llvm)) == n end check_code_trampoline(testclosure, (Any, Any, Bool, Type), 2) check_code_trampoline(testclosure, (Any, Int, Bool, Type{Int}), 2) diff --git a/test/channels.jl b/test/channels.jl index c5b1b3f6db9a5..0611b387e6f88 100644 --- a/test/channels.jl +++ b/test/channels.jl @@ -333,7 +333,7 @@ end # interpreting the calling function. @noinline garbage_finalizer(f) = (finalizer(f, "gar" * "bage"); nothing) run = Ref(0) - garbage_finalizer(x -> nothing) # warmup + garbage_finalizer(Returns(nothing)) # warmup @test GC.enable(false) # test for finalizers trying to yield leading to failed attempts to context switch garbage_finalizer((x) -> (run[] += 1; sleep(1))) @@ -533,7 +533,7 @@ end # make sure that we don't accidentally create a one-shot timer let - t = Timer(t->nothing, 10, interval=0.00001) + t = Timer(Returns(nothing), 10, interval=0.00001) @test ccall(:uv_timer_get_repeat, UInt64, (Ptr{Cvoid},), t) == 1 close(t) end diff --git a/test/core.jl b/test/core.jl index c360dc6ba5b13..87bf436b474a7 100644 --- a/test/core.jl +++ b/test/core.jl @@ -5972,11 +5972,11 @@ end for U in boxedunions local U for N in (1, 2, 3, 4) - A = Array{U}(undef, ntuple(x->0, N)...) + A = Array{U}(undef, ntuple(Returns(0), N)...) @test isempty(A) @test sizeof(A) == 0 - A = Array{U}(undef, ntuple(x->10, N)...) + A = Array{U}(undef, ntuple(Returns(10), N)...) @test length(A) == 10^N @test sizeof(A) == sizeof(Int) * (10^N) @test !isassigned(A, 1) @@ -6057,11 +6057,11 @@ using Serialization for U in unboxedunions local U for N in (1, 2, 3, 4) - A = Array{U}(undef, ntuple(x->0, N)...) + A = Array{U}(undef, ntuple(Returns(0), N)...) @test isempty(A) @test sizeof(A) == 0 - len = ntuple(x->10, N) + len = ntuple(Returns(10), N) mxsz = maximum(sizeof, Base.uniontypes(U)) A = Array{U}(undef, len) @test length(A) == prod(len) diff --git a/test/generic_map_tests.jl b/test/generic_map_tests.jl index 8fde731770bf3..8e77533362fe3 100644 --- a/test/generic_map_tests.jl +++ b/test/generic_map_tests.jl @@ -76,6 +76,6 @@ function run_map_equivalence_tests(mapf) testmap_equivalence(mapf, identity, (1,2,3,4)) testmap_equivalence(mapf, (x,y,z)->x+y+z, 1,2,3) testmap_equivalence(mapf, x->x ? false : true, BitMatrix(undef, 10,10)) - testmap_equivalence(mapf, x->"foobar", BitMatrix(undef, 10,10)) + testmap_equivalence(mapf, Returns("foobar"), BitMatrix(undef, 10,10)) testmap_equivalence(mapf, (x,y,z)->string(x,y,z), BitVector(undef, 10), fill(1.0, 10), "1234567890") end diff --git a/test/iterators.jl b/test/iterators.jl index 1bd997d971ff3..c4b438d279693 100644 --- a/test/iterators.jl +++ b/test/iterators.jl @@ -381,7 +381,7 @@ let a = 1:2, end # size infinite or unknown raises an error - for itr in Any[countfrom(1), Iterators.filter(i->0, 1:10)] + for itr in Any[countfrom(1), Iterators.filter(Returns(0), 1:10)] @test_throws ArgumentError length(product(itr)) @test_throws ArgumentError size(product(itr)) @test_throws ArgumentError ndims(product(itr)) @@ -592,7 +592,7 @@ end end @testset "filter empty iterable #16704" begin - arr = filter(n -> true, 1:0) + arr = filter(Returns(true), 1:0) @test length(arr) == 0 @test eltype(arr) == Int end diff --git a/test/offsetarray.jl b/test/offsetarray.jl index 5deb442f36222..50fe2fcef4c1f 100644 --- a/test/offsetarray.jl +++ b/test/offsetarray.jl @@ -235,7 +235,7 @@ targets2 = ["(fill(1.0), fill(1.0))", "([1.0], [1.0])", "([1.0], [1.0])"] @testset "printing of OffsetArray with n=$n" for n = 0:4 - a = OffsetArray(fill(1.,ntuple(d->1,n)), ntuple(identity,n)) + a = OffsetArray(fill(1.,ntuple(Returns(1),n)), ntuple(identity,n)) show(IOContext(io, :limit => true), MIME("text/plain"), a) @test String(take!(io)) == targets1[n+1] show(IOContext(io, :limit => true), MIME("text/plain"), (a,a)) diff --git a/test/reduce.jl b/test/reduce.jl index f87b2285480f4..7f3963590fbe0 100644 --- a/test/reduce.jl +++ b/test/reduce.jl @@ -460,8 +460,8 @@ end @test reduce((a, b) -> a .& b, fill(trues(5), 24)) == trues(5) @test reduce((a, b) -> a .& b, fill(falses(5), 24)) == falses(5) -@test_throws TypeError any(x->0, [false]) -@test_throws TypeError all(x->0, [false]) +@test_throws TypeError any(Returns(0), [false]) +@test_throws TypeError all(Returns(0), [false]) # short-circuiting any and all diff --git a/test/show.jl b/test/show.jl index b9ddbc689efdb..a235026534e3b 100644 --- a/test/show.jl +++ b/test/show.jl @@ -1148,7 +1148,7 @@ let x = [], y = [], z = Base.ImmutableDict(x => y) """ dz = sprint(dump, z) @test 10 < countlines(IOBuffer(dz)) < 40 - @test sum(x -> 1, eachmatch(r"circular reference", dz)) == 4 + @test sum(Returns(1), eachmatch(r"circular reference", dz)) == 4 end # PR 16221 diff --git a/test/subarray.jl b/test/subarray.jl index 76f00ab7948cb..334211d3e3975 100644 --- a/test/subarray.jl +++ b/test/subarray.jl @@ -134,8 +134,8 @@ end function test_bounds(@nospecialize(A)) @test_throws BoundsError A[0] @test_throws BoundsError A[end+1] - trailing2 = ntuple(x->1, max(ndims(A)-2, 0)) - trailing3 = ntuple(x->1, max(ndims(A)-3, 0)) + trailing2 = ntuple(Returns(1), max(ndims(A)-2, 0)) + trailing3 = ntuple(Returns(1), max(ndims(A)-3, 0)) @test_throws BoundsError A[1, 0, trailing2...] @test_throws BoundsError A[1, end+1, trailing2...] @test_throws BoundsError A[1, 1, 0, trailing3...] @@ -214,10 +214,10 @@ end function runviews(SB::AbstractArray, indexN, indexNN, indexNNN) @assert ndims(SB) > 2 for i3 in indexN, i2 in indexN, i1 in indexN - runsubarraytests(SB, i1, i2, i3, ntuple(x->1, max(ndims(SB)-3, 0))...) + runsubarraytests(SB, i1, i2, i3, ntuple(Returns(1), max(ndims(SB)-3, 0))...) end for i2 in indexN, i1 in indexN - runsubarraytests(SB, i1, i2, ntuple(x->1, max(ndims(SB)-2, 0))...) + runsubarraytests(SB, i1, i2, ntuple(Returns(1), max(ndims(SB)-2, 0))...) end for i1 in indexNNN runsubarraytests(SB, i1) diff --git a/test/tuple.jl b/test/tuple.jl index 80a4323f6d2f2..7c274851ea555 100644 --- a/test/tuple.jl +++ b/test/tuple.jl @@ -278,7 +278,7 @@ end @testset "filter" begin @test filter(isodd, (1,2,3)) == (1, 3) @test filter(isequal(2), (true, 2.0, 3)) === (2.0,) - @test filter(i -> true, ()) == () + @test filter(Returns(true), ()) == () @test filter(identity, (true,)) === (true,) longtuple = ntuple(identity, 20) @test filter(iseven, longtuple) == ntuple(i->2i, 10) From 46165cd01bd8f5f2abfdf9c059d65c6fdc180cd4 Mon Sep 17 00:00:00 2001 From: Jan Weidner Date: Wed, 3 Mar 2021 12:42:00 +0100 Subject: [PATCH 12/16] fix Returns test --- test/operators.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/operators.jl b/test/operators.jl index 2d07be78fa6e0..898b523621361 100644 --- a/test/operators.jl +++ b/test/operators.jl @@ -296,5 +296,5 @@ a = rand(3, 3) @inferred f(1,2) val = [1,2,3] @test Returns(val)(1) === val - @test sprint(show, Returns(1)) == "Returns(1)" + @test sprint(show, Returns(1.0)) == "Returns{Float64}(1.0)" end From 283e647470ef0c8e34f54993774ffa58cf06a63d Mon Sep 17 00:00:00 2001 From: Jan Weidner Date: Wed, 3 Mar 2021 12:44:41 +0100 Subject: [PATCH 13/16] fix Returns show --- base/show.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/base/show.jl b/base/show.jl index b668296f875b4..c6f710dd39c22 100644 --- a/base/show.jl +++ b/base/show.jl @@ -45,6 +45,7 @@ function show(io::IO, ::MIME"text/plain", f::Function) end show(io::IO, ::MIME"text/plain", c::ComposedFunction) = show(io, c) +show(io::IO, ::MIME"text/plain", c::Returns) = show(io, c) function show(io::IO, ::MIME"text/plain", iter::Union{KeySet,ValueIterator}) isempty(iter) && get(io, :compact, false) && return show(io, iter) From d873d4a7149289efd727028cc93090112b85ddcf Mon Sep 17 00:00:00 2001 From: Jan Weidner Date: Thu, 4 Mar 2021 12:23:03 +0100 Subject: [PATCH 14/16] fix --- test/cartesian.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cartesian.jl b/test/cartesian.jl index 036c10883d451..af0bc466e3d04 100644 --- a/test/cartesian.jl +++ b/test/cartesian.jl @@ -407,5 +407,5 @@ end end # issue #39705 -f39705() = Base.Cartesian.@nany 0 Returns(true) +f39705() = Base.Cartesian.@nany 0 _ -> true @test f39705() === false From aa856109c59697c0d7f70db001fdfd50927ca180 Mon Sep 17 00:00:00 2001 From: Jan Weidner Date: Mon, 15 Mar 2021 23:33:58 +0100 Subject: [PATCH 15/16] Update NEWS.md Co-authored-by: Simeon Schaub --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 5b33b2f723a31..6cbf83663efbc 100644 --- a/NEWS.md +++ b/NEWS.md @@ -33,7 +33,7 @@ New library functions * Two argument methods `findmax(f, domain)`, `argmax(f, domain)` and the corresponding `min` versions ([#27613]). * `isunordered(x)` returns true if `x` is value that is normally unordered, such as `NaN` or `missing`. * New macro `Base.@invokelatest f(args...; kwargs...)` provides a convenient way to call `Base.invokelatest(f, args...; kwargs...)` ([#37971]) -* New function/type `Returns(value)` that creates a function, which returns `value` for any arguments ([ #39794]) +* New functor `Returns(value)`, which returns `value` for any arguments ([#39794]) * New macro `Base.@invoke f(arg1::T1, arg2::T2; kwargs...)` provides an easier syntax to call `invoke(f, Tuple{T1,T2}, arg1, arg2; kwargs...)` ([#38438]) New library features From 8cc1827dd0b96ba5142e66c961753afee540397b Mon Sep 17 00:00:00 2001 From: Jan Weidner Date: Tue, 16 Mar 2021 08:02:24 +0100 Subject: [PATCH 16/16] fix --- test/arrayops.jl | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/arrayops.jl b/test/arrayops.jl index b212f63aaa746..80a37c9d2f26a 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -1153,17 +1153,17 @@ end # issue #5177 c = fill(1,2,3,4) - m1 = mapslices(Returns(fill(1,2,3)), c, dims=[1,2]) - m2 = mapslices(Returns(fill(1,2,4)), c, dims=[1,3]) - m3 = mapslices(Returns(fill(1,3,4)), c, dims=[2,3]) + m1 = mapslices(_ -> fill(1,2,3), c, dims=[1,2]) + m2 = mapslices(_ -> fill(1,2,4), c, dims=[1,3]) + m3 = mapslices(_ -> fill(1,3,4), c, dims=[2,3]) @test size(m1) == size(m2) == size(m3) == size(c) - n1 = mapslices(Returns(fill(1,6) ), c, dims=[1,2]) - n2 = mapslices(Returns(fill(1,6) ), c, dims=[1,3]) - n3 = mapslices(Returns(fill(1,6) ), c, dims=[2,3]) - n1a = mapslices(Returns(fill(1,1,6)), c, dims=[1,2]) - n2a = mapslices(Returns(fill(1,1,6)), c, dims=[1,3]) - n3a = mapslices(Returns(fill(1,1,6)), c, dims=[2,3]) + n1 = mapslices(_ -> fill(1,6) , c, dims=[1,2]) + n2 = mapslices(_ -> fill(1,6) , c, dims=[1,3]) + n3 = mapslices(_ -> fill(1,6) , c, dims=[2,3]) + n1a = mapslices(_ -> fill(1,1,6), c, dims=[1,2]) + n2a = mapslices(_ -> fill(1,1,6), c, dims=[1,3]) + n3a = mapslices(_ -> fill(1,1,6), c, dims=[2,3]) @test size(n1a) == (1,6,4) && size(n2a) == (1,3,6) && size(n3a) == (2,1,6) @test size(n1) == (6,1,4) && size(n2) == (6,3,1) && size(n3) == (2,6,1)