Skip to content
This repository has been archived by the owner on May 4, 2019. It is now read-only.

Rewrite broadcast() and map() based on lift() #166

Merged
merged 19 commits into from
Jan 23, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update eltype computation code to match Base
These have recently been simplified. map() in Base does not use
the same path as broadcast(), but doing so here is much simpler
and results should be equivalent for consistency anyway.
  • Loading branch information
nalimilan committed Jan 19, 2017
commit 2d8670d6e0b370489d385485c86c95f3dc1b49e0
21 changes: 14 additions & 7 deletions src/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,12 @@ else
const broadcast_indices = broadcast_shape
end

if !isdefined(Base.Broadcast, :ftype) # Julia < 0.6
if VERSION < v"0.6.0-dev" # Old approach needed for inference to work
ftype(f, A) = typeof(f)
ftype(f, A...) = typeof(a -> f(a...))
ftype(T::DataType, A) = Type{T}
ftype(T::DataType, A...) = Type{T}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes in JuliaLang/julia#19421 might be relevant here. Best!

else
using Base.Broadcast: ftype
end

if !isdefined(Base.Broadcast, :ziptype) # Julia < 0.6
if isdefined(Base, :Iterators)
using Base.Iterators: Zip2
else
Expand All @@ -27,8 +23,19 @@ if !isdefined(Base.Broadcast, :ziptype) # Julia < 0.6
ziptype(A) = Tuple{eltype(A)}
ziptype(A, B) = Zip2{Tuple{eltype(A)}, Tuple{eltype(B)}}
@inline ziptype(A, B, C, D...) = Zip{Tuple{eltype(A)}, ziptype(B, C, D...)}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise here, the changes in JuliaLang/julia#19421 might be relevant. Best!


nullable_broadcast_eltype(f, As...) =
_default_eltype(Base.Generator{ziptype(As...), ftype(f, As...)})
else
using Base.Broadcast: ziptype
Base.@pure nullable_eltypestuple(a) = Tuple{eltype(eltype(a))}
Base.@pure nullable_eltypestuple(T::Type) = Tuple{Type{eltype(T)}}
Base.@pure nullable_eltypestuple(a, b...) =
Tuple{nullable_eltypestuple(a).types..., nullable_eltypestuple(b...).types...}

Base.@pure function nullable_broadcast_eltype(f, As...)
T = Core.Inference.return_type(f, nullable_eltypestuple(As...))
T === Union{} ? Any : T
end
end

invoke_broadcast!{F, N}(f::F, dest, As::Vararg{NullableArray, N}) =
Expand Down Expand Up @@ -57,7 +64,7 @@ function Base.broadcast{F}(f::F, As::NullableArray...)
@inline f2(x1, x2, x3, x4, x5, x6, x7) = lift(f, (x1, x2, x3, x4, x5, x6, x7))
@inline f2(x...) = lift(f, x)

T = _default_eltype(Base.Generator{ziptype(As...), ftype(f2, As...)})
T = nullable_broadcast_eltype(f, As...)
dest = similar(NullableArray{eltype(T)}, broadcast_indices(As...))
invoke_broadcast!(f2, dest, As...)
end
Expand Down
4 changes: 1 addition & 3 deletions src/map.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
using Base: collect_similar, Generator

invoke_map!{F, N}(f::F, dest, As::Vararg{NullableArray, N}) =
invoke(map!, Tuple{F, AbstractArray, Vararg{AbstractArray, N}}, f, dest, As...)

Expand All @@ -26,7 +24,7 @@ function Base.map{F}(f::F, As::NullableArray...)
@inline f2(x1, x2, x3, x4, x5, x6, x7) = lift(f, (x1, x2, x3, x4, x5, x6, x7))
@inline f2(x...) = lift(f, x)

T = _default_eltype(Base.Generator{ziptype(As...), ftype(f2, As...)})
T = nullable_broadcast_eltype(f, As...)
dest = similar(NullableArray{eltype(T)}, size(As[1]))
invoke_map!(f2, dest, As...)
end
Expand Down