Skip to content

Commit abb0daa

Browse files
committed
remove mapreduce methods that don't take an iterator argument
PR JuliaLang#52631 made `map` throw `MethodError` when called without an iterator argument. That made `mapreduce` throw `MethodError` when called without an iterator argument, too, something that was *not* noticed back then. This change makes iteratorless `mapreduce` throw before it can be called, instead of when it tries to call `map` (or `Generator`) without passing it an iterator argument. Now all of these functions should only have methods that take a positive number of iterator arguments, which improves consistency: 1. `map` 2. `Iterators.map` 3. `foreach` 4. `reduce` 5. `foldl` 6. `foldr` 7. `mapreduce` 8. `mapfoldl` 9. `mapfoldr` 10. `Base.Generator`
1 parent 98f4747 commit abb0daa

File tree

3 files changed

+28
-9
lines changed

3 files changed

+28
-9
lines changed

base/reduce.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ implementations may reuse the return value of `f` for elements that appear multi
297297
guaranteed left or right associativity and invocation of `f` for every value.
298298
"""
299299
mapreduce(f, op, itr; kw...) = mapfoldl(f, op, itr; kw...)
300-
mapreduce(f, op, itrs...; kw...) = reduce(op, Generator(f, itrs...); kw...)
300+
mapreduce(f, op, itr, itrs...; kw...) = reduce(op, Generator(f, itr, itrs...); kw...)
301301

302302
# Note: sum_seq usually uses four or more accumulators after partial
303303
# unrolling, so each accumulator gets at most 256 numbers

base/reducedim.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,8 +326,8 @@ julia> mapreduce(isodd, |, a, dims=1)
326326
"""
327327
mapreduce(f, op, A::AbstractArrayOrBroadcasted; dims=:, init=_InitialValue()) =
328328
_mapreduce_dim(f, op, init, A, dims)
329-
mapreduce(f, op, A::AbstractArrayOrBroadcasted...; kw...) =
330-
reduce(op, map(f, A...); kw...)
329+
mapreduce(f, op, A::AbstractArrayOrBroadcasted, B::AbstractArrayOrBroadcasted...; kw...) =
330+
reduce(op, map(f, A, B...); kw...)
331331

332332
_mapreduce_dim(f, op, nt, A::AbstractArrayOrBroadcasted, ::Colon) =
333333
mapfoldl_impl(f, op, nt, A)

test/iterators.jl

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,12 +1037,31 @@ let itr = (i for i in 1:9) # Base.eltype == Any
10371037
@test collect(zip(repeat([Iterators.Stateful(itr)], 3)...)) == [(1, 2, 3), (4, 5, 6), (7, 8, 9)]
10381038
end
10391039

1040-
@testset "no single-argument map methods" begin
1041-
maps = (tuple, Returns(nothing), (() -> nothing))
1042-
mappers = (Iterators.map, map, foreach)
1043-
for f maps, m mappers
1044-
@test !applicable(m, f)
1045-
@test !hasmethod(m, Tuple{typeof(f)})
1040+
@testset "map/reduce/mapreduce without an iterator argument" begin
1041+
maps = map(Returns, (nothing, 3, 3:2, 3:3, (), (3,)))
1042+
mappers1 = (Iterators.map, map, foreach, reduce, foldl, foldr)
1043+
mappers2 = (mapreduce, mapfoldl, mapfoldr)
1044+
1045+
@testset "map/reduce" begin
1046+
@testset "r: $r" for r mappers1
1047+
@testset "f: $f" for f maps
1048+
@test_throws MethodError r(f)
1049+
@test !applicable(r, f)
1050+
@test !hasmethod(r, Tuple{typeof(f)})
1051+
end
1052+
end
1053+
end
1054+
1055+
@testset "mapreduce" begin
1056+
@testset "mr: $mr" for mr mappers2
1057+
@testset "f: $f" for f maps
1058+
@testset "g: $g" for g maps
1059+
@test_throws MethodError mr(f, g)
1060+
@test !applicable(mr, f, g)
1061+
@test !hasmethod(mr, Tuple{typeof(f),typeof(g)})
1062+
end
1063+
end
1064+
end
10461065
end
10471066
end
10481067

0 commit comments

Comments
 (0)