TL;DR: currently, push!
and pop!
conflate two different meanings (adding/removing elements to unordered/sorted collections vs. adding elements to the end of Vector
s, Stack
s, Deque
s, etc). These meanings should be split into different functions in Julia 2.0.
Background
DataStructures.jl
implements a number of data structures, including Stack
, Queue
, Deque
, and CircularDeque
, which are meant to be more performant implementations of stacks and queues (and deques) than just using Vector
s.
Stack
, Deque
, and CircularDeque
all use the same functions as base (push!
, pop!
, pushfirst!
, and popfirst!
). Queue
has never been moved over to that interface, and still uses enqueue!
and dequeue!
We’re having a discussion in DataStructures.jl
around moving Queue
to the standard interface.
Currently, we have the following:
Data structure | push! |
pop! |
pushfirst! |
popfirst! |
enqueue! |
dequeue! |
---|---|---|---|---|---|---|
Base |
||||||
Vector | ||||||
Set | ||||||
Dict | ||||||
DataStructures.jl |
||||||
Stack | ||||||
Deque | ||||||
CircularQueue | ||||||
OrderedDict, OrderedSet | ◯ | ◯ | ||||
SortedDict, SortedSet | ||||||
─────────── | ───── | ───── | ───── | ───── | ───── | ───── |
Queue, PriorityQueue (current) | ||||||
Queue, PriorityQueue (DS proposal A) | ||||||
Queue, PriorityQueue (DS proposal B) |
= implemented
◯ = not implemented, but could/should be
────────────────────────────────────────
From this, we can see that push!
and pop!
have two different meanings.
- For unordered and sorted collections, they simply mean to add or remove elements from the collection.
- For every other collection listed, they (necessarily) mean to add or remove elements from the end of the collection, and they carry their traditional meaning.
There are two proposals for the Queue
interface
“DS Proposal A” above suggests that Queue
should be treated like Set
, Dict
, and SortedDict/SortedSet
, (and perhaps Stack
), since there’s only one way to add things to the collection.
“DS Proposal B” above suggests that Queue
should be treated like a Vector
, Deque
, CircularDeque
, (and perhaps OrderedDict
, OrderedSet
, and Stack
), since there’s a distinction as to whether things are added to the front or back of the collection.
Both are valid perspectives, and this suggests that the fact that push!
and pop!
are used for adding/removing elements from unordered and sorted collections should be revisited.
Proposal 1
For Julia 2.0, pop!
and push!
should be deprecated for Dict
s, Set
s (and SortedDict/SortedSet
s), and a separate function for adding/removing elements into unordered or sorted collections should be implemented. Possibilities include:
-
push!(s::Set, elem)
⇒add!(s, elem) # this was the name in Julia 0.1!
insert!(s, elem)
-
pop!(s::Set, elem)
⇒remove!(s, elem)
For delete!
, see item #1 under Notes.
Proposal 2
Switch to GitHub - andyferris/Dictionaries.jl: An alternative interface for dictionaries in Julia, for improved productivity and performance as the main dictionary interface. This would be a much larger discussion, but has the benefit here that push!
and pop!
would not be defined on unordered collections.
Notes
-
delete!(s, elem)
already exists; it returns the updated collection, as opposed topop!
(currently), which returns the removed element:julia> s = Set([1,2,3]) Set([2, 3, 1]) julia> pop!(s) 2 julia> pop!(s,3) 3 julia> delete!(s, 1) Set(Int64[])
References
Original discussion/PR where push!
and pop!
were originally defined on Dict
and Set
:
–
Kevin