-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Conversation
cc: @nalimilan |
+1, but see #17053. |
While it would be nice to have a more general mechanism, I'd prefer to merge this so that the |
Sure, let's merge and possibly revise this to use the new trait from #17053 later. Another interesting question: should strings behave like scalars? That's been advocated at #16966 (comment). Again, should not block this PR. |
@@ -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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test type equality too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will do
At least for the purposes of |
Why should it return Otherwise, I agree with this PR. |
I was doing this also as part of #16986. But that tries to be much more general. I agree that at least the simple case for number should work on 0.5. |
I think it would do all of those things. |
@TotalVerb, my feeling was that |
Another reason for this (I could explicitly check for the case where all the arguments are literals, of course, but the inlining behavior is much more consistent if I don't have to special-case this.) |
Okay to merge? cc @JeffBezanson |
These semantics really should be decided by 0.5, because the |
# 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...) |
There was a problem hiding this comment.
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
Line 370 in 2b98dda
function broadcast(x::Any, i::Union{Integer,Symbol}) |
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
.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
This changes
f.(numbers...)
to be equivalent tof(numbers...)
. Rationale:.^
are equivalent to the "non-dot" operator when acting on scalars, and we need to preserve this behavior if we want to change dot operators to usebroadcast
as per Vectorization Roadmap #16285.map(f, numbers...)
already returnedf(numbers...)
, and it is odd forbroadcast
to be different.Also, I made the empty-argument case
f.()
ormap(f)
returnf()
, for much the same reasons. (Previously, this threw an exception for bothmap
andbroadcast
.) Update: This also will give more consistent behavior for inlining literals inf.(args...)
broadcast syntax (see below).