# Why does delete!() work with sets, but not deleteat!()

**URL:** <https://discourse.julialang.org/t/why-does-delete-work-with-sets-but-not-deleteat/48596>\
**Category:** New to Julia\
**Created:** [October 18, 2020, 6:04pm UTC](https://discourse.julialang.org/t/why-does-delete-work-with-sets-but-not-deleteat/48596 "2020-10-18T18:04:58Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![anon60034542](https://avatars.discourse-cdn.com/v4/letter/a/90ced4/32.png) [@anon60034542](https://discourse.julialang.org/u/anon60034542)\
**Post date:** [October 18, 2020, 6:04pm UTC](https://discourse.julialang.org/t/why-does-delete-work-with-sets-but-not-deleteat/48596/1 "2020-10-18T18:04:58Z")

</div>

If I had the following set:

```julia
numbers = Set([1,2,3,4,5])

```

and I do:

```julia
 delete!(3)

```

It will remove the number `3` from the `Set`, but when I use `deleteat!(3)` it throws an error, why?

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [October 18, 2020, 6:05pm UTC](https://discourse.julialang.org/t/why-does-delete-work-with-sets-but-not-deleteat/48596/2 "2020-10-18T18:05:32Z")

</div>

Sets aren’t ordered, so deleting the third element has an undefined meaning.

---

<div class="post-metadata">

**Author:** ![anon60034542](https://avatars.discourse-cdn.com/v4/letter/a/90ced4/32.png) [@anon60034542](https://discourse.julialang.org/u/anon60034542)\
**Post date:** [October 18, 2020, 6:10pm UTC](https://discourse.julialang.org/t/why-does-delete-work-with-sets-but-not-deleteat/48596/3 "2020-10-18T18:10:48Z")

</div>

When I provide `3`, it isn’t the index of `3` but the element `3`, correct? `delete!()` checked if the element existed first and then removed it?

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [October 18, 2020, 6:12pm UTC](https://discourse.julialang.org/t/why-does-delete-work-with-sets-but-not-deleteat/48596/4 "2020-10-18T18:12:48Z")

</div>

`delete(x)` looks for the element `x` and deletes it. `deleteat!(y)` looks for the index `y` and deletes that index and whatever is in it.

---

<div class="post-metadata">

**Author:** ![anon60034542](https://avatars.discourse-cdn.com/v4/letter/a/90ced4/32.png) [@anon60034542](https://discourse.julialang.org/u/anon60034542)\
**Post date:** [October 18, 2020, 6:14pm UTC](https://discourse.julialang.org/t/why-does-delete-work-with-sets-but-not-deleteat/48596/5 "2020-10-18T18:14:17Z")

</div>

Is this also why `pop!()` will return the first element of a `Set` and `Dict`?

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [October 18, 2020, 6:20pm UTC](https://discourse.julialang.org/t/why-does-delete-work-with-sets-but-not-deleteat/48596/6 "2020-10-18T18:20:26Z")

</div>

It is not defined which is the element returned by `pop!(set)`, the function documentation says:

> pop!(collection) → item
> 
> Remove an item in collection and return it. If collection is an ordered container, the last item is returned.

`Set`s are not ordered so it is just defined an element will be removed and returned, not which one. The same applies to `Dict` that is also not an ordered container.

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [October 19, 2020, 11:50am UTC](https://discourse.julialang.org/t/why-does-delete-work-with-sets-but-not-deleteat/48596/7 "2020-10-19T11:50:18Z")

</div>

To me it seems strange that `pop!(::Set)` is even supported. `pop!(::Set, x)` and `pop!(::Set, x, default)`, sure, but IMO `pop!(::Set)` would be better as a `MethodError`.

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [October 19, 2020, 12:11pm UTC](https://discourse.julialang.org/t/why-does-delete-work-with-sets-but-not-deleteat/48596/8 "2020-10-19T12:11:08Z")

</div>

I kind of like being able to get arbitrary elements from a set. There are a lot of graph appropriate, where your need to iterate over everything, but it doesn’t really matter how.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [October 19, 2020, 12:24pm UTC](https://discourse.julialang.org/t/why-does-delete-work-with-sets-but-not-deleteat/48596/9 "2020-10-19T12:24:20Z")

</div>

I agree with Oscar in this one. It is a strange, but valid way of emptying a container one-by-one in the most efficient way. While this is not guaranteed, it seems clear to me that the item removed is the first in the data structure internal layout and, therefore, the easiest arbitrary element to remove (does not need a search).

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [October 19, 2020, 12:28pm UTC](https://discourse.julialang.org/t/why-does-delete-work-with-sets-but-not-deleteat/48596/10 "2020-10-19T12:28:52Z")

</div>

I can see that. I wonder, though, if we should explicitly spell out the converse in the docstring:

```julia
  pop!(collection) -> item

  Remove an item in collection and return it. If collection is an ordered container, the last item is returned.

```

and add “; for unordered containers, an arbitrary element is returned.”

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [October 19, 2020, 12:52pm UTC](https://discourse.julialang.org/t/why-does-delete-work-with-sets-but-not-deleteat/48596/11 "2020-10-19T12:52:52Z")

</div>

Create a PR with @tim.holy suggestion [here](https://github.com/JuliaLang/julia/pull/38097).
