Skip to content

Commit

Permalink
Merge pull request #15804 from martinholters/depfunctors
Browse files Browse the repository at this point in the history
Defunctorize
  • Loading branch information
tkelman committed Apr 22, 2016
2 parents 5c9b7a6 + 0429c38 commit 21a7d4d
Show file tree
Hide file tree
Showing 33 changed files with 332 additions and 603 deletions.
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,6 @@ CORE_SRCS := $(addprefix $(JULIAHOME)/, \
base/essentials.jl \
base/generator.jl \
base/expr.jl \
base/functors.jl \
base/hashing.jl \
base/inference.jl \
base/int.jl \
Expand Down
34 changes: 8 additions & 26 deletions base/arraymath.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,67 +56,49 @@ promote_array_type(F, ::Type{Bool}, ::Type{Bool}) = promote_op(F, Bool, Bool)
.^(X::AbstractArray, y::Number ) =
reshape([ x ^ y for x in X ], size(X))

for (f,F) in ((:+, AddFun()),
(:-, SubFun()),
(:div, IDivFun()),
(:mod, ModFun()),
(:&, AndFun()),
(:|, OrFun()),
(:$, XorFun()))
for f in (:+, :-, :div, :mod, :&, :|, :$)
@eval begin
function ($f){S,T}(A::Range{S}, B::Range{T})
F = similar(A, promote_op($F,S,T), promote_shape(size(A),size(B)))
F = similar(A, promote_op($f,S,T), promote_shape(size(A),size(B)))
for (iF, iA, iB) in zip(eachindex(F), eachindex(A), eachindex(B))
@inbounds F[iF] = ($f)(A[iA], B[iB])
end
return F
end
function ($f){S,T}(A::AbstractArray{S}, B::Range{T})
F = similar(A, promote_op($F,S,T), promote_shape(size(A),size(B)))
F = similar(A, promote_op($f,S,T), promote_shape(size(A),size(B)))
for (iF, iA, iB) in zip(eachindex(F), eachindex(A), eachindex(B))
@inbounds F[iF] = ($f)(A[iA], B[iB])
end
return F
end
function ($f){S,T}(A::Range{S}, B::AbstractArray{T})
F = similar(B, promote_op($F,S,T), promote_shape(size(A),size(B)))
F = similar(B, promote_op($f,S,T), promote_shape(size(A),size(B)))
for (iF, iA, iB) in zip(eachindex(F), eachindex(A), eachindex(B))
@inbounds F[iF] = ($f)(A[iA], B[iB])
end
return F
end
function ($f){S,T}(A::AbstractArray{S}, B::AbstractArray{T})
F = similar(A, promote_op($F,S,T), promote_shape(size(A),size(B)))
F = similar(A, promote_op($f,S,T), promote_shape(size(A),size(B)))
for (iF, iA, iB) in zip(eachindex(F), eachindex(A), eachindex(B))
@inbounds F[iF] = ($f)(A[iA], B[iB])
end
return F
end
end
end
for (f,F) in ((:.+, DotAddFun()),
(:.-, DotSubFun()),
(:.*, DotMulFun()),
(:, DotIDivFun()),
(:.%, DotRemFun()),
(:.<<, DotLSFun()),
(:.>>, DotRSFun()),
(:div, IDivFun()),
(:mod, ModFun()),
(:rem, RemFun()),
(:&, AndFun()),
(:|, OrFun()),
(:$, XorFun()))
for f in (:.+, :.-, :.*, :, :.%, :.<<, :.>>, :div, :mod, :rem, :&, :|, :$)
@eval begin
function ($f){T}(A::Number, B::AbstractArray{T})
F = similar(B, promote_array_type($F,typeof(A),T))
F = similar(B, promote_array_type($f,typeof(A),T))
for (iF, iB) in zip(eachindex(F), eachindex(B))
@inbounds F[iF] = ($f)(A, B[iB])
end
return F
end
function ($f){T}(A::AbstractArray{T}, B::Number)
F = similar(A, promote_array_type($F,typeof(B),T))
F = similar(A, promote_array_type($f,typeof(B),T))
for (iF, iA) in zip(eachindex(F), eachindex(A))
@inbounds F[iF] = ($f)(A[iA], B)
end
Expand Down
2 changes: 0 additions & 2 deletions base/base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,6 @@ gc_enable(on::Bool) = ccall(:jl_gc_enable, Cint, (Cint,), on)!=0

bytestring(str::ByteString) = str

identity(x) = x

# used by { } syntax
function cell_1d(xs::ANY...)
n = length(xs)
Expand Down
47 changes: 29 additions & 18 deletions base/bitarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1047,12 +1047,11 @@ for f in (:+, :-)
return r
end
end
for (f,F) in ((:.+, DotAddFun()),
(:.-, DotSubFun()))
for (f) in (:.+, :.-)
for (arg1, arg2, T, fargs) in ((:(B::BitArray), :(x::Bool) , Int , :(b, x)),
(:(B::BitArray), :(x::Number) , :(promote_array_type($F, typeof(x), Bool)), :(b, x)),
(:(B::BitArray), :(x::Number) , :(promote_array_type($f, typeof(x), Bool)), :(b, x)),
(:(x::Bool) , :(B::BitArray), Int , :(x, b)),
(:(x::Number) , :(B::BitArray), :(promote_array_type($F, typeof(x), Bool)), :(x, b)))
(:(x::Number) , :(B::BitArray), :(promote_array_type($f, typeof(x), Bool)), :(x, b)))
@eval function ($f)($arg1, $arg2)
r = Array($T, size(B))
bi = start(B)
Expand Down Expand Up @@ -1091,7 +1090,7 @@ function div(x::Bool, B::BitArray)
end
function div(x::Number, B::BitArray)
all(B) || throw(DivideError())
pt = promote_array_type(IDivFun(), typeof(x), Bool)
pt = promote_array_type(div, typeof(x), Bool)
y = div(x, true)
reshape(pt[ y for i = 1:length(B) ], size(B))
end
Expand All @@ -1112,16 +1111,15 @@ function mod(x::Bool, B::BitArray)
end
function mod(x::Number, B::BitArray)
all(B) || throw(DivideError())
pt = promote_array_type(ModFun(), typeof(x), Bool)
pt = promote_array_type(mod, typeof(x), Bool)
y = mod(x, true)
reshape(pt[ y for i = 1:length(B) ], size(B))
end

for (f,F) in ((:div, IDivFun()),
(:mod, ModFun()))
for f in (:div, :mod)
@eval begin
function ($f)(B::BitArray, x::Number)
F = Array(promote_array_type($F, typeof(x), Bool), size(B))
F = Array(promote_array_type($f, typeof(x), Bool), size(B))
for i = 1:length(F)
F[i] = ($f)(B[i], x)
end
Expand Down Expand Up @@ -1676,7 +1674,7 @@ end

## Reductions ##

sum(A::BitArray, region) = reducedim(AddFun(), A, region)
sum(A::BitArray, region) = reducedim(+, A, region)
sum(B::BitArray) = countnz(B)

function all(B::BitArray)
Expand Down Expand Up @@ -1711,19 +1709,32 @@ maximum(B::BitArray) = isempty(B) ? throw(ArgumentError("argument must be non-em
# arrays since there can be a 64x speedup by working at the level of Int64
# instead of looping bit-by-bit.

map(f::Function, A::BitArray) = map(specialized_bitwise_unary(f), A)
map(f::Function, A::BitArray, B::BitArray) = map(specialized_bitwise_binary(f), A, B)
map(f::BitFunctorUnary, A::BitArray) = map!(f, similar(A), A)
map(f::BitFunctorBinary, A::BitArray, B::BitArray) = map!(f, similar(A), A, B)
map(f::Function, A::BitArray) = map!(f, similar(A), A)
map(f::Function, A::BitArray, B::BitArray) = map!(f, similar(A), A, B)

map!(f, A::BitArray) = map!(f, A, A)
map!(f::Function, dest::BitArray, A::BitArray) = map!(specialized_bitwise_unary(f), dest, A)
map!(f::Function, dest::BitArray, A::BitArray, B::BitArray) = map!(specialized_bitwise_binary(f), dest, A, B)
map!(f::typeof(!), dest::BitArray, A::BitArray) = map!(~, dest, A)
map!(f::typeof(zero), dest::BitArray, A::BitArray) = fill!(dest, false)
map!(f::typeof(one), dest::BitArray, A::BitArray) = fill!(dest, true)

immutable BitChunkFunctor{F<:Function}
f::F
end
(f::BitChunkFunctor)(x, y) = f.f(x,y)

map!(f::Union{typeof(*), typeof(min)}, dest::BitArray, A::BitArray, B::BitArray) = map!(&, dest, A, B)
map!(f::typeof(max), dest::BitArray, A::BitArray, B::BitArray) = map!(|, dest, A, B)
map!(f::typeof(!=), dest::BitArray, A::BitArray, B::BitArray) = map!($, dest, A, B)
map!(f::Union{typeof(>=), typeof(^)}, dest::BitArray, A::BitArray, B::BitArray) = map!(BitChunkFunctor((p, q) -> p | ~q), dest, A, B)
map!(f::typeof(<=), dest::BitArray, A::BitArray, B::BitArray) = map!(BitChunkFunctor((p, q) -> ~p | q), dest, A, B)
map!(f::typeof(==), dest::BitArray, A::BitArray, B::BitArray) = map!(BitChunkFunctor((p, q) -> ~(p $ q)), dest, A, B)
map!(f::typeof(<), dest::BitArray, A::BitArray, B::BitArray) = map!(BitChunkFunctor((p, q) -> ~p & q), dest, A, B)
map!(f::typeof(>), dest::BitArray, A::BitArray, B::BitArray) = map!(BitChunkFunctor((p, q) -> p & ~q), dest, A, B)

# If we were able to specialize the function to a known bitwise operation,
# map across the chunks. Otherwise, fall-back to the AbstractArray method that
# iterates bit-by-bit.
function map!(f::BitFunctorUnary, dest::BitArray, A::BitArray)
function map!(f::Union{typeof(identity), typeof(~)}, dest::BitArray, A::BitArray)
size(A) == size(dest) || throw(DimensionMismatch("sizes of dest and A must match"))
isempty(A) && return dest
for i=1:length(A.chunks)-1
Expand All @@ -1732,7 +1743,7 @@ function map!(f::BitFunctorUnary, dest::BitArray, A::BitArray)
dest.chunks[end] = f(A.chunks[end]) & _msk_end(A)
dest
end
function map!(f::BitFunctorBinary, dest::BitArray, A::BitArray, B::BitArray)
function map!(f::Union{BitChunkFunctor, typeof(&), typeof(|), typeof($)}, dest::BitArray, A::BitArray, B::BitArray)
size(A) == size(B) == size(dest) || throw(DimensionMismatch("sizes of dest, A, and B must all match"))
isempty(A) && return dest
for i=1:length(A.chunks)-1
Expand Down
1 change: 1 addition & 0 deletions base/bool.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,4 @@ rem(x::Bool, y::Bool) = y ? false : throw(DivideError())
mod(x::Bool, y::Bool) = rem(x,y)

promote_op(op, ::Type{Bool}, ::Type{Bool}) = typeof(op(true, true))
promote_op{T<:Integer}(::typeof(^), ::Type{Bool}, ::Type{T}) = Bool
13 changes: 6 additions & 7 deletions base/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ module Broadcast

using ..Cartesian
using Base: promote_op, promote_eltype, promote_eltype_op, @get!, _msk_end, unsafe_bitgetindex
using Base: AddFun, SubFun, MulFun, LDivFun, RDivFun, PowFun
import Base: .+, .-, .*, ./, .\, .//, .==, .<, .!=, .<=, , .%, .<<, .>>, .^
export broadcast, broadcast!, broadcast_function, broadcast!_function, bitbroadcast
export broadcast_getindex, broadcast_setindex!
Expand Down Expand Up @@ -277,24 +276,24 @@ end
.<<(A::AbstractArray, B::AbstractArray) = broadcast(<<, A, B)
.>>(A::AbstractArray, B::AbstractArray) = broadcast(>>, A, B)

eltype_plus(As::AbstractArray...) = promote_eltype_op(AddFun(), As...)
eltype_plus(As::AbstractArray...) = promote_eltype_op(+, As...)

.+(As::AbstractArray...) = broadcast!(+, Array(eltype_plus(As...), broadcast_shape(As...)), As...)

function .-(A::AbstractArray, B::AbstractArray)
broadcast!(-, Array(promote_op(SubFun(), eltype(A), eltype(B)), broadcast_shape(A,B)), A, B)
broadcast!(-, Array(promote_op(-, eltype(A), eltype(B)), broadcast_shape(A,B)), A, B)
end

eltype_mul(As::AbstractArray...) = promote_eltype_op(MulFun(), As...)
eltype_mul(As::AbstractArray...) = promote_eltype_op(*, As...)

.*(As::AbstractArray...) = broadcast!(*, Array(eltype_mul(As...), broadcast_shape(As...)), As...)

function ./(A::AbstractArray, B::AbstractArray)
broadcast!(/, Array(promote_op(RDivFun(), eltype(A), eltype(B)), broadcast_shape(A, B)), A, B)
broadcast!(/, Array(promote_op(/, eltype(A), eltype(B)), broadcast_shape(A, B)), A, B)
end

function .\(A::AbstractArray, B::AbstractArray)
broadcast!(\, Array(promote_op(LDivFun(), eltype(A), eltype(B)), broadcast_shape(A, B)), A, B)
broadcast!(\, Array(promote_op(\, eltype(A), eltype(B)), broadcast_shape(A, B)), A, B)
end

typealias RatIntT{T<:Integer} Union{Type{Rational{T}},Type{T}}
Expand All @@ -308,7 +307,7 @@ function .//(A::AbstractArray, B::AbstractArray)
end

function .^(A::AbstractArray, B::AbstractArray)
broadcast!(^, Array(promote_op(PowFun(), eltype(A), eltype(B)), broadcast_shape(A, B)), A, B)
broadcast!(^, Array(promote_op(^, eltype(A), eltype(B)), broadcast_shape(A, B)), A, B)
end

## element-wise comparison operators returning BitArray ##
Expand Down
8 changes: 4 additions & 4 deletions base/char.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ length(c::Char) = 1
endof(c::Char) = 1
getindex(c::Char) = c
getindex(c::Char, i::Integer) = i == 1 ? c : throw(BoundsError())
getindex(c::Char, I::Integer...) = all(EqX(1), I) ? c : throw(BoundsError())
getindex(c::Char, I::Integer...) = all(Predicate(x -> x == 1), I) ? c : throw(BoundsError())
first(c::Char) = c
last(c::Char) = c
eltype(::Type{Char}) = Char
Expand All @@ -42,9 +42,9 @@ isless(x::Integer, y::Char) = isless(x, UInt32(y))
+(x::Char, y::Integer) = Char(Int32(x) + Int32(y))
+(x::Integer, y::Char) = y + x

Base.promote_op{I<:Integer}(::Base.SubFun, ::Type{Char}, ::Type{I}) = Char
Base.promote_op{I<:Integer}(::Base.AddFun, ::Type{Char}, ::Type{I}) = Char
Base.promote_op{I<:Integer}(::Base.AddFun, ::Type{I}, ::Type{Char}) = Char
Base.promote_op{I<:Integer}(::typeof(-), ::Type{Char}, ::Type{I}) = Char
Base.promote_op{I<:Integer}(::typeof(+), ::Type{Char}, ::Type{I}) = Char
Base.promote_op{I<:Integer}(::typeof(+), ::Type{I}, ::Type{Char}) = Char

bswap(x::Char) = Char(bswap(UInt32(x)))

Expand Down
1 change: 0 additions & 1 deletion base/coreimg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ include("nofloat_hashing.jl")
macro simd(forloop)
esc(forloop)
end
include("functors.jl")
include("reduce.jl")

## core structures
Expand Down
24 changes: 8 additions & 16 deletions base/dates/arithmetic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -97,26 +97,18 @@ end

# promotion rules

for (op,F) in ((:+, Base.AddFun),
(:-, Base.SubFun),
(:.+, Base.DotAddFun),
(:.-, Base.DotSubFun))
for op in (:+, :-, :.+, :.-)
@eval begin
Base.promote_op{P<:Period}(::$F, ::Type{P}, ::Type{P}) = P
Base.promote_op{P1<:Period,P2<:Period}(::$F, ::Type{P1}, ::Type{P2}) = CompoundPeriod
Base.promote_op{D<:Date}(::$F, ::Type{D}, ::Type{D}) = Day
Base.promote_op{D<:DateTime}(::$F, ::Type{D}, ::Type{D}) = Millisecond
Base.promote_op{P<:Period}(::typeof($op), ::Type{P}, ::Type{P}) = P
Base.promote_op{P1<:Period,P2<:Period}(::typeof($op), ::Type{P1}, ::Type{P2}) = CompoundPeriod
Base.promote_op{D<:Date}(::typeof($op), ::Type{D}, ::Type{D}) = Day
Base.promote_op{D<:DateTime}(::typeof($op), ::Type{D}, ::Type{D}) = Millisecond
end
end

for (op,F) in ((:/, Base.RDivFun),
(:%, Base.RemFun),
(:div, Base.IDivFun),
(:mod, Base.ModFun),
(:./, Base.DotRDivFun),
(:.%, Base.DotRemFun))
for op in (:/, :%, :div, :mod, :./, :.%)
@eval begin
Base.promote_op{P<:Period}(::$F, ::Type{P}, ::Type{P}) = typeof($op(1,1))
Base.promote_op{P<:Period,R<:Real}(::$F, ::Type{P}, ::Type{R}) = P
Base.promote_op{P<:Period}(::typeof($op), ::Type{P}, ::Type{P}) = typeof($op(1,1))
Base.promote_op{P<:Period,R<:Real}(::typeof($op), ::Type{P}, ::Type{R}) = P
end
end
50 changes: 50 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1020,6 +1020,56 @@ function pmap(f, c...; err_retry=nothing, err_stop=nothing, pids=nothing)
return pmap(p, f, c...)
end

# 15692
typealias Func{N} Function
deprecate(:Func)
for (Fun, func) in [(:IdFun, :identity),
(:AbsFun, :abs),
(:Abs2Fun, :abs2),
(:ExpFun, :exp),
(:LogFun, :log),
(:ConjFun, :conj),
(:AndFun, :&),
(:OrFun, :|),
(:XorFun, :$),
(:AddFun, :+),
(:DotAddFun, :.+),
(:SubFun, :-),
(:DotSubFun, :.-),
(:MulFun, :*),
(:DotMulFun, :.*),
(:RDivFun, :/),
(:DotRDivFun, :./),
(:LDivFun, :\),
(:IDivFun, :div),
(:DotIDivFun, :),
(:ModFun, :mod),
(:RemFun, :rem),
(:DotRemFun, :.%),
(:PowFun, :^),
(:MaxFun, :scalarmax),
(:MinFun, :scalarmin),
(:LessFun, :<),
(:MoreFun, :>),
(:DotLSFun, :.<<),
(:DotRSFun, :.>>),
(:ElementwiseMaxFun, :max),
(:ElementwiseMinFun, :min),
(:ComplexFun, :complex),
(:DotFun, :dot),
]
@eval begin
@deprecate_binding $(Fun) typeof($(func))
(::Type{typeof($(func))})() = $(func)
end
end
@deprecate_binding CentralizedAbs2Fun typeof(centralizedabs2fun(0)).name.primary
(::Type{typeof(centralizedabs2fun(0)).name.primary})(m::Number) = centralizedabs2fun(m)
@deprecate specialized_unary(f::Function) f
@deprecate specialized_binary(f::Function) f
@deprecate specialized_bitwise_unary(f::Function) f
@deprecate specialized_bitwise_binary(f::Function) f


# During the 0.5 development cycle, do not add any deprecations below this line
# To be deprecated in 0.6
Expand Down
Loading

0 comments on commit 21a7d4d

Please sign in to comment.