# Concerning \`AbstractDict\` inheritance and \`push!\`, is Base wrong?

**URL:** <https://discourse.julialang.org/t/concerning-abstractdict-inheritance-and-push-is-base-wrong/25082>\
**Category:** New to Julia\
**Created:** [June 8, 2019, 8:29pm UTC](https://discourse.julialang.org/t/concerning-abstractdict-inheritance-and-push-is-base-wrong/25082 "2019-06-08T20:29:32Z")\
**Posts on this page:** 3\
**Page:** 1

<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:** [June 8, 2019, 8:29pm UTC](https://discourse.julialang.org/t/concerning-abstractdict-inheritance-and-push-is-base-wrong/25082/1 "2019-06-08T20:29:32Z")

</div>

I am implementing an struct that inherit `AbstractDict`.  
To reduce the effort needed for a first working implementation I decided to let many methods to be defined by the fallback methods in [abstracdict.jl](https://github.com/JuliaLang/julia/blob/master/base/abstractdict.jl).

`push!` would be one of these methods, as it is defined in terms of `setindex!` at [line 479](https://github.com/JuliaLang/julia/blob/70382102220ac6fe6f7366b5124a40e016e41119/base/abstractdict.jl#L479). However, seems to be some kind of inconsistency in the three definitions in lines 479–481 (quoted below).

```julia
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...)

```

If I call `push!(d, 1 => 2.0)` (where `d` is an instance of my type) it does not fail, but if I call `push!(d, 1 => 2.0, 3 => 4.0)` for example, it gives:

```julia
ERROR: MethodError: no method matching push!(::Float64, ::Pair{Int64,Float64})

```

What was kind of an strange error (I was sure `d` is not a Float64), but if we look at line 480 above, it is defined as:

```julia
push!(t::AbstractDict, p::Pair, q::Pair) = push!(push!(t, p), q)

```

So it expects `push!` to return the AbstractDict/collection to chain the two `push!` calls but it defines the `push!` for just one pair one line above as:

```julia
push!(t::AbstractDict, p::Pair) = setindex!(t, p.second, p.first)

```

Which used `setindex!`, and `setindex!` by convention do not return the indexable collection but the new value inserted/updated (otherwise all code that does something like `a[1] = a[2] = 0` would fail).

As `push!` for Dicts, Vectors, and everything else returns the collection itself (and not the newly pushed value), and the definitions of lines 480 and 481 also seem to assume so, is the fallback definition of `push!` for a single pair in abstractdict.jl wrong? Should not it be:

```julia
function push!(t::AbstractDict, p::Pair)
  setindex!(t, p.second, p.first)
  t
end

```

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [June 8, 2019, 9:32pm UTC](https://discourse.julialang.org/t/concerning-abstractdict-inheritance-and-push-is-base-wrong/25082/2 "2019-06-08T21:32:50Z")

</div>

> [@Henrique\_Becker](#):
>
> Which used `setindex!` , and `setindex!` by convention do not return the indexable collection but the new value inserted/updated (otherwise all code that does something like `a[1] = a[2] = 0` would fail).

This is not true,

```julia
julia> a = rand(5);

julia> b = setindex!(a, 1, 1);

julia> typeof(b)
Array{Float64,1}

```

The lowering for `a[1] = 0` is not only to a `setindex!` call, cf:

```julia
julia> Meta.lower(Main, :(a[1] = x))
:($(Expr(:thunk, CodeInfo(
1 ─ (Base.setindex!)(a, x, 1)
└── return x
))))

```

---

<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:** [June 9, 2019, 2:59am UTC](https://discourse.julialang.org/t/concerning-abstractdict-inheritance-and-push-is-base-wrong/25082/3 "2019-06-09T02:59:18Z")

</div>

Ouch, this lowering caught me off guard. Now things make sense, my code has errors because I define my `setindex!` based on this incorrect assumption I had. I really not know how this has escaped me, as the manual is irreproachable:

> `setindex!(collection, value, key...)`  
> Store the given value at the given key or index within a collection. The syntax `a[i,j,...] = x` is converted by the compiler to `(setindex!(a, x, i, j, ...); x)` .

Sorry for the noise.
