Skip to content

Commit

Permalink
rename Type* traits to *Style. fixes #25440 (#25555)
Browse files Browse the repository at this point in the history
also rename `HasOrder` to `Ordered` and `ArithmeticOverflows` to
  `ArithmeticWraps`
  • Loading branch information
JeffBezanson authored Jan 15, 2018
1 parent 1c68f8a commit 1a416fb
Show file tree
Hide file tree
Showing 9 changed files with 46 additions and 39 deletions.
2 changes: 1 addition & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ This section lists changes that do not have deprecation warnings.
* `AbstractRange` objects are now considered as equal to other `AbstractArray` objects
by `==` and `isequal` if all of their elements are equal ([#16401]).
This has required changing the hashing algorithm: ranges now use an O(N) fallback
instead of a O(1) specialized method unless they define the `Base.TypeRangeStep`
instead of a O(1) specialized method unless they define the `Base.RangeStepStyle`
trait; see its documentation for details. Types which support subtraction (operator
`-`) must now implement `widen` for hashing to work inside heterogeneous arrays.

Expand Down
2 changes: 1 addition & 1 deletion base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1959,7 +1959,7 @@ end

function hash(a::AbstractArray{T}, h::UInt) where T
# O(1) hashing for types with regular step
if isa(a, AbstractRange) && isa(TypeRangeStep(a), RangeStepRegular)
if isa(a, AbstractRange) && isa(RangeStepStyle(a), RangeStepRegular)
return hash_range(a, h)
end

Expand Down
7 changes: 7 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2727,6 +2727,13 @@ end
@deprecate_binding iteratorsize IteratorSize
@deprecate_binding iteratoreltype IteratorEltype

# issue #25440
@deprecate_binding TypeOrder OrderStyle
@deprecate_binding TypeArithmetic ArithmeticStyle
@deprecate_binding TypeRangeStep RangeStepStyle
@deprecate_binding HasOrder Ordered
@deprecate_binding ArithmeticOverflows ArithmeticWraps

@deprecate search(str::Union{String,SubString}, re::Regex, idx::Integer) findnext(re, str, idx)
@deprecate search(s::AbstractString, r::Regex, idx::Integer) findnext(r, s, idx)
@deprecate search(s::AbstractString, r::Regex) findfirst(r, s)
Expand Down
4 changes: 2 additions & 2 deletions base/multidimensional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ end

function cumsum!(out, v::AbstractVector, dim::Integer)
# we dispatch on the possibility of numerical stability issues
_cumsum!(out, v, dim, TypeArithmetic(eltype(out)))
_cumsum!(out, v, dim, ArithmeticStyle(eltype(out)))
end

function _cumsum!(out, v, dim, ::ArithmeticRounds)
Expand All @@ -745,7 +745,7 @@ end
function _cumsum!(out, v, dim, ::ArithmeticUnknown)
_cumsum!(out, v, dim, ArithmeticRounds())
end
function _cumsum!(out, v, dim, ::TypeArithmetic)
function _cumsum!(out, v, dim, ::ArithmeticStyle)
dim == 1 ? accumulate!(+, out, v) : copyto!(out, v)
end

Expand Down
16 changes: 8 additions & 8 deletions base/range.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ julia> colon(1, 2, 5)
```
"""
colon(start::T, step::T, stop::T) where {T<:AbstractFloat} =
_colon(TypeOrder(T), TypeArithmetic(T), start, step, stop)
_colon(OrderStyle(T), ArithmeticStyle(T), start, step, stop)
colon(start::T, step::T, stop::T) where {T<:Real} =
_colon(TypeOrder(T), TypeArithmetic(T), start, step, stop)
_colon(::HasOrder, ::Any, start::T, step, stop::T) where {T} = StepRange(start, step, stop)
_colon(OrderStyle(T), ArithmeticStyle(T), start, step, stop)
_colon(::Ordered, ::Any, start::T, step, stop::T) where {T} = StepRange(start, step, stop)
# for T<:Union{Float16,Float32,Float64} see twiceprecision.jl
_colon(::HasOrder, ::ArithmeticRounds, start::T, step, stop::T) where {T} =
_colon(::Ordered, ::ArithmeticRounds, start::T, step, stop::T) where {T} =
StepRangeLen(start, step, floor(Int, (stop-start)/step)+1)
_colon(::Any, ::Any, start::T, step, stop::T) where {T} =
StepRangeLen(start, step, floor(Int, (stop-start)/step)+1)
Expand All @@ -57,8 +57,8 @@ end
Construct a range by length, given a starting value and optional step (defaults to 1).
"""
range(a::T, step, len::Integer) where {T} = _range(TypeOrder(T), TypeArithmetic(T), a, step, len)
_range(::HasOrder, ::ArithmeticOverflows, a::T, step::S, len::Integer) where {T,S} =
range(a::T, step, len::Integer) where {T} = _range(OrderStyle(T), ArithmeticStyle(T), a, step, len)
_range(::Ordered, ::ArithmeticWraps, a::T, step::S, len::Integer) where {T,S} =
StepRange{T,S}(a, step, convert(T, a+step*(len-1)))
_range(::Any, ::Any, a::T, step::S, len::Integer) where {T,S} =
StepRangeLen{typeof(a+0*step),T,S}(a, step, len)
Expand All @@ -79,8 +79,8 @@ range(a::AbstractFloat, st::Real, len::Integer) = range(a, float(st), len)

abstract type AbstractRange{T} <: AbstractArray{T,1} end

TypeRangeStep(::Type{<:AbstractRange}) = RangeStepIrregular()
TypeRangeStep(::Type{<:AbstractRange{<:Integer}}) = RangeStepRegular()
RangeStepStyle(::Type{<:AbstractRange}) = RangeStepIrregular()
RangeStepStyle(::Type{<:AbstractRange{<:Integer}}) = RangeStepRegular()

## ordinal ranges

Expand Down
44 changes: 22 additions & 22 deletions base/traits.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,29 @@

## numeric/object traits
# trait for objects that have an ordering
abstract type TypeOrder end
struct HasOrder <: TypeOrder end
struct Unordered <: TypeOrder end
abstract type OrderStyle end
struct Ordered <: OrderStyle end
struct Unordered <: OrderStyle end

TypeOrder(instance) = TypeOrder(typeof(instance))
TypeOrder(::Type{<:Real}) = HasOrder()
TypeOrder(::Type{<:Any}) = Unordered()
OrderStyle(instance) = OrderStyle(typeof(instance))
OrderStyle(::Type{<:Real}) = Ordered()
OrderStyle(::Type{<:Any}) = Unordered()

# trait for objects that support arithmetic
abstract type TypeArithmetic end
struct ArithmeticRounds <: TypeArithmetic end # least significant bits can be lost
struct ArithmeticOverflows <: TypeArithmetic end # most significant bits can be lost
struct ArithmeticUnknown <: TypeArithmetic end
abstract type ArithmeticStyle end
struct ArithmeticRounds <: ArithmeticStyle end # least significant bits can be lost
struct ArithmeticWraps <: ArithmeticStyle end # most significant bits can be lost
struct ArithmeticUnknown <: ArithmeticStyle end

TypeArithmetic(instance) = TypeArithmetic(typeof(instance))
TypeArithmetic(::Type{<:AbstractFloat}) = ArithmeticRounds()
TypeArithmetic(::Type{<:Integer}) = ArithmeticOverflows()
TypeArithmetic(::Type{<:Any}) = ArithmeticUnknown()
ArithmeticStyle(instance) = ArithmeticStyle(typeof(instance))
ArithmeticStyle(::Type{<:AbstractFloat}) = ArithmeticRounds()
ArithmeticStyle(::Type{<:Integer}) = ArithmeticWraps()
ArithmeticStyle(::Type{<:Any}) = ArithmeticUnknown()

# trait for objects that support ranges with regular step
"""
TypeRangeStep(instance)
TypeRangeStep(T::Type)
RangeStepStyle(instance)
RangeStepStyle(T::Type)
Indicate whether an instance or a type supports constructing a range with
a perfectly regular step or not. A regular step means that
Expand All @@ -37,7 +37,7 @@ all(diff(r) .== step(r))
When a type `T` always leads to ranges with regular steps, it should
define the following method:
```julia
Base.TypeRangeStep(::Type{<:AbstractRange{<:T}}) = Base.RangeStepRegular()
Base.RangeStepStyle(::Type{<:AbstractRange{<:T}}) = Base.RangeStepRegular()
```
This will allow [`hash`](@ref) to use an O(1) algorithm for `AbstractRange{T}`
objects instead of the default O(N) algorithm (with N the length of the range).
Expand All @@ -46,14 +46,14 @@ In some cases, whether the step will be regular depends not only on the
element type `T`, but also on the type of the step `S`. In that case, more
specific methods should be defined:
```julia
Base.TypeRangeStep(::Type{<:OrdinalRange{<:T, <:S}}) = Base.RangeStepRegular()
Base.RangeStepStyle(::Type{<:OrdinalRange{<:T, <:S}}) = Base.RangeStepRegular()
```
By default, all range types are assumed to be `RangeStepIrregular`, except
ranges with an element type which is a subtype of `Integer`.
"""
abstract type TypeRangeStep end
struct RangeStepRegular <: TypeRangeStep end # range with regular step
struct RangeStepIrregular <: TypeRangeStep end # range with rounding error
abstract type RangeStepStyle end
struct RangeStepRegular <: RangeStepStyle end # range with regular step
struct RangeStepIrregular <: RangeStepStyle end # range with rounding error

TypeRangeStep(instance) = TypeRangeStep(typeof(instance))
RangeStepStyle(instance) = RangeStepStyle(typeof(instance))
2 changes: 1 addition & 1 deletion stdlib/Dates/src/ranges.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,5 @@ Base.done(r::StepRange{<:TimeType,<:Period}, i::Integer) = length(r) <= i
-(r::AbstractRange{<:TimeType}, x::Period) = (first(r)-x):step(r):(last(r)-x)

# Combinations of types and periods for which the range step is regular
Base.TypeRangeStep(::Type{<:OrdinalRange{<:TimeType, <:FixedPeriod}}) =
Base.RangeStepStyle(::Type{<:OrdinalRange{<:TimeType, <:FixedPeriod}}) =
Base.RangeStepRegular()
4 changes: 2 additions & 2 deletions stdlib/Dates/src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -356,5 +356,5 @@ sleep(time::Period) = sleep(toms(time) / 1000)
Timer(time::Period, repeat::Period=Second(0)) = Timer(toms(time) / 1000, toms(repeat) / 1000)
timedwait(testcb::Function, time::Period) = timedwait(testcb, toms(time) / 1000)

Base.TypeOrder(::Type{<:AbstractTime}) = Base.HasOrder()
Base.TypeArithmetic(::Type{<:AbstractTime}) = Base.ArithmeticOverflows()
Base.OrderStyle(::Type{<:AbstractTime}) = Base.Ordered()
Base.ArithmeticStyle(::Type{<:AbstractTime}) = Base.ArithmeticWraps()
4 changes: 2 additions & 2 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2154,11 +2154,11 @@ end
@test accumulate(op, [10 20 30], 2) == [10 op(10, 20) op(op(10, 20), 30)] == [10 40 110]
end

struct F21666{T <: Base.TypeArithmetic}
struct F21666{T <: Base.ArithmeticStyle}
x::Float32
end

Base.TypeArithmetic(::Type{F21666{T}}) where {T} = T()
Base.ArithmeticStyle(::Type{F21666{T}}) where {T} = T()
Base.:+(x::F, y::F) where {F <: F21666} = F(x.x + y.x)
Float64(x::F21666) = Float64(x.x)
@testset "Exactness of cumsum # 21666" begin
Expand Down

0 comments on commit 1a416fb

Please sign in to comment.