diff --git a/NEWS.md b/NEWS.md index 9dba8544cecbf..fed1fae81dd83 100644 --- a/NEWS.md +++ b/NEWS.md @@ -171,6 +171,8 @@ Standard library changes Deprecated or removed --------------------- +* `Base.map`, `Iterators.map`, and `foreach` lost their single-argument methods ([#52631]). + External dependencies --------------------- diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 743aca7395c91..7248e9f8038e6 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -3108,9 +3108,8 @@ julia> foreach((x, y) -> println(x, " with ", y), tri, 'a':'z') 7 with c ``` """ -foreach(f) = (f(); nothing) foreach(f, itr) = (for x in itr; f(x); end; nothing) -foreach(f, itrs...) = (for z in zip(itrs...); f(z...); end; nothing) +foreach(f, itr, itrs...) = (for z in zip(itr, itrs...); f(z...); end; nothing) ## map over arrays ## @@ -3282,10 +3281,6 @@ end concatenate_setindex!(R, v, I...) = (R[I...] .= (v,); R) concatenate_setindex!(R, X::AbstractArray, I...) = (R[I...] = X) -## 0 arguments - -map(f) = f() - ## 1 argument function map!(f::F, dest::AbstractArray, A::AbstractArray) where F @@ -3421,7 +3416,7 @@ julia> map(+, [1 2; 3 4], [1,10,100,1000], zeros(3,1)) # iterates until 3rd is 102.0 ``` """ -map(f, iters...) = collect(Generator(f, iters...)) +map(f, it, iters...) = collect(Generator(f, it, iters...)) # multi-item push!, pushfirst! (built on top of type-specific 1-item version) # (note: must not cause a dispatch loop when 1-item case is not defined) diff --git a/base/iterators.jl b/base/iterators.jl index 14cbd104c09d1..a03d426e05622 100644 --- a/base/iterators.jl +++ b/base/iterators.jl @@ -59,7 +59,7 @@ julia> collect(Iterators.map(x -> x^2, 1:3)) 9 ``` """ -map(f, args...) = Base.Generator(f, args...) +map(f, arg, args...) = Base.Generator(f, arg, args...) tail_if_any(::Tuple{}) = () tail_if_any(x::Tuple) = tail(x) diff --git a/base/tuple.jl b/base/tuple.jl index 19b88234cbb00..274f8d8354890 100644 --- a/base/tuple.jl +++ b/base/tuple.jl @@ -321,7 +321,7 @@ end # n argument function heads(ts::Tuple...) = map(t -> t[1], ts) tails(ts::Tuple...) = map(tail, ts) -map(f, ::Tuple{}...) = () +map(f, ::Tuple{}, ::Tuple{}...) = () anyempty(x::Tuple{}, xs...) = true anyempty(x::Tuple, xs...) = anyempty(xs...) anyempty() = false @@ -615,4 +615,4 @@ Return an empty tuple, `()`. empty(@nospecialize x::Tuple) = () foreach(f, itr::Tuple) = foldl((_, x) -> (f(x); nothing), itr, init=nothing) -foreach(f, itrs::Tuple...) = foldl((_, xs) -> (f(xs...); nothing), zip(itrs...), init=nothing) +foreach(f, itr::Tuple, itrs::Tuple...) = foldl((_, xs) -> (f(xs...); nothing), zip(itr, itrs...), init=nothing) diff --git a/stdlib/LinearAlgebra/src/adjtrans.jl b/stdlib/LinearAlgebra/src/adjtrans.jl index 5ad678e82f014..24ad7960f00b4 100644 --- a/stdlib/LinearAlgebra/src/adjtrans.jl +++ b/stdlib/LinearAlgebra/src/adjtrans.jl @@ -396,8 +396,14 @@ hcat(tvs::Transpose{T,Vector{T}}...) where {T} = _transpose_hcat(tvs...) # # note that the caller's operation f operates in the domain of the wrapped vectors' entries. # hence the adjoint->f->adjoint shenanigans applied to the parent vectors' entries. -map(f, avs::AdjointAbsVec...) = adjoint(map((xs...) -> adjoint(f(adjoint.(xs)...)), parent.(avs)...)) -map(f, tvs::TransposeAbsVec...) = transpose(map((xs...) -> transpose(f(transpose.(xs)...)), parent.(tvs)...)) +function map(f, av::AdjointAbsVec, avs::AdjointAbsVec...) + s = (av, avs...) + adjoint(map((xs...) -> adjoint(f(adjoint.(xs)...)), parent.(s)...)) +end +function map(f, tv::TransposeAbsVec, tvs::TransposeAbsVec...) + s = (tv, tvs...) + transpose(map((xs...) -> transpose(f(transpose.(xs)...)), parent.(s)...)) +end quasiparentt(x) = parent(x); quasiparentt(x::Number) = x # to handle numbers in the defs below quasiparenta(x) = parent(x); quasiparenta(x::Number) = conj(x) # to handle numbers in the defs below quasiparentc(x) = parent(parent(x)); quasiparentc(x::Number) = conj(x) # to handle numbers in the defs below diff --git a/test/abstractarray.jl b/test/abstractarray.jl index d1987bbe0b668..21b80c257872f 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -822,9 +822,8 @@ Base.getindex(A::TSlowNIndexes{T,2}, i::Int, j::Int) where {T} = A.data[i,j] @test isa(map(Set, Array[[1,2],[3,4]]), Vector{Set{Int}}) end -@testset "mapping over scalars and empty arguments:" begin +@testset "mapping over scalars" begin @test map(sin, 1) === sin(1) - @test map(()->1234) === 1234 end function test_UInt_indexing(::Type{TestAbstractArray}) diff --git a/test/functional.jl b/test/functional.jl index fce64c0e5720a..3436fb8911cc1 100644 --- a/test/functional.jl +++ b/test/functional.jl @@ -52,9 +52,6 @@ end # foreach let a = [] - foreach(()->push!(a,0)) - @test a == [0] - a = [] foreach(x->push!(a,x), [1,5,10]) @test a == [1,5,10] a = [] diff --git a/test/iterators.jl b/test/iterators.jl index 74d7d61f0a496..d8184eab7b656 100644 --- a/test/iterators.jl +++ b/test/iterators.jl @@ -1010,6 +1010,15 @@ end @test collect(Iterators.partition(lstrip("01111", '0'), 2)) == ["11", "11"] end +@testset "no single-argument map methods" begin + maps = (tuple, Returns(nothing), (() -> nothing)) + mappers = (Iterators.map, map, foreach) + for f ∈ maps, m ∈ mappers + @test !applicable(m, f) + @test !hasmethod(m, Tuple{typeof(f)}) + end +end + @testset "Iterators docstrings" begin @test isempty(Docs.undocumented_names(Iterators)) end