Skip to content

Commit

Permalink
Remove single-argument methods for map, foreach, Iterators.map (#…
Browse files Browse the repository at this point in the history
…52631)

In the case of `map` and `foreach`, this removes awkward functionality.
`Iterators.map(::Any)`, on the other hand, already threw.
  • Loading branch information
nsajko authored Jan 18, 2024
1 parent 8c49e5e commit a28e553
Show file tree
Hide file tree
Showing 8 changed files with 25 additions and 17 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ Standard library changes
Deprecated or removed
---------------------

* `Base.map`, `Iterators.map`, and `foreach` lost their single-argument methods ([#52631]).


External dependencies
---------------------
Expand Down
9 changes: 2 additions & 7 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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 ##

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion base/iterators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions base/tuple.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
10 changes: 8 additions & 2 deletions stdlib/LinearAlgebra/src/adjtrans.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 1 addition & 2 deletions test/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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})
Expand Down
3 changes: 0 additions & 3 deletions test/functional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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 = []
Expand Down
9 changes: 9 additions & 0 deletions test/iterators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit a28e553

Please sign in to comment.