Skip to content

Commit 2dca269

Browse files
author
Andy Ferris
committed
Added `empty
* `empty` returns an `Associative` with no keys, replacing `similar`. * Also `empty(::Tuple) = ()` and `empty(::Array{T}) = T[]`.
1 parent ea34968 commit 2dca269

14 files changed

Lines changed: 87 additions & 28 deletions

NEWS.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,6 +1292,13 @@ Deprecated or removed
12921292
12931293
* `EnvHash` has been renamed to `EnvDict` ([#24167]).
12941294
1295+
* Introduced the `empty` function, the functional pair to `empty!` which returns a new,
1296+
empty container ([#24390]).
1297+
1298+
* `similar(::Associative)` has been deprecated in favor of `empty(::Associative)`, and
1299+
`similar(::Associative, ::Pair{K, V})` has been deprecated in favour of
1300+
`empty(::Associative, K, V)` ([#24390]).
1301+
12951302
Command-line option changes
12961303
---------------------------
12971304

base/abstractarray.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,24 @@ indices of `A`.
566566
similar(f, shape::Tuple) = f(to_shape(shape))
567567
similar(f, dims::DimOrInd...) = similar(f, dims)
568568

569+
"""
570+
empty(v::AbstractVector, [eltype])
571+
572+
Create an empty vector similar to `v`, optionally changing the `eltype`.
573+
574+
# Examples
575+
576+
```jldoctest
577+
julia> empty([1.0, 2.0, 3.0])
578+
0-element Array{Float64,1}
579+
580+
julia> empty([1.0, 2.0, 3.0], String)
581+
0-element Array{String,1}
582+
```
583+
"""
584+
empty(a::AbstractVector) = empty(a, eltype(a))
585+
empty(a::AbstractVector, ::Type{T}) where {T} = Vector{T}()
586+
569587
## from general iterable to any array
570588

571589
function copy!(dest::AbstractArray, src)

base/associative.jl

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,23 @@ This includes arrays, where the keys are the array indices.
136136
"""
137137
pairs(collection) = Generator(=>, keys(collection), values(collection))
138138

139+
"""
140+
empty(a::Associative, [index_type=keytype(a)], [value_type=valtype(a)])
141+
142+
Create an empty `Associative` container which can accept indices of type `index_type` and
143+
values of type `value_type`. The second and third arguments are optional and default to the
144+
input's `keytype` and `valtype`, respectively. (If only one of the two types is specified,
145+
it is assumed to be the `value_type`, and the `index_type` we default to `keytype(a)`).
146+
147+
Custom `Associative` subtypes may choose which specific associative type is best suited to
148+
return for the given index and value types, by specializing on the three-argument signature.
149+
The default is to return an empty `Dict`.
150+
"""
151+
empty(a::Associative) = empty(a, keytype(a), valtype(a))
152+
empty(a::Associative, ::Type{V}) where {V} = empty(a, keytype(a), V) # Note: this is the form which makes sense for `Vector`.
153+
139154
function copy(a::Associative)
140-
b = similar(a)
155+
b = empty(a)
141156
for (k,v) in a
142157
b[k] = v
143158
end
@@ -403,7 +418,7 @@ Dict{Int64,String} with 1 entry:
403418
"""
404419
function filter(f, d::Associative)
405420
# don't just do filter!(f, copy(d)): avoid making a whole copy of d
406-
df = similar(d)
421+
df = empty(d)
407422
try
408423
for (k, v) in d
409424
if f(k => v)
@@ -512,7 +527,7 @@ mutable struct ObjectIdDict <: Associative{Any,Any}
512527
ObjectIdDict(o::ObjectIdDict) = new(copy(o.ht))
513528
end
514529

515-
similar(d::ObjectIdDict) = ObjectIdDict()
530+
empty(d::ObjectIdDict, ::Type{Any}, ::Type{Any}) = ObjectIdDict()
516531

517532
function rehash!(t::ObjectIdDict, newsz = length(t.ht))
518533
t.ht = ccall(:jl_idtable_rehash, Any, (Any, Csize_t), t.ht, newsz)

base/deepcopy.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ function deepcopy_internal(x::Dict, stackdict::ObjectIdDict)
105105
return (stackdict[x] = copy(x))
106106
end
107107

108-
dest = similar(x)
108+
dest = empty(x)
109109
stackdict[x] = dest
110110
for (k, v) in x
111111
dest[deepcopy_internal(k, stackdict)] = deepcopy_internal(v, stackdict)

base/deprecated.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2210,7 +2210,6 @@ end
22102210
@deprecate chol!(x::Number, uplo) chol(x) false
22112211
end
22122212

2213-
22142213
# issue #16307
22152214
@deprecate finalizer(o, f::Function) finalizer(f, o)
22162215
# This misses other callables but they are very rare in the wild
@@ -2221,6 +2220,10 @@ end
22212220
finalizer(f::Ptr{Void}, o::Ptr{Void}) = invoke(finalizer, Tuple{Ptr{Void}, Any}, f, o)
22222221
finalizer(f::Ptr{Void}, o::Function) = invoke(finalizer, Tuple{Ptr{Void}, Any}, f, o)
22232222

2223+
# issue #24019
2224+
@deprecate similar(a::Associative) empty(a)
2225+
@deprecate similar(a::Associative, ::Type{Pair{K,V}}) where {K, V} empty(a, K, V)
2226+
22242227
# END 0.7 deprecations
22252228

22262229
# BEGIN 1.0 deprecations

base/dict.jl

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ mutable struct Dict{K,V} <: Associative{K,V}
107107
new(copy(d.slots), copy(d.keys), copy(d.vals), d.ndel, d.count, d.age,
108108
d.idxfloor, d.maxprobe)
109109
end
110+
function Dict{K, V}(slots, keys, vals, ndel, count, age, idxfloor, maxprobe) where {K, V}
111+
new(slots, keys, vals, ndel, count, age, idxfloor, maxprobe)
112+
end
110113
end
111114
function Dict{K,V}(kv) where V where K
112115
h = Dict{K,V}()
@@ -166,7 +169,7 @@ end
166169
# this is a special case due to (1) allowing both Pairs and Tuples as elements,
167170
# and (2) Pair being invariant. a bit annoying.
168171
function grow_to!(dest::Associative, itr)
169-
out = grow_to!(similar(dest, Pair{Union{},Union{}}), itr, start(itr))
172+
out = grow_to!(empty(dest, Union{}, Union{}), itr, start(itr))
170173
return isempty(out) ? dest : out
171174
end
172175

@@ -176,7 +179,7 @@ function grow_to!(dest::Associative{K,V}, itr, st) where V where K
176179
if isa(k,K) && isa(v,V)
177180
dest[k] = v
178181
else
179-
new = similar(dest, Pair{typejoin(K,typeof(k)), typejoin(V,typeof(v))})
182+
new = empty(dest, typejoin(K,typeof(k)), typejoin(V,typeof(v)))
180183
copy!(new, dest)
181184
new[k] = v
182185
return grow_to!(new, itr, st)
@@ -185,8 +188,7 @@ function grow_to!(dest::Associative{K,V}, itr, st) where V where K
185188
return dest
186189
end
187190

188-
similar(d::Dict{K,V}) where {K,V} = Dict{K,V}()
189-
similar(d::Dict, ::Type{Pair{K,V}}) where {K,V} = Dict{K,V}()
191+
empty(a::Associative, ::Type{K}, ::Type{V}) where {K, V} = Dict{K, V}()
190192

191193
# conversion between Dict types
192194
function convert(::Type{Dict{K,V}},d::Associative) where V where K
@@ -809,12 +811,7 @@ next(::ImmutableDict{K,V}, t) where {K,V} = (Pair{K,V}(t.key, t.value), t.parent
809811
done(::ImmutableDict, t) = !isdefined(t, :parent)
810812
length(t::ImmutableDict) = count(x->true, t)
811813
isempty(t::ImmutableDict) = done(t, start(t))
812-
function similar(t::ImmutableDict)
813-
while isdefined(t, :parent)
814-
t = t.parent
815-
end
816-
return t
817-
end
814+
empty(::ImmutableDict, ::Type{K}, ::Type{V}) where {K, V} = ImmutableDict{K,V}()
818815

819-
_similar_for(c::Dict, ::Type{P}, itr, isz) where {P<:Pair} = similar(c, P)
816+
_similar_for(c::Dict, ::Type{Pair{K,V}}, itr, isz) where {K, V} = empty(c, K, V)
820817
_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"))

base/env.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ variables.
7373
"""
7474
const ENV = EnvDict()
7575

76-
similar(::EnvDict) = Dict{String,String}()
77-
7876
getindex(::EnvDict, k::AbstractString) = access_env(k->throw(KeyError(k)), k)
7977
get(::EnvDict, k::AbstractString, def) = access_env(k->def, k)
8078
get(f::Callable, ::EnvDict, k::AbstractString) = access_env(k->f(), k)

base/exports.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,7 @@ export
651651
deleteat!,
652652
eltype,
653653
empty!,
654+
empty,
654655
endof,
655656
filter!,
656657
filter,

base/pkg/query.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ end
4242

4343
# Specialized copy for the avail argument below because the deepcopy is slow
4444
function availcopy(avail)
45-
new_avail = similar(avail)
45+
new_avail = empty(avail)
4646
for (pkg, vers_avail) in avail
47-
new_vers_avail = similar(vers_avail)
47+
new_vers_avail = empty(vers_avail)
4848
for (version, pkg_avail) in vers_avail
4949
new_vers_avail[version] = copy(pkg_avail)
5050
end

base/tuple.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,3 +328,10 @@ any(x::Tuple{}) = false
328328
any(x::Tuple{Bool}) = x[1]
329329
any(x::Tuple{Bool, Bool}) = x[1]|x[2]
330330
any(x::Tuple{Bool, Bool, Bool}) = x[1]|x[2]|x[3]
331+
332+
"""
333+
empty(x::Tuple)
334+
335+
Returns an empty tuple, `()`.
336+
"""
337+
empty(x::Tuple) = ()

0 commit comments

Comments
 (0)