Skip to content

Commit 2c4e353

Browse files
committed
treat dot operators as dot calls, e.g. x .+ y --> (+).(x,y)
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
1 parent 1f8006d commit 2c4e353

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+495
-893
lines changed

NEWS.md

+14-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ New language features
77
Language changes
88
----------------
99

10-
* Multiline and singleline nonstandard command literals have been added. A
10+
* Multi-line and single-line nonstandard command literals have been added. A
1111
nonstandard command literal is like a nonstandard string literal, but the
1212
syntax uses backquotes (``` ` ```) instead of double quotes, and the
1313
resulting macro called is suffixed with `_cmd`. For instance, the syntax
@@ -17,6 +17,11 @@ Language changes
1717
module. For instance, `Base.r"x"` is now parsed as `Base.@r_str "x"`.
1818
Previously, this syntax parsed as an implicit multiplication. ([#18690])
1919

20+
* For every binary operator ``, `a .⨳ b` is now automatically equivalent to
21+
the `broadcast` call `(⨳).(a, b)`. Hence, one no longer defines methods
22+
for `.*` etcetera. This also means that "dot operations" automatically
23+
fuse into a single loop, along with other dot calls `f.(x)`. ([#17623])
24+
2025
Breaking changes
2126
----------------
2227

@@ -34,6 +39,14 @@ This section lists changes that do not have deprecation warnings.
3439
* `broadcast` now handles tuples, and treats any argument that is not a tuple
3540
or an array as a "scalar" ([#16986]).
3641

42+
* `broadcast` now produces a `BitArray` instead of `Array{Bool}` for
43+
functions yielding a boolean result. If you want `Array{Bool}`, use
44+
`broadcast!` or `.=` ([#17623]).
45+
46+
* Operations like `.+` and `.*` on `Range` objects are now generic
47+
`broadcast` calls (see above) and produce an `Array`. If you want
48+
a `Range` result, use `+` and `*`, etcetera ([#17623]).
49+
3750
Library improvements
3851
--------------------
3952

base/LineEdit.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ function splice_buffer!{T<:Integer}(buf::IOBuffer, r::UnitRange{T}, ins::Abstrac
437437
elseif pos > last(r)
438438
seek(buf, pos - length(r))
439439
end
440-
splice!(buf.data, r .+ 1, ins.data) # position(), etc, are 0-indexed
440+
splice!(buf.data, r + 1, ins.data) # position(), etc, are 0-indexed
441441
buf.size = buf.size + sizeof(ins) - length(r)
442442
seek(buf, position(buf) + sizeof(ins))
443443
end

base/abstractarraymath.jl

-9
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,6 @@ imag{T<:Real}(x::AbstractArray{T}) = zero(x)
9191
+{T<:Number}(x::AbstractArray{T}) = x
9292
*{T<:Number}(x::AbstractArray{T,2}) = x
9393

94-
## Binary arithmetic operators ##
95-
96-
*(A::Number, B::AbstractArray) = A .* B
97-
*(A::AbstractArray, B::Number) = A .* B
98-
99-
/(A::AbstractArray, B::Number) = A ./ B
100-
101-
\(A::Number, B::AbstractArray) = B ./ A
102-
10394
# index A[:,:,...,i,:,:,...] where "i" is in dimension "d"
10495

10596
"""

base/arraymath.jl

+10-18
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@ end
6060
promote_array_type(F, ::Type, ::Type, T::Type) = T
6161
promote_array_type{S<:Real, A<:AbstractFloat}(F, ::Type{S}, ::Type{A}, ::Type) = A
6262
promote_array_type{S<:Integer, A<:Integer}(F, ::Type{S}, ::Type{A}, ::Type) = A
63-
promote_array_type{S<:Integer, A<:Integer}(::typeof(./), ::Type{S}, ::Type{A}, T::Type) = T
64-
promote_array_type{S<:Integer, A<:Integer}(::typeof(.\), ::Type{S}, ::Type{A}, T::Type) = T
65-
promote_array_type{S<:Integer}(::typeof(./), ::Type{S}, ::Type{Bool}, T::Type) = T
66-
promote_array_type{S<:Integer}(::typeof(.\), ::Type{S}, ::Type{Bool}, T::Type) = T
63+
promote_array_type{S<:Integer, A<:Integer}(::typeof(/), ::Type{S}, ::Type{A}, T::Type) = T
64+
promote_array_type{S<:Integer, A<:Integer}(::typeof(\), ::Type{S}, ::Type{A}, T::Type) = T
65+
promote_array_type{S<:Integer}(::typeof(/), ::Type{S}, ::Type{Bool}, T::Type) = T
66+
promote_array_type{S<:Integer}(::typeof(\), ::Type{S}, ::Type{Bool}, T::Type) = T
6767
promote_array_type{S<:Integer}(F, ::Type{S}, ::Type{Bool}, T::Type) = T
6868

6969
for f in (:+, :-, :div, :mod, :&, :|, :xor)
@@ -89,9 +89,9 @@ function _elementwise{T}(op, ::Type{T}, A::AbstractArray, B::AbstractArray)
8989
return F
9090
end
9191

92-
for f in (:.+, :.-, :.*, :./, :.\, :.^, :, :.%, :.<<, :.>>, :div, :mod, :rem, :&, :|, :xor)
93-
@eval begin
94-
function ($f){T}(A::Number, B::AbstractArray{T})
92+
for f in (:div, :mod, :rem, :&, :|, :xor, :/, :\, :*, :+, :-)
93+
if f != :/
94+
@eval function ($f){T}(A::Number, B::AbstractArray{T})
9595
R = promote_op($f, typeof(A), T)
9696
S = promote_array_type($f, typeof(A), T, R)
9797
S === Any && return [($f)(A, b) for b in B]
@@ -108,7 +108,9 @@ for f in (:.+, :.-, :.*, :./, :.\, :.^, :.÷, :.%, :.<<, :.>>, :div, :mod, :rem,
108108
end
109109
return F
110110
end
111-
function ($f){T}(A::AbstractArray{T}, B::Number)
111+
end
112+
if f != :\
113+
@eval function ($f){T}(A::AbstractArray{T}, B::Number)
112114
R = promote_op($f, T, typeof(B))
113115
S = promote_array_type($f, typeof(B), T, R)
114116
S === Any && return [($f)(a, B) for a in A]
@@ -128,16 +130,6 @@ for f in (:.+, :.-, :.*, :./, :.\, :.^, :.÷, :.%, :.<<, :.>>, :div, :mod, :rem,
128130
end
129131
end
130132

131-
# familiar aliases for broadcasting operations of array ± scalar (#7226):
132-
(+)(A::AbstractArray{Bool},x::Bool) = A .+ x
133-
(+)(x::Bool,A::AbstractArray{Bool}) = x .+ A
134-
(-)(A::AbstractArray{Bool},x::Bool) = A .- x
135-
(-)(x::Bool,A::AbstractArray{Bool}) = x .- A
136-
(+)(A::AbstractArray,x::Number) = A .+ x
137-
(+)(x::Number,A::AbstractArray) = x .+ A
138-
(-)(A::AbstractArray,x::Number) = A .- x
139-
(-)(x::Number,A::AbstractArray) = x .- A
140-
141133
## data movement ##
142134

143135
function flipdim{T}(A::Array{T}, d::Integer)

base/bitarray.jl

-97
Original file line numberDiff line numberDiff line change
@@ -1136,9 +1136,6 @@ function empty!(B::BitVector)
11361136
return B
11371137
end
11381138

1139-
## Misc functions
1140-
broadcast(::typeof(abs), B::BitArray) = copy(B)
1141-
11421139
## Unary operators ##
11431140

11441141
function (-)(B::BitArray)
@@ -1232,35 +1229,6 @@ for f in (:+, :-)
12321229
end
12331230
end
12341231

1235-
for (f) in (:.+, :.-)
1236-
for (arg1, arg2, T, t) in ((:(B::BitArray), :(x::Bool) , Int , (:b, :x)),
1237-
(:(B::BitArray), :(x::Number) , :(Bool, typeof(x)), (:b, :x)),
1238-
(:(x::Bool) , :(B::BitArray), Int , (:x, :b)),
1239-
(:(x::Number) , :(B::BitArray), :(typeof(x), Bool), (:x, :b)))
1240-
@eval function ($f)($arg1, $arg2)
1241-
$(if T === Int
1242-
quote
1243-
r = Array{Int}(size(B))
1244-
end
1245-
else
1246-
quote
1247-
T = promote_op($f, $(T.args[1]), $(T.args[2]))
1248-
T === Any && return [($f)($(t[1]), $(t[2])) for b in B]
1249-
r = Array{T}(size(B))
1250-
end
1251-
end)
1252-
bi = start(B)
1253-
ri = 1
1254-
while !done(B, bi)
1255-
b, bi = next(B, bi)
1256-
@inbounds r[ri] = ($f)($(t[1]), $(t[2]))
1257-
ri += 1
1258-
end
1259-
return r
1260-
end
1261-
end
1262-
end
1263-
12641232
for f in (:/, :\)
12651233
@eval begin
12661234
($f)(A::BitArray, B::BitArray) = ($f)(Array(A), Array(B))
@@ -1359,71 +1327,6 @@ for f in (:&, :|, :xor)
13591327
end
13601328
end
13611329

1362-
function (.^)(B::BitArray, x::Bool)
1363-
x ? copy(B) : trues(size(B))
1364-
end
1365-
function (.^)(x::Bool, B::BitArray)
1366-
x ? trues(size(B)) : ~B
1367-
end
1368-
function (.^)(x::Number, B::BitArray)
1369-
z = x ^ false
1370-
u = x ^ true
1371-
reshape([ B[i] ? u : z for i = 1:length(B) ], size(B))
1372-
end
1373-
function (.^)(B::BitArray, x::Integer)
1374-
x == 0 && return trues(size(B))
1375-
x < 0 && throw(DomainError())
1376-
return copy(B)
1377-
end
1378-
function (.^){T<:Number}(B::BitArray, x::T)
1379-
x == 0 && return ones(typeof(true ^ x), size(B))
1380-
T <: Real && x > 0 && return convert(Array{T}, B)
1381-
1382-
z = nothing
1383-
u = nothing
1384-
zerr = nothing
1385-
uerr = nothing
1386-
try
1387-
z = false^x
1388-
catch err
1389-
zerr = err
1390-
end
1391-
try
1392-
u = true^x
1393-
catch err
1394-
uerr = err
1395-
end
1396-
if zerr === nothing && uerr === nothing
1397-
t = promote_type(typeof(z), typeof(u))
1398-
elseif zerr === nothing
1399-
t = typeof(z)
1400-
else
1401-
t = typeof(u)
1402-
end
1403-
F = Array{t}(size(B))
1404-
for i = 1:length(B)
1405-
if B[i]
1406-
if uerr === nothing
1407-
F[i] = u
1408-
else
1409-
throw(uerr)
1410-
end
1411-
else
1412-
if zerr === nothing
1413-
F[i] = z
1414-
else
1415-
throw(zerr)
1416-
end
1417-
end
1418-
end
1419-
return F
1420-
end
1421-
1422-
(.*)(x::Bool, B::BitArray) = x & B
1423-
(.*)(B::BitArray, x::Bool) = B & x
1424-
(.*)(x::Number, B::BitArray) = x .* Array(B)
1425-
(.*)(B::BitArray, x::Number) = Array(B) .* x
1426-
14271330
## promotion to complex ##
14281331

14291332
# TODO?

0 commit comments

Comments
 (0)