-
-
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
*(::Number, ::AbstractArray)
calls .*
#11053
Comments
Given only the information Without redesigning the type hierarchy, I think the only thing you can do is define |
Thanks! I'll need to ponder this for a bit. |
Conceptually, it would make sense to me that if a = A(...); b = B(...)
a*b
[a]*b
a*[b]
[a].*[b] and it shouldn't matters what
I think this is (part of) what @jiahao referred to in his post. To make this work, it would somehow be necessary to tag (2) the problem with implementing it: what is the Array-type of But I think, even with above limitations, the current system could be improved on. When To fix this, I think just the definition of the *(A::Number, B::AbstractArray) = A .* B # abstractarray.jl#L445
function (.*){T}(A::Number, B::AbstractArray{T}) # array.jl#L799
F = similar(B, promote_array_type(typeof(A),T))
for i in eachindex(B)
@inbounds F[i] = (.*)(A, B[i])
end
return F
end But |
Another point, if instead of type A
a::Float64
end
.*(a::A, b::Real) = A(a.a*b)
.*(b::Real, a::A) = a.*b now this works:
This also seems backwards. |
Indeed, there is something unsatisfactory about how the dotted operators are defined. The broadcasting operators only make sense on arrays, and they should automatically inherit the meanings of the undotted operators acting on individual elements. |
This should get fixed with #17623, I think. |
Fixed by #17623: julia> import Base.*
julia> type A
a::Float64
end
julia> *(a::A, b::Real) = A(a.a*b)
* (generic function with 165 methods)
julia> *(b::Real, a::A) = a*b
* (generic function with 166 methods)
julia> [A(1)] * 5
1-element Array{A,1}:
A(5.0)
julia> [A(1)] .* 5
1-element Array{A,1}:
A(5.0) |
worth adding that as a test case, if you haven't added anything equivalent yet? |
Is there any reason why we can't add Scalar as a type that numbers, chars, and bools etc are subtypes of? |
No need for a type. Broadcast defaults to treating arguments as "scalar" if they are not arrays etc |
Will add a test case |
syntax deprecation for .op method definitions, and removed these deprecations from Base use range + 1, not range .+ 1, to make sure we call the specialized + method that produces a range (not an array) add depwarn for using .+ etc as function objects support dotted pipe operators eliminate most broadcast(::typeof(func), ...) methods, since fusion makes them ~useless; make broadcast produce a BitArray if a Bool array is expected test for .op loop fusion docs for new broadcasting dot-operator behavior define broadcast! earlier (fixes JuliaLang#18462) use specialized code for non-fusing array ± scalar, for performance work around slight slowdown in Diagonal due to broadcast vs. broadcast_elwise_op closes JuliaLang#11053
This example
fails with
Of course it could be fixed by adding
.*(a::A, b::Real) = a*b
but seems to me that that breaks the abstraction of treatingA
andReal
as scalar like entities. Same goes for other operators.I had a look at the code, relevant definitions feature both in abstracarray.jl https://github.com/JuliaLang/julia/blob/master/base/abstractarray.jl#L445, in array.jl https://github.com/JuliaLang/julia/blob/master/base/array.jl#L799 and https://github.com/JuliaLang/julia/blob/master/base/operators.jl#L92.
The text was updated successfully, but these errors were encountered: