Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

broadcasting over scalars should produce a scalar #17318

Merged
merged 2 commits into from
Jul 11, 2016
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
1 change: 1 addition & 0 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1504,6 +1504,7 @@ end

map!{F}(f::F, dest::AbstractArray, As::AbstractArray...) = map_n!(f, dest, As)

map(f) = f()
map(f, iters...) = collect(Generator(f, iters...))

# multi-item push!, unshift! (built on top of type-specific 1-item version)
Expand Down
5 changes: 5 additions & 0 deletions base/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ export broadcast_getindex, broadcast_setindex!

## Broadcasting utilities ##

# fallback routines for broadcasting with no arguments or with scalars
# to just produce a scalar result:
broadcast(f) = f()
broadcast(f, x::Number...) = f(x...)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is ambiguous with

function broadcast(x::Any, i::Union{Integer,Symbol})
(but not detected? cc @timholy) and causes, for example speye(5).(2) to not trigger the deprecation getfield path that it would have meant on 0.4, but instead trigger a MethodError: objects of type SparseMatrixCSC{Float64,Int32} are not callable.

Copy link
Member Author

Choose a reason for hiding this comment

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

Should be a simple matter of adding a more specific deprecation method, yes?

Copy link
Contributor

Choose a reason for hiding this comment

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

is the deprecation method already more specific? integer vs number? or is the union making dispatch pick Number?

Copy link
Member Author

Choose a reason for hiding this comment

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

You're right, the deprecation method seems more specific according to the rules discussed in #16489, but maybe the varargs are confusing things here. @JeffBezanson?

Copy link
Member Author

@stevengj stevengj Aug 3, 2016

Choose a reason for hiding this comment

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

Oh, right, it's turning foo.(1) into broadcast(() -> foo(1)) because the literal gets inlined into the function by compress-fuse, so the deprecation can't be invoked.

Copy link
Member Author

@stevengj stevengj Aug 3, 2016

Choose a reason for hiding this comment

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

Will submit a PR shortly to restore the getfield deprecation.

Copy link
Contributor

Choose a reason for hiding this comment

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

thanks, I was attempting some things and not able to get it to work - d8f4b60 wasn't where I thought bisect would point me


## Calculate the broadcast shape of the arguments, or error if incompatible
# array inputs
broadcast_shape() = ()
Expand Down
4 changes: 4 additions & 0 deletions test/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,10 @@ end
# issue #15689, mapping an abstract type
@test isa(map(Set, Array[[1,2],[3,4]]), Vector{Set{Int}})

# mapping over scalars and empty arguments:
@test map(sin, 1) == sin(1)
@test map(()->1234) == 1234

function test_UInt_indexing(::Type{TestAbstractArray})
A = [1:100...]
_A = Expr(:quote, A)
Expand Down
6 changes: 5 additions & 1 deletion test/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,10 @@ let a = broadcast(Float32, [3, 4, 5])
@test eltype(a) == Float32
end

# broadcasting scalars:
@test sin.(1) == broadcast(sin, 1) == sin(1)
Copy link
Contributor

Choose a reason for hiding this comment

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

test type equality too?

Copy link
Member Author

Choose a reason for hiding this comment

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

will do

@test (()->1234).() == broadcast(()->1234) == 1234

# issue #4883
@test isa(broadcast(tuple, [1 2 3], ["a", "b", "c"]), Matrix{Tuple{Int,String}})
@test isa(broadcast((x,y)->(x==1?1.0:x,y), [1 2 3], ["a", "b", "c"]), Matrix{Tuple{Real,String}})
Expand All @@ -211,5 +215,5 @@ end

# PR 16988
@test Base.promote_op(+, Bool) === Int
@test isa(broadcast(+, true), Array{Int,0})
@test isa(broadcast(+, [true]), Array{Int,1})
@test Base.promote_op(Float64, Bool) === Float64