diff --git a/base/REPLCompletions.jl b/base/REPLCompletions.jl index 2c24a22c600bb..ccb27426fa25f 100644 --- a/base/REPLCompletions.jl +++ b/base/REPLCompletions.jl @@ -391,7 +391,7 @@ function shell_completions(string, pos) # Now look at the last thing we parsed isempty(args.args[end].args) && return UTF8String[], 0:-1, false arg = args.args[end].args[end] - if all(map(s -> isa(s, AbstractString), args.args[end].args)) + if all(s -> isa(s, AbstractString), args.args[end].args) # Treat this as a path (perhaps give a list of commands in the future as well?) return complete_path(join(args.args[end].args), pos) elseif isexpr(arg, :escape) && (isexpr(arg.args[1], :incomplete) || isexpr(arg.args[1], :error)) diff --git a/base/deprecated.jl b/base/deprecated.jl index 127d7abb4203c..bc3a4e156e662 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -738,3 +738,26 @@ function complement!(s::IntSet) end complement(s::IntSet) = complement!(copy(s)) export complement, complement! + + +# 11774 +# when removing these deprecations, move them to reduce.jl, remove the depwarns and uncomment the errors. + +nonboolean_warning(f, op, status) = """ + + Using non-boolean collections with $f(itr) is $status, use reduce($op, itr) instead. + If you are using $f(map(f, itr)) or $f([f(x) for x in itr]), use $f(f, itr) instead. +""" + + +function nonboolean_any(itr) + depwarn(nonboolean_warning(:any, :|, "deprecated"), :nonboolean_any) + #throw(ArgumentError(nonboolean_warning(:any, :|, "not supported"))) + reduce(|, itr) +end + +function nonboolean_all(itr) + depwarn(nonboolean_warning(:all, :&, "deprecated"), :nonboolean_all) + #throw(ArgumentError(nonboolean_warning(:all, :&, "not supported"))) + reduce(&, itr) +end diff --git a/base/functors.jl b/base/functors.jl index 8f239ea661c40..69bc52d0eac7a 100644 --- a/base/functors.jl +++ b/base/functors.jl @@ -76,6 +76,20 @@ end call(f::UnspecializedFun{1}, x) = f.f(x) call(f::UnspecializedFun{2}, x, y) = f.f(x,y) +# Special purpose functors + +type Predicate{F} <: Func{1} + f::F +end +call(pred::Predicate, x) = pred.f(x)::Bool + + +immutable EqX{T} <: Func{1} + x::T +end +EqX{T}(x::T) = EqX{T}(x) + +call(f::EqX, y) = f.x == y #### Bitwise operators #### diff --git a/base/pkg/query.jl b/base/pkg/query.jl index 6c304c12aa644..2a7245d524b84 100644 --- a/base/pkg/query.jl +++ b/base/pkg/query.jl @@ -89,7 +89,7 @@ end function check_requirements(reqs::Requires, deps::Dict{ByteString,Dict{VersionNumber,Available}}, fix::Dict) for (p,vs) in reqs - if !any([(vn in vs) for vn in keys(deps[p])]) + if !any(vn->(vn in vs), keys(deps[p])) remaining_vs = VersionSet() err_msg = "fixed packages introduce conflicting requirements for $p: \n" available_list = sort(collect(keys(deps[p]))) diff --git a/base/reduce.jl b/base/reduce.jl index ae15b886da4ba..7ba0955c325d6 100644 --- a/base/reduce.jl +++ b/base/reduce.jl @@ -155,12 +155,65 @@ end mapreduce(f, op, A::AbstractArray) = _mapreduce(f, op, A) mapreduce(f, op, a::Number) = f(a) -mapreduce(f, op::Function, A::AbstractArray) = _mapreduce(f, specialized_binary(op), A) +mapreduce(f, op::Function, A::AbstractArray) = mapreduce(f, specialized_binary(op), A) reduce(op, v0, itr) = mapreduce(IdFun(), op, v0, itr) reduce(op, itr) = mapreduce(IdFun(), op, itr) reduce(op, a::Number) = a +### short-circuiting specializations of mapreduce + +## conditions and results of short-circuiting + +const ShortCircuiting = Union{AndFun, OrFun} +const ReturnsBool = Union{EqX, Predicate} + +shortcircuits(::AndFun, x::Bool) = !x +shortcircuits(::OrFun, x::Bool) = x + +shorted(::AndFun) = false +shorted(::OrFun) = true + +sc_finish(::AndFun) = true +sc_finish(::OrFun) = false + +## short-circuiting (sc) mapreduce definitions + +function mapreduce_sc_impl(f, op, itr::AbstractArray) + @inbounds for x in itr + shortcircuits(op, f(x)) && return shorted(op) + end + return sc_finish(op) +end + +function mapreduce_sc_impl(f, op, itr) + for x in itr + shortcircuits(op, f(x)) && return shorted(op) + end + return sc_finish(op) +end + +# mapreduce_sc tests if short-circuiting is safe; +# if so, mapreduce_sc_impl is called. If it's not +# safe, call mapreduce_no_sc, which redirects to +# non-short-circuiting definitions. + +mapreduce_no_sc(f, op, itr::Any) = mapfoldl(f, op, itr) +mapreduce_no_sc(f, op, itr::AbstractArray) = _mapreduce(f, op, itr) + +mapreduce_sc(f::Function, op, itr) = mapreduce_sc(specialized_unary(f), op, itr) +mapreduce_sc(f::ReturnsBool, op, itr) = mapreduce_sc_impl(f, op, itr) +mapreduce_sc(f::Func{1}, op, itr) = mapreduce_no_sc(f, op, itr) + +mapreduce_sc(f::IdFun, op, itr) = + eltype(itr) <: Bool? + mapreduce_sc_impl(f, op, itr) : + mapreduce_no_sc(f, op, itr) + +mapreduce(f, op::ShortCircuiting, n::Number) = n +mapreduce(f, op::ShortCircuiting, itr::AbstractArray) = mapreduce_sc(f,op,itr) +mapreduce(f, op::ShortCircuiting, itr::Any) = mapreduce_sc(f,op,itr) + ###### Specific reduction functions ###### @@ -298,53 +351,28 @@ end ## all & any -function mapfoldl(f, ::AndFun, itr) - for x in itr - !f(x) && return false - end - return true -end - -function mapfoldl(f, ::OrFun, itr) - for x in itr - f(x) && return true - end - return false -end - -function mapreduce_impl(f, op::AndFun, A::AbstractArray{Bool}, ifirst::Int, ilast::Int) - while ifirst <= ilast - @inbounds x = A[ifirst] - !f(x) && return false - ifirst += 1 - end - return true -end +# make sure that the identity function is defined before `any` or `all` are used +function identity end -function mapreduce_impl(f, op::OrFun, A::AbstractArray{Bool}, ifirst::Int, ilast::Int) - while ifirst <= ilast - @inbounds x = A[ifirst] - f(x) && return true - ifirst += 1 - end - return false -end - -all(a) = mapreduce(IdFun(), AndFun(), a) -any(a) = mapreduce(IdFun(), OrFun(), a) +any(itr) = any(IdFun(), itr) +all(itr) = all(IdFun(), itr) -all(pred::Union{Callable,Func{1}}, a) = mapreduce(pred, AndFun(), a) -any(pred::Union{Callable,Func{1}}, a) = mapreduce(pred, OrFun(), a) +any(f::Any, itr) = any(f === identity? IdFun() : Predicate(f), itr) +any(f::Predicate, itr) = mapreduce_sc_impl(f, OrFun(), itr) +any(f::IdFun, itr) = + eltype(itr) <: Bool? + mapreduce_sc_impl(f, OrFun(), itr) : + nonboolean_any(itr) +all(f::Any, itr) = all(f === identity? IdFun() : Predicate(f), itr) +all(f::Predicate, itr) = mapreduce_sc_impl(f, AndFun(), itr) +all(f::IdFun, itr) = + eltype(itr) <: Bool? + mapreduce_sc_impl(f, AndFun(), itr) : + nonboolean_all(itr) ## in & contains -immutable EqX{T} <: Func{1} - x::T -end -EqX{T}(x::T) = EqX{T}(x) - -call(f::EqX, y) = f.x == y in(x, itr) = any(EqX(x), itr) const ∈ = in diff --git a/base/subarray.jl b/base/subarray.jl index 889bae0c35e54..6d874f899c9f2 100644 --- a/base/subarray.jl +++ b/base/subarray.jl @@ -356,7 +356,7 @@ in(::Int, ::Colon) = true ## Strides @generated function strides{T,N,P,I}(V::SubArray{T,N,P,I}) Ip = I.parameters - all(map(x->x<:Union{RangeIndex,Colon}, Ip)) || throw(ArgumentError("strides valid only for RangeIndex indexing")) + all(x->x<:Union{RangeIndex,Colon}, Ip) || throw(ArgumentError("strides valid only for RangeIndex indexing")) strideexprs = Array(Any, N+1) strideexprs[1] = 1 i = 1 diff --git a/examples/queens.jl b/examples/queens.jl index 04803f3f8a014..dba16fd5ad40f 100644 --- a/examples/queens.jl +++ b/examples/queens.jl @@ -2,7 +2,7 @@ addqueen(queens::Array{Vector{Int}}, queen::Vector{Int}) = push!(copy(queens), queen) -hitsany(queen::Vector{Int}, queens::Array{Vector{Int}}) = any(map(x->hits(queen, x), queens)) +hitsany(queen::Vector{Int}, queens::Array{Vector{Int}}) = any(x->hits(queen, x), queens) hits(a::Array{Int}, b::Array{Int}) = any(a .== b) || abs(a-b)[1] == abs(a-b)[2] function solve(x, y, n, d=Array(Vector{Int}, 0)) diff --git a/test/bitarray.jl b/test/bitarray.jl index 52537214283df..0fa6e7062aa22 100644 --- a/test/bitarray.jl +++ b/test/bitarray.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: http://julialang.org/license -tc{N}(r1::NTuple{N}, r2::NTuple{N}) = all(map(x->tc(x...), [zip(r1,r2)...])) +tc{N}(r1::NTuple{N}, r2::NTuple{N}) = all(x->tc(x...), [zip(r1,r2)...]) tc{N}(r1::BitArray{N}, r2::Union{BitArray{N},Array{Bool,N}}) = true tc{T}(r1::T, r2::T) = true tc(r1,r2) = false diff --git a/test/dates/ranges.jl b/test/dates/ranges.jl index 1a3b15bb9d627..3b5b3ff14bbf2 100644 --- a/test/dates/ranges.jl +++ b/test/dates/ranges.jl @@ -258,17 +258,17 @@ drs2 = map(x->Dates.Date(first(x)):step(x):Dates.Date(last(x)),drs) @test map(length,drs) == map(x->size(x)[1],drs) @test map(length,drs) == map(x->length(Dates.Date(first(x)):step(x):Dates.Date(last(x))),drs) @test map(length,drs) == map(x->length(reverse(x)),drs) -@test all(map(x->findin(x,x)==[1:length(x);],drs[1:4])) +@test all(x->findin(x,x)==[1:length(x);],drs[1:4]) @test isempty(dr2) -@test all(map(x->reverse(x) == range(last(x), -step(x), length(x)),drs)) -@test all(map(x->minimum(x) == (step(x) < zero(step(x)) ? last(x) : first(x)),drs[4:end])) -@test all(map(x->maximum(x) == (step(x) < zero(step(x)) ? first(x) : last(x)),drs[4:end])) -@test all(map(drs[1:3]) do dd +@test all(x->reverse(x) == range(last(x), -step(x), length(x)),drs) +@test all(x->minimum(x) == (step(x) < zero(step(x)) ? last(x) : first(x)),drs[4:end]) +@test all(x->maximum(x) == (step(x) < zero(step(x)) ? first(x) : last(x)),drs[4:end]) +@test all(drs[1:3]) do dd for (i,d) in enumerate(dd) @test d == (first(dd) + Dates.Day(i-1)) end true -end) +end @test_throws MethodError dr + 1 a = Dates.DateTime(2013,1,1) b = Dates.DateTime(2013,2,1) @@ -283,8 +283,8 @@ b = Dates.DateTime(2013,2,1) @test Dates.DateTime(2013,1,26) in dr @test !(Dates.DateTime(2012,1,1) in dr) -@test all(map(x->sort(x) == (step(x) < zero(step(x)) ? reverse(x) : x),drs)) -@test all(map(x->step(x) < zero(step(x)) ? issorted(reverse(x)) : issorted(x),drs)) +@test all(x->sort(x) == (step(x) < zero(step(x)) ? reverse(x) : x),drs) +@test all(x->step(x) < zero(step(x)) ? issorted(reverse(x)) : issorted(x),drs) @test length(b:Dates.Day(-1):a) == 32 @test length(b:a) == 0 @@ -336,17 +336,17 @@ drs = Any[dr,dr1,dr2,dr3,dr4,dr5,dr6,dr7,dr8,dr9,dr10, dr11,dr12,dr13,dr14,dr15,dr16,dr17,dr18,dr19,dr20] @test map(length,drs) == map(x->size(x)[1],drs) -@test all(map(x->findin(x,x) == [1:length(x);], drs[1:4])) +@test all(x->findin(x,x) == [1:length(x);], drs[1:4]) @test isempty(dr2) -@test all(map(x->reverse(x) == last(x):-step(x):first(x),drs)) -@test all(map(x->minimum(x) == (step(x) < zero(step(x)) ? last(x) : first(x)),drs[4:end])) -@test all(map(x->maximum(x) == (step(x) < zero(step(x)) ? first(x) : last(x)),drs[4:end])) -@test all(map(drs[1:3]) do dd +@test all(x->reverse(x) == last(x):-step(x):first(x),drs) +@test all(x->minimum(x) == (step(x) < zero(step(x)) ? last(x) : first(x)),drs[4:end]) +@test all(x->maximum(x) == (step(x) < zero(step(x)) ? first(x) : last(x)),drs[4:end]) +@test all(drs[1:3]) do dd for (i,d) in enumerate(dd) @test d == (first(dd) + Dates.Day(i-1)) end true -end) +end @test_throws MethodError dr + 1 a = Dates.Date(2013,1,1) b = Dates.Date(2013,2,1) @@ -361,8 +361,8 @@ b = Dates.Date(2013,2,1) @test Dates.Date(2013,1,26) in dr @test !(Dates.Date(2012,1,1) in dr) -@test all(map(x->sort(x) == (step(x) < zero(step(x)) ? reverse(x) : x),drs)) -@test all(map(x->step(x) < zero(step(x)) ? issorted(reverse(x)) : issorted(x),drs)) +@test all(x->sort(x) == (step(x) < zero(step(x)) ? reverse(x) : x),drs) +@test all(x->step(x) < zero(step(x)) ? issorted(reverse(x)) : issorted(x),drs) @test length(b:Dates.Day(-1):a) == 32 @test length(b:a) == 0 diff --git a/test/reduce.jl b/test/reduce.jl index 21661c5c38fcc..4426525086b16 100644 --- a/test/reduce.jl +++ b/test/reduce.jl @@ -204,6 +204,27 @@ prod2(itr) = invoke(prod, Tuple{Any}, itr) @test reduce(&, fill(trues(5), 24)) == trues(5) @test reduce(&, fill(falses(5), 24)) == falses(5) +@test_throws TypeError any(x->0, [false]) +@test_throws TypeError all(x->0, [false]) + +# short-circuiting any and all + +let c = [0, 0], A = 1:1000 + any(x->(c[1]=x; x==10), A) + all(x->(c[2]=x; x!=10), A) + + @test c == [10,10] +end + +# any and all with functors + +immutable SomeFunctor end +Base.call(::SomeFunctor, x) = true + +@test any(SomeFunctor(), 1:10) +@test all(SomeFunctor(), 1:10) + + # in @test in(1, Int[]) == false