diff --git a/Makefile b/Makefile index e16d620e168f9..e0f1a54bd3040 100644 --- a/Makefile +++ b/Makefile @@ -179,7 +179,7 @@ CORE_SRCS := $(addprefix $(JULIAHOME)/, \ base/abstractarray.jl \ base/array.jl \ base/bool.jl \ - base/associative.jl \ + base/abstractdict.jl \ base/codevalidation.jl \ base/error.jl \ base/essentials.jl \ diff --git a/NEWS.md b/NEWS.md index 7d1277a02dc3a..4b3d8173fced7 100644 --- a/NEWS.md +++ b/NEWS.md @@ -738,6 +738,8 @@ Deprecated or removed * The `sum_kbn` and `cumsum_kbn` functions have been moved to the [KahanSummation](https://github.com/JuliaMath/KahanSummation.jl) package ([#24869]). + * `Associative` has been deprecated in favor of `AbstractDict` ([#??]). + Command-line option changes --------------------------- diff --git a/base/associative.jl b/base/abstractdict.jl similarity index 78% rename from base/associative.jl rename to base/abstractdict.jl index f3719ba65eaac..e8f42bb2c5a53 100644 --- a/base/associative.jl +++ b/base/abstractdict.jl @@ -1,11 +1,11 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -# generic operations on associative collections +# generic operations on dictionaries """ KeyError(key) -An indexing operation into an `Associative` (`Dict`) or `Set` like object tried to access or +An indexing operation into an `AbstractDict` (`Dict`) or `Set` like object tried to access or delete a non-existent element. """ struct KeyError <: Exception @@ -14,9 +14,9 @@ end const secret_table_token = :__c782dbf1cf4d6a2e5e3865d7e95634f2e09b5902__ -haskey(d::Associative, k) = in(k, keys(d)) +haskey(d::AbstractDict, k) = in(k, keys(d)) -function in(p::Pair, a::Associative, valcmp=(==)) +function in(p::Pair, a::AbstractDict, valcmp=(==)) v = get(a,p[1],secret_table_token) if v !== secret_table_token valcmp(v, p[2]) && return true @@ -24,23 +24,23 @@ function in(p::Pair, a::Associative, valcmp=(==)) return false end -function in(p, a::Associative) - error("""Associative collections only contain Pairs; +function in(p, a::AbstractDict) + error("""AbstractDict collections only contain Pairs; Either look for e.g. A=>B instead, or use the `keys` or `values` function if you are looking for a key or value respectively.""") end -function summary(t::Associative) +function summary(t::AbstractDict) n = length(t) return string(typeof(t), " with ", n, (n==1 ? " entry" : " entries")) end -struct KeySet{K, T <: Associative{K}} <: AbstractSet{K} +struct KeySet{K, T <: AbstractDict{K}} <: AbstractSet{K} dict::T end -KeySet(dict::Associative) = KeySet{keytype(dict), typeof(dict)}(dict) +KeySet(dict::AbstractDict) = KeySet{keytype(dict), typeof(dict)}(dict) -struct ValueIterator{T<:Associative} +struct ValueIterator{T<:AbstractDict} dict::T end @@ -78,9 +78,9 @@ return an iterator over the keys. function keys end """ - keys(a::Associative) + keys(a::AbstractDict) -Return an iterator over all keys in an associative collection. +Return an iterator over all keys in a dictionary. `collect(keys(a))` returns an array of keys. Since the keys are stored internally in a hash table, the order in which they are returned may vary. @@ -100,10 +100,10 @@ julia> collect(keys(a)) 'a' ``` """ -keys(a::Associative) = KeySet(a) +keys(a::AbstractDict) = KeySet(a) """ - values(a::Associative) + values(a::AbstractDict) Return an iterator over all values in a collection. `collect(values(a))` returns an array of values. @@ -125,7 +125,7 @@ julia> collect(values(a)) 2 ``` """ -values(a::Associative) = ValueIterator(a) +values(a::AbstractDict) = ValueIterator(a) """ pairs(collection) @@ -136,24 +136,24 @@ This includes arrays, where the keys are the array indices. """ pairs(collection) = Generator(=>, keys(collection), values(collection)) -pairs(a::Associative) = a +pairs(a::AbstractDict) = a """ - empty(a::Associative, [index_type=keytype(a)], [value_type=valtype(a)]) + empty(a::AbstractDict, [index_type=keytype(a)], [value_type=valtype(a)]) -Create an empty `Associative` container which can accept indices of type `index_type` and +Create an empty `AbstractDict` container which can accept indices of type `index_type` and values of type `value_type`. The second and third arguments are optional and default to the input's `keytype` and `valtype`, respectively. (If only one of the two types is specified, it is assumed to be the `value_type`, and the `index_type` we default to `keytype(a)`). -Custom `Associative` subtypes may choose which specific associative type is best suited to +Custom `AbstractDict` subtypes may choose which specific dictionary type is best suited to return for the given index and value types, by specializing on the three-argument signature. The default is to return an empty `Dict`. """ -empty(a::Associative) = empty(a, keytype(a), valtype(a)) -empty(a::Associative, ::Type{V}) where {V} = empty(a, keytype(a), V) # Note: this is the form which makes sense for `Vector`. +empty(a::AbstractDict) = empty(a, keytype(a), valtype(a)) +empty(a::AbstractDict, ::Type{V}) where {V} = empty(a, keytype(a), V) # Note: this is the form which makes sense for `Vector`. -function copy(a::Associative) +function copy(a::AbstractDict) b = empty(a) for (k,v) in a b[k] = v @@ -162,7 +162,7 @@ function copy(a::Associative) end """ - merge!(d::Associative, others::Associative...) + merge!(d::AbstractDict, others::AbstractDict...) Update collection with pairs from the other collections. See also [`merge`](@ref). @@ -182,7 +182,7 @@ Dict{Int64,Int64} with 3 entries: 1 => 4 ``` """ -function merge!(d::Associative, others::Associative...) +function merge!(d::AbstractDict, others::AbstractDict...) for other in others for (k,v) in other d[k] = v @@ -192,7 +192,7 @@ function merge!(d::Associative, others::Associative...) end """ - merge!(combine, d::Associative, others::Associative...) + merge!(combine, d::AbstractDict, others::AbstractDict...) Update collection with pairs from the other collections. Values with the same key will be combined using the @@ -221,7 +221,7 @@ Dict{Int64,Int64} with 3 entries: 1 => 0 ``` """ -function merge!(combine::Function, d::Associative, others::Associative...) +function merge!(combine::Function, d::AbstractDict, others::AbstractDict...) for other in others for (k,v) in other d[k] = haskey(d, k) ? combine(d[k], v) : v @@ -232,7 +232,7 @@ end # very similar to `merge!`, but accepts any iterable and extends code # that would otherwise only use `copy!` with arrays. -function copy!(dest::Union{Associative,AbstractSet}, src) +function copy!(dest::Union{AbstractDict,AbstractSet}, src) for x in src push!(dest, x) end @@ -242,7 +242,7 @@ end """ keytype(type) -Get the key type of an associative collection type. Behaves similarly to [`eltype`](@ref). +Get the key type of an dictionary type. Behaves similarly to [`eltype`](@ref). # Examples ```jldoctest @@ -250,14 +250,14 @@ julia> keytype(Dict(Int32(1) => "foo")) Int32 ``` """ -keytype(::Type{Associative{K,V}}) where {K,V} = K -keytype(a::Associative) = keytype(typeof(a)) -keytype(::Type{A}) where {A<:Associative} = keytype(supertype(A)) +keytype(::Type{AbstractDict{K,V}}) where {K,V} = K +keytype(a::AbstractDict) = keytype(typeof(a)) +keytype(::Type{A}) where {A<:AbstractDict} = keytype(supertype(A)) """ valtype(type) -Get the value type of an associative collection type. Behaves similarly to [`eltype`](@ref). +Get the value type of an dictionary type. Behaves similarly to [`eltype`](@ref). # Examples ```jldoctest @@ -265,12 +265,12 @@ julia> valtype(Dict(Int32(1) => "foo")) String ``` """ -valtype(::Type{Associative{K,V}}) where {K,V} = V -valtype(::Type{A}) where {A<:Associative} = valtype(supertype(A)) -valtype(a::Associative) = valtype(typeof(a)) +valtype(::Type{AbstractDict{K,V}}) where {K,V} = V +valtype(::Type{A}) where {A<:AbstractDict} = valtype(supertype(A)) +valtype(a::AbstractDict) = valtype(typeof(a)) """ - merge(d::Associative, others::Associative...) + merge(d::AbstractDict, others::AbstractDict...) Construct a merged collection from the given collections. If necessary, the types of the resulting collection will be promoted to accommodate the types of @@ -302,11 +302,11 @@ Dict{String,Float64} with 3 entries: "foo" => 0.0 ``` """ -merge(d::Associative, others::Associative...) = +merge(d::AbstractDict, others::AbstractDict...) = merge!(_typeddict(d, others...), others...) """ - merge(combine, d::Associative, others::Associative...) + merge(combine, d::AbstractDict, others::AbstractDict...) Construct a merged collection from the given collections. If necessary, the types of the resulting collection will be promoted to accommodate the types of @@ -332,21 +332,21 @@ Dict{String,Float64} with 3 entries: "foo" => 0.0 ``` """ -merge(combine::Function, d::Associative, others::Associative...) = +merge(combine::Function, d::AbstractDict, others::AbstractDict...) = merge!(combine, _typeddict(d, others...), others...) promoteK(K) = K promoteV(V) = V promoteK(K, d, ds...) = promoteK(promote_type(K, keytype(d)), ds...) promoteV(V, d, ds...) = promoteV(promote_type(V, valtype(d)), ds...) -function _typeddict(d::Associative, others::Associative...) +function _typeddict(d::AbstractDict, others::AbstractDict...) K = promoteK(keytype(d), others...) V = promoteV(valtype(d), others...) Dict{K,V}(d) end """ - filter!(f, d::Associative) + filter!(f, d::AbstractDict) Update `d`, removing elements for which `f` is `false`. The function `f` is passed `key=>value` pairs. @@ -365,11 +365,11 @@ Dict{Int64,String} with 2 entries: 1 => "a" ``` """ -function filter!(f, d::Associative) +function filter!(f, d::AbstractDict) badkeys = Vector{keytype(d)}() try for pair in d - # don't delete!(d, k) here, since associative types + # don't delete!(d, k) here, since dictionary types # may not support mutation during iteration f(pair) || push!(badkeys, pair.first) end @@ -382,7 +382,7 @@ function filter!(f, d::Associative) return d end -function filter_in_one_pass!(f, d::Associative) +function filter_in_one_pass!(f, d::AbstractDict) try for pair in d if !f(pair) @@ -395,12 +395,12 @@ function filter_in_one_pass!(f, d::Associative) return d end -function filter!_dict_deprecation(e, f, d::Associative) +function filter!_dict_deprecation(e, f, d::AbstractDict) if isa(e, MethodError) && e.f === f depwarn("In `filter!(f, dict)`, `f` is now passed a single pair instead of two arguments.", :filter!) badkeys = Vector{keytype(d)}() for (k,v) in d - # don't delete!(d, k) here, since associative types + # don't delete!(d, k) here, since dictionary types # may not support mutation during iteration f(k, v) || push!(badkeys, k) end @@ -414,7 +414,7 @@ function filter!_dict_deprecation(e, f, d::Associative) end """ - filter(f, d::Associative) + filter(f, d::AbstractDict) Return a copy of `d`, removing elements for which `f` is `false`. The function `f` is passed `key=>value` pairs. @@ -431,7 +431,7 @@ Dict{Int64,String} with 1 entry: 1 => "a" ``` """ -function filter(f, d::Associative) +function filter(f, d::AbstractDict) # don't just do filter!(f, copy(d)): avoid making a whole copy of d df = empty(d) try @@ -455,9 +455,9 @@ function filter(f, d::Associative) return df end -eltype(::Type{Associative{K,V}}) where {K,V} = Pair{K,V} +eltype(::Type{AbstractDict{K,V}}) where {K,V} = Pair{K,V} -function isequal(l::Associative, r::Associative) +function isequal(l::AbstractDict, r::AbstractDict) l === r && return true if isa(l,ObjectIdDict) != isa(r,ObjectIdDict) return false @@ -471,7 +471,7 @@ function isequal(l::Associative, r::Associative) true end -function ==(l::Associative, r::Associative) +function ==(l::AbstractDict, r::AbstractDict) l === r && return true if isa(l,ObjectIdDict) != isa(r,ObjectIdDict) return false @@ -486,7 +486,7 @@ function ==(l::Associative, r::Associative) end const hasha_seed = UInt === UInt64 ? 0x6d35bb51952d5539 : 0x952d5539 -function hash(a::Associative, h::UInt) +function hash(a::AbstractDict, h::UInt) hv = hasha_seed for (k,v) in a hv ⊻= hash(k, hash(v)) @@ -494,7 +494,7 @@ function hash(a::Associative, h::UInt) hash(hv, h) end -function getindex(t::Associative, key) +function getindex(t::AbstractDict, key) v = get(t, key, secret_table_token) if v === secret_table_token throw(KeyError(key)) @@ -504,12 +504,12 @@ end # t[k1,k2,ks...] is syntactic sugar for t[(k1,k2,ks...)]. (Note # that we need to avoid dispatch loops if setindex!(t,v,k) is not defined.) -getindex(t::Associative, k1, k2, ks...) = getindex(t, tuple(k1,k2,ks...)) -setindex!(t::Associative, v, k1, k2, ks...) = setindex!(t, v, tuple(k1,k2,ks...)) +getindex(t::AbstractDict, k1, k2, ks...) = getindex(t, tuple(k1,k2,ks...)) +setindex!(t::AbstractDict, v, k1, k2, ks...) = setindex!(t, v, tuple(k1,k2,ks...)) -push!(t::Associative, p::Pair) = setindex!(t, p.second, p.first) -push!(t::Associative, p::Pair, q::Pair) = push!(push!(t, p), q) -push!(t::Associative, p::Pair, q::Pair, r::Pair...) = push!(push!(push!(t, p), q), r...) +push!(t::AbstractDict, p::Pair) = setindex!(t, p.second, p.first) +push!(t::AbstractDict, p::Pair, q::Pair) = push!(push!(t, p), q) +push!(t::AbstractDict, p::Pair, q::Pair, r::Pair...) = push!(push!(push!(t, p), q), r...) # hashing objects by identity @@ -522,7 +522,7 @@ and value type and thus its `eltype` is always `Pair{Any,Any}`. See [`Dict`](@ref) for further help. """ -mutable struct ObjectIdDict <: Associative{Any,Any} +mutable struct ObjectIdDict <: AbstractDict{Any,Any} ht::Vector{Any} ndel::Int ObjectIdDict() = new(Vector{Any}(uninitialized, 32), 0) @@ -613,6 +613,6 @@ copy(o::ObjectIdDict) = ObjectIdDict(o) get!(o::ObjectIdDict, key, default) = (o[key] = get(o, key, default)) -# For some Associative types, it is safe to implement filter! +# For some AbstractDict types, it is safe to implement filter! # by deleting keys during iteration. filter!(f, d::ObjectIdDict) = filter_in_one_pass!(f, d) diff --git a/base/array.jl b/base/array.jl index 083e4a4323f7f..74801cef5c50b 100644 --- a/base/array.jl +++ b/base/array.jl @@ -70,7 +70,7 @@ const DenseVecOrMat{T} = Union{DenseVector{T}, DenseMatrix{T}} eltype(type) Determine the type of the elements generated by iterating a collection of the given `type`. -For associative collection types, this will be a `Pair{KeyType,ValType}`. The definition +For dictionary types, this will be a `Pair{KeyType,ValType}`. The definition `eltype(x) = eltype(typeof(x))` is provided for convenience so that instances can be passed instead of types. However the form that accepts a type argument should be defined for new types. @@ -451,7 +451,7 @@ _similar_for(c, T, itr, isz) = similar(c, T) """ collect(collection) -Return an `Array` of all items in a collection or iterator. For associative collections, returns +Return an `Array` of all items in a collection or iterator. For dictionaries, returns `Pair{KeyType, ValType}`. If the argument is array-like or is an iterator with the `HasShape()` trait, the result will have the same shape and number of dimensions as the argument. diff --git a/base/coreimg.jl b/base/coreimg.jl index 10b56c1f8b063..11e29947b5be2 100644 --- a/base/coreimg.jl +++ b/base/coreimg.jl @@ -56,7 +56,7 @@ include("reduce.jl") ## core structures include("bitarray.jl") include("bitset.jl") -include("associative.jl") +include("abstractdict.jl") include("namedtuple.jl") # core docsystem diff --git a/base/deprecated.jl b/base/deprecated.jl index 68960bb291104..4346cdc6b818c 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -1528,7 +1528,7 @@ export hex2num # remove code for `importall` in src/ # issue #17886 -# deprecations for filter[!] with 2-arg functions are in associative.jl +# deprecations for filter[!] with 2-arg functions are in abstractdict.jl # PR #23066 @deprecate cfunction(f, r, a::Tuple) cfunction(f, r, Tuple{a...}) @@ -1608,7 +1608,7 @@ import .Iterators.enumerate @deprecate_binding Range AbstractRange # issue #5794 -@deprecate map(f, d::T) where {T<:Associative} T( f(p) for p in pairs(d) ) +@deprecate map(f, d::T) where {T<:AbstractDict} T( f(p) for p in pairs(d) ) # issue #17086 @deprecate isleaftype isconcrete @@ -2172,8 +2172,8 @@ end @deprecate merge!(repo::LibGit2.GitRepo, args...; kwargs...) LibGit2.merge!(repo, args...; kwargs...) # issue #24019 -@deprecate similar(a::Associative) empty(a) -@deprecate similar(a::Associative, ::Type{Pair{K,V}}) where {K, V} empty(a, K, V) +@deprecate similar(a::AbstractDict) empty(a) +@deprecate similar(a::AbstractDict, ::Type{Pair{K,V}}) where {K, V} empty(a, K, V) # PR #24594 @eval LibGit2 begin @@ -2186,6 +2186,9 @@ end @deprecate_moved sum_kbn "KahanSummation" @deprecate_moved cumsum_kbn "KahanSummation" +# Associative -> AbstractDict (#??) +@deprecate_binding Associative AbstractDict + # END 0.7 deprecations # BEGIN 1.0 deprecations diff --git a/base/dict.jl b/base/dict.jl index bd3ac41287e55..9a84ed011b5d9 100644 --- a/base/dict.jl +++ b/base/dict.jl @@ -23,7 +23,7 @@ function _truncate_at_width_or_chars(str, width, chars="", truncmark="…") end end -function show(io::IO, t::Associative{K,V}) where V where K +function show(io::IO, t::AbstractDict{K,V}) where V where K recur_io = IOContext(io, :SHOWN_SET => t) limit::Bool = get(io, :limit, false) if !haskey(io, :compact) @@ -89,7 +89,7 @@ Dict{String,Int64} with 2 entries: "A" => 1 ``` """ -mutable struct Dict{K,V} <: Associative{K,V} +mutable struct Dict{K,V} <: AbstractDict{K,V} slots::Array{UInt8,1} keys::Array{K,1} vals::Array{V,1} @@ -141,7 +141,7 @@ Dict(ps::Pair...) = Dict{Any,Any}(ps) function Dict(kv) try - associative_with_eltype((K, V) -> Dict{K, V}, kv, eltype(kv)) + dict_with_eltype((K, V) -> Dict{K, V}, kv, eltype(kv)) catch e if !applicable(start, kv) || !all(x->isa(x,Union{Tuple,Pair}),kv) throw(ArgumentError("Dict(kv): kv needs to be an iterator of tuples or pairs")) @@ -153,27 +153,27 @@ end TP{K,V} = Union{Type{Tuple{K,V}},Type{Pair{K,V}}} -associative_with_eltype(DT_apply, kv, ::TP{K,V}) where {K,V} = DT_apply(K, V)(kv) -associative_with_eltype(DT_apply, kv::Generator, ::TP{K,V}) where {K,V} = DT_apply(K, V)(kv) -associative_with_eltype(DT_apply, ::Type{Pair{K,V}}) where {K,V} = DT_apply(K, V)() -associative_with_eltype(DT_apply, ::Type) = DT_apply(Any, Any)() -associative_with_eltype(DT_apply::F, kv, t) where {F} = grow_to!(associative_with_eltype(DT_apply, @default_eltype(typeof(kv))), kv) -function associative_with_eltype(DT_apply::F, kv::Generator, t) where F +dict_with_eltype(DT_apply, kv, ::TP{K,V}) where {K,V} = DT_apply(K, V)(kv) +dict_with_eltype(DT_apply, kv::Generator, ::TP{K,V}) where {K,V} = DT_apply(K, V)(kv) +dict_with_eltype(DT_apply, ::Type{Pair{K,V}}) where {K,V} = DT_apply(K, V)() +dict_with_eltype(DT_apply, ::Type) = DT_apply(Any, Any)() +dict_with_eltype(DT_apply::F, kv, t) where {F} = grow_to!(dict_with_eltype(DT_apply, @default_eltype(typeof(kv))), kv) +function dict_with_eltype(DT_apply::F, kv::Generator, t) where F T = @default_eltype(typeof(kv)) if T <: Union{Pair, Tuple{Any, Any}} && _isleaftype(T) - return associative_with_eltype(DT_apply, kv, T) + return dict_with_eltype(DT_apply, kv, T) end - return grow_to!(associative_with_eltype(DT_apply, T), kv) + return grow_to!(dict_with_eltype(DT_apply, T), kv) end # this is a special case due to (1) allowing both Pairs and Tuples as elements, # and (2) Pair being invariant. a bit annoying. -function grow_to!(dest::Associative, itr) +function grow_to!(dest::AbstractDict, itr) out = grow_to!(empty(dest, Union{}, Union{}), itr, start(itr)) return isempty(out) ? dest : out end -function grow_to!(dest::Associative{K,V}, itr, st) where V where K +function grow_to!(dest::AbstractDict{K,V}, itr, st) where V where K while !done(itr, st) (k,v), st = next(itr, st) if isa(k,K) && isa(v,V) @@ -188,10 +188,10 @@ function grow_to!(dest::Associative{K,V}, itr, st) where V where K return dest end -empty(a::Associative, ::Type{K}, ::Type{V}) where {K, V} = Dict{K, V}() +empty(a::AbstractDict, ::Type{K}, ::Type{V}) where {K, V} = Dict{K, V}() # conversion between Dict types -function convert(::Type{Dict{K,V}},d::Associative) where V where K +function convert(::Type{Dict{K,V}},d::AbstractDict) where V where K h = Dict{K,V}() for (k,v) in d ck = convert(K,k) @@ -727,7 +727,7 @@ end filter!(f, d::Dict) = filter_in_one_pass!(f, d) -struct ImmutableDict{K,V} <: Associative{K,V} +struct ImmutableDict{K,V} <: AbstractDict{K,V} parent::ImmutableDict{K,V} key::K value::V @@ -799,4 +799,4 @@ isempty(t::ImmutableDict) = done(t, start(t)) empty(::ImmutableDict, ::Type{K}, ::Type{V}) where {K, V} = ImmutableDict{K,V}() _similar_for(c::Dict, ::Type{Pair{K,V}}, itr, isz) where {K, V} = empty(c, K, V) -_similar_for(c::Associative, T, itr, isz) = throw(ArgumentError("for Associatives, similar requires an element type of Pair;\n if calling map, consider a comprehension instead")) +_similar_for(c::AbstractDict, T, itr, isz) = throw(ArgumentError("for AbstractDicts, similar requires an element type of Pair;\n if calling map, consider a comprehension instead")) diff --git a/base/env.jl b/base/env.jl index e7849373e308f..cf3b647ab1e6b 100644 --- a/base/env.jl +++ b/base/env.jl @@ -63,7 +63,7 @@ end # os test A singleton of this type provides a hash table interface to environment variables. """ -struct EnvDict <: Associative{String,String}; end +struct EnvDict <: AbstractDict{String,String}; end """ ENV diff --git a/base/essentials.jl b/base/essentials.jl index 8271e315c5fae..bf095d5410f7b 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -7,7 +7,7 @@ const Callable = Union{Function,Type} const Bottom = Union{} abstract type AbstractSet{T} end -abstract type Associative{K,V} end +abstract type AbstractDict{K,V} end # The real @inline macro is not available until after array.jl, so this # internal macro splices the meta Expr directly into the function body. diff --git a/base/exports.jl b/base/exports.jl index ed3f5d2b34b49..6c5cdf45d2d1b 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -30,7 +30,7 @@ export AbstractVector, AbstractVecOrMat, Array, - Associative, + AbstractDict, Bidiagonal, BigFloat, BigInt, diff --git a/base/process.jl b/base/process.jl index 0d56aaee5b2f1..33b978789106f 100644 --- a/base/process.jl +++ b/base/process.jl @@ -207,7 +207,7 @@ end # convert various env representations into an array of "key=val" strings byteenv(env::AbstractArray{<:AbstractString}) = String[cstr(x) for x in env] -byteenv(env::Associative) = +byteenv(env::AbstractDict) = String[cstr(string(k)*"="*string(v)) for (k,v) in env] byteenv(env::Void) = nothing byteenv(env::Union{AbstractVector{Pair{T}}, Tuple{Vararg{Pair{T}}}}) where {T<:AbstractString} = diff --git a/base/random/generation.jl b/base/random/generation.jl index 29b0b4891ce93..00771a8536637 100644 --- a/base/random/generation.jl +++ b/base/random/generation.jl @@ -281,18 +281,18 @@ function rand(rng::AbstractRNG, sp::SamplerSimple{BitSet,<:Sampler}) end end -## random values from Associative/AbstractSet +## random values from AbstractDict/AbstractSet # we defer to _Sampler to avoid ambiguities with a call like Sampler(rng, Set(1), Val(1)) -Sampler(rng::AbstractRNG, t::Union{Associative,AbstractSet}, n::Repetition) = +Sampler(rng::AbstractRNG, t::Union{AbstractDict,AbstractSet}, n::Repetition) = _Sampler(rng, t, n) # avoid linear complexity for repeated calls -_Sampler(rng::AbstractRNG, t::Union{Associative,AbstractSet}, n::Val{Inf}) = +_Sampler(rng::AbstractRNG, t::Union{AbstractDict,AbstractSet}, n::Val{Inf}) = Sampler(rng, collect(t), n) # when generating only one element, avoid the call to collect -_Sampler(::AbstractRNG, t::Union{Associative,AbstractSet}, ::Val{1}) = +_Sampler(::AbstractRNG, t::Union{AbstractDict,AbstractSet}, ::Val{1}) = SamplerTrivial(t) function nth(iter, n::Integer)::eltype(iter) @@ -301,7 +301,7 @@ function nth(iter, n::Integer)::eltype(iter) end end -rand(rng::AbstractRNG, sp::SamplerTrivial{<:Union{Associative,AbstractSet}}) = +rand(rng::AbstractRNG, sp::SamplerTrivial{<:Union{AbstractDict,AbstractSet}}) = nth(sp[], rand(rng, 1:length(sp[]))) diff --git a/base/random/random.jl b/base/random/random.jl index fe082fdd495d7..643e122d69b0d 100644 --- a/base/random/random.jl +++ b/base/random/random.jl @@ -177,7 +177,7 @@ Pick a random element or array of random elements from the set of values specifi `S` can be * an indexable collection (for example `1:n` or `['x','y','z']`), -* an `Associative` or `AbstractSet` object, +* an `AbstractDict` or `AbstractSet` object, * a string (considered as a collection of characters), or * a type: the set of values to pick from is then equivalent to `typemin(S):typemax(S)` for integers (this is not applicable to [`BigInt`](@ref)), and to ``[0, 1)`` for floating @@ -197,7 +197,7 @@ julia> rand(MersenneTwister(0), Dict(1=>2, 3=>4)) ``` !!! note - The complexity of `rand(rng, s::Union{Associative,AbstractSet})` + The complexity of `rand(rng, s::Union{AbstractDict,AbstractSet})` is linear in the length of `s`, unless an optimized method with constant complexity is available, which is the case for `Dict`, `Set` and `BitSet`. For more than a few calls, use `rand(rng, diff --git a/base/repl/REPLCompletions.jl b/base/repl/REPLCompletions.jl index 3e5056d613f26..9743aaba87d06 100644 --- a/base/repl/REPLCompletions.jl +++ b/base/repl/REPLCompletions.jl @@ -464,7 +464,7 @@ function dict_identifier_key(str,tag) begin_of_key = first(search(str, r"\S", nextind(str, end_of_identifier) + 1)) # 1 for [ begin_of_key==0 && return (true, nothing, nothing) partial_key = str[begin_of_key:end] - (isa(obj, Associative) && length(obj) < 1e6) || return (true, nothing, nothing) + (isa(obj, AbstractDict) && length(obj) < 1e6) || return (true, nothing, nothing) return (obj, partial_key, begin_of_key) end diff --git a/base/replutil.jl b/base/replutil.jl index 65a72b0864007..afaef1312c5df 100644 --- a/base/replutil.jl +++ b/base/replutil.jl @@ -34,7 +34,7 @@ function show(io::IO, ::MIME"text/plain", iter::Union{KeySet,ValueIterator}) end end -function show(io::IO, ::MIME"text/plain", t::Associative{K,V}) where {K,V} +function show(io::IO, ::MIME"text/plain", t::AbstractDict{K,V}) where {K,V} # show more descriptively, with one line per key/value pair recur_io = IOContext(io, :SHOWN_SET => t) limit::Bool = get(io, :limit, false) diff --git a/base/sparse/sparsevector.jl b/base/sparse/sparsevector.jl index 4cb4f3ce8f3b7..f7a0b84c4e445 100644 --- a/base/sparse/sparsevector.jl +++ b/base/sparse/sparsevector.jl @@ -237,7 +237,7 @@ julia> sparsevec(Dict(1 => 3, 2 => 2)) [2] = 2 ``` """ -function sparsevec(dict::Associative{Ti,Tv}) where {Tv,Ti<:Integer} +function sparsevec(dict::AbstractDict{Ti,Tv}) where {Tv,Ti<:Integer} m = length(dict) nzind = Vector{Ti}(uninitialized, m) nzval = Vector{Tv}(uninitialized, m) @@ -258,7 +258,7 @@ function sparsevec(dict::Associative{Ti,Tv}) where {Tv,Ti<:Integer} _sparsevector!(nzind, nzval, len) end -function sparsevec(dict::Associative{Ti,Tv}, len::Integer) where {Tv,Ti<:Integer} +function sparsevec(dict::AbstractDict{Ti,Tv}, len::Integer) where {Tv,Ti<:Integer} m = length(dict) nzind = Vector{Ti}(uninitialized, m) nzval = Vector{Tv}(uninitialized, m) diff --git a/base/sysimg.jl b/base/sysimg.jl index 7204750b00d85..959d84be659cc 100644 --- a/base/sysimg.jl +++ b/base/sysimg.jl @@ -147,7 +147,7 @@ Matrix(::Uninitialized, m::Integer, n::Integer) = Matrix{Any}(uninitialized, Int Vector() = Vector{Any}(uninitialized, 0) -include("associative.jl") +include("abstractdict.jl") include("namedtuple.jl") diff --git a/base/weakkeydict.jl b/base/weakkeydict.jl index f07d2f29f5ea0..ecda0680dda10 100644 --- a/base/weakkeydict.jl +++ b/base/weakkeydict.jl @@ -11,7 +11,7 @@ referenced in a hash table. See [`Dict`](@ref) for further help. """ -mutable struct WeakKeyDict{K,V} <: Associative{K,V} +mutable struct WeakKeyDict{K,V} <: AbstractDict{K,V} ht::Dict{WeakRef,V} lock::Threads.RecursiveSpinLock finalizer::Function @@ -58,7 +58,7 @@ WeakKeyDict(ps::Pair...) = WeakKeyDict{Any,Any}(ps) function WeakKeyDict(kv) try - Base.associative_with_eltype((K, V) -> WeakKeyDict{K, V}, kv, eltype(kv)) + Base.dict_with_eltype((K, V) -> WeakKeyDict{K, V}, kv, eltype(kv)) catch e if !applicable(start, kv) || !all(x->isa(x,Union{Tuple,Pair}),kv) throw(ArgumentError("WeakKeyDict(kv): kv needs to be an iterator of tuples or pairs")) @@ -71,7 +71,7 @@ end empty(d::WeakKeyDict, ::Type{K}, ::Type{V}) where {K, V} = WeakKeyDict{K, V}() # conversion between Dict types -function convert(::Type{WeakKeyDict{K,V}},d::Associative) where V where K +function convert(::Type{WeakKeyDict{K,V}},d::AbstractDict) where V where K h = WeakKeyDict{K,V}() for (k,v) in d ck = convert(K,k) diff --git a/doc/src/stdlib/collections.md b/doc/src/stdlib/collections.md index 8b5d9ede0d572..43c3a360072ec 100644 --- a/doc/src/stdlib/collections.md +++ b/doc/src/stdlib/collections.md @@ -160,9 +160,9 @@ Partially implemented by: * [`ObjectIdDict`](@ref) * [`WeakKeyDict`](@ref) -## Associative Collections +## Dictionaries -[`Dict`](@ref) is the standard associative collection. Its implementation uses [`hash`](@ref) +[`Dict`](@ref) is the standard dictionary. Its implementation uses [`hash`](@ref) as the hashing function for the key, and [`isequal`](@ref) to determine equality. Define these two functions for custom types to override how they are stored in a hash table. @@ -176,7 +176,7 @@ constructor: `Dict("A"=>1, "B"=>2)`. This call will attempt to infer type inform keys and values (i.e. this example creates a `Dict{String, Int64}`). To explicitly specify types use the syntax `Dict{KeyType,ValueType}(...)`. For example, `Dict{String,Int32}("A"=>1, "B"=>2)`. -Associative collections may also be created with generators. For example, `Dict(i => f(i) for i = 1:10)`. +Dictionaries may also be created with generators. For example, `Dict(i => f(i) for i = 1:10)`. Given a dictionary `D`, the syntax `D[x]` returns the value of key `x` (if it exists) or throws an error, and `D[x] = y` stores the key-value pair `x => y` in `D` (replacing any existing value diff --git a/examples/lru.jl b/examples/lru.jl index 7063a3387e735..404c90590e16b 100644 --- a/examples/lru.jl +++ b/examples/lru.jl @@ -25,7 +25,7 @@ import Base.haskey, Base.get import Base.setindex!, Base.getindex, Base.delete!, Base.empty! import Base.show -abstract type LRU{K,V} <: Associative{K,V} end +abstract type LRU{K,V} <: AbstractDict{K,V} end # Default cache size const __MAXCACHE = 1024 diff --git a/stdlib/Test/src/Test.jl b/stdlib/Test/src/Test.jl index 916834c42bf3b..ab0b352b69deb 100644 --- a/stdlib/Test/src/Test.jl +++ b/stdlib/Test/src/Test.jl @@ -1413,15 +1413,15 @@ end """ The `GenericDict` can be used to test generic dict APIs that program to -the `Associative` interface, in order to ensure that functions can work +the `AbstractDict` interface, in order to ensure that functions can work with associative types besides the standard `Dict` type. """ -struct GenericDict{K,V} <: Associative{K,V} - s::Associative{K,V} +struct GenericDict{K,V} <: AbstractDict{K,V} + s::AbstractDict{K,V} end for (G, A) in ((GenericSet, AbstractSet), - (GenericDict, Associative)) + (GenericDict, AbstractDict)) @eval begin Base.convert(::Type{$G}, s::$A) = $G(s) Base.done(s::$G, state) = done(s.s, state) diff --git a/test/dict.jl b/test/dict.jl index 7212022e51ea4..b7c65ed5e8b9a 100644 --- a/test/dict.jl +++ b/test/dict.jl @@ -170,7 +170,7 @@ end @testset "issue #2344" begin local bar bestkey(d, key) = key - bestkey(d::Associative{K,V}, key) where {K<:AbstractString,V} = string(key) + bestkey(d::AbstractDict{K,V}, key) where {K<:AbstractString,V} = string(key) bar(x) = bestkey(x, :y) @test bar(Dict(:x => [1,2,5])) == :y @test bar(Dict("x" => [1,2,5])) == "y" @@ -305,7 +305,7 @@ end end end -@testset "Issue #15739" begin # Compact REPL printouts of an `Associative` use brackets when appropriate +@testset "Issue #15739" begin # Compact REPL printouts of an `AbstractDict` use brackets when appropriate d = Dict((1=>2) => (3=>45), (3=>10) => (10=>11)) buf = IOBuffer() showcompact(buf, d) @@ -526,7 +526,7 @@ end d = Dict(zip(1:1000,1:1000)) f = p -> iseven(p.first) @test filter(f, d) == filter!(f, copy(d)) == - invoke(filter!, Tuple{Function,Associative}, f, copy(d)) == + invoke(filter!, Tuple{Function,AbstractDict}, f, copy(d)) == Dict(zip(2:2:1000, 2:2:1000)) end diff --git a/test/replcompletions.jl b/test/replcompletions.jl index 9698b1622fdf9..a941a417aeff2 100644 --- a/test/replcompletions.jl +++ b/test/replcompletions.jl @@ -21,8 +21,8 @@ let ex = quote :() end - # Support non-Dict Associatives, #19441 - mutable struct CustomDict{K, V} <: Associative{K, V} + # Support non-Dict AbstractDicts, #19441 + mutable struct CustomDict{K, V} <: AbstractDict{K, V} mydict::Dict{K, V} end diff --git a/test/subtype.jl b/test/subtype.jl index a9d41836c084f..ae89341f57a69 100644 --- a/test/subtype.jl +++ b/test/subtype.jl @@ -902,7 +902,7 @@ function test_intersection() @test length(E)==1 && isa(E[1],TypeVar) @testintersect(Tuple{Dict{Int,Int}, Ref{Pair{K,V}}} where V where K, - Tuple{Associative{Int,Int}, Ref{Pair{T,T}} where T}, + Tuple{AbstractDict{Int,Int}, Ref{Pair{T,T}} where T}, Tuple{Dict{Int,Int}, Ref{Pair{K,K}}} where K) # issue #20643