# Mergewith(dicts...)

**URL:** <https://discourse.julialang.org/t/mergewith-dicts/88136>\
**Category:** General Usage\
**Created:** [October 2, 2022, 11:51pm UTC](https://discourse.julialang.org/t/mergewith-dicts/88136 "2022-10-02T23:51:30Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [October 2, 2022, 11:51pm UTC](https://discourse.julialang.org/t/mergewith-dicts/88136/1 "2022-10-02T23:51:30Z")

</div>

Why does this discard the first dict instead of merging? This signature is undocumented.

```julia
julia> mergewith(Dict(1=>10), Dict(2=>20))
Dict{Int64, Int64} with 1 entry:
  2 => 20

```

---

<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 3, 2022, 1:34am UTC](https://discourse.julialang.org/t/mergewith-dicts/88136/2 "2022-10-03T01:34:30Z")

</div>

If the signature is undocumented this is undefined behaviour and you should not rely on it.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [October 3, 2022, 3:10am UTC](https://discourse.julialang.org/t/mergewith-dicts/88136/3 "2022-10-03T03:10:24Z")

</div>

eh, you just want

```julia

julia> merge(Dict(1=>10), Dict(2=>20))
Dict{Int64, Int64} with 2 entries:
  2 => 20
  1 => 10

```

merge with takes an “combine” function

---

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [October 3, 2022, 3:21am UTC](https://discourse.julialang.org/t/mergewith-dicts/88136/4 "2022-10-03T03:21:11Z")

</div>

It should give an error in this case, no?

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [October 3, 2022, 3:29am UTC](https://discourse.julialang.org/t/mergewith-dicts/88136/5 "2022-10-03T03:29:38Z")

</div>

maybe, but we probably have 1000:  
“this works because our functions are general enough but users probably don’t want this behavior”

this particular case is just because

```julia
function mergewith!(combine, d::AbstractDict, others::AbstractDict...)
    foldl(mergewith!(combine), others; init = d)
end

```

we just returned `init=d` I guess

and the fact that this is un-typed

```julia
mergewith!(combine) = (args...) -> mergewith!(combine, args...)

```

maybe type this with:

```julia
julia> Base.Callable
Union{Function, Type}

```

?

---

<div class="post-metadata">

**Author:** ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)\
**Post date:** [October 3, 2022, 4:35am UTC](https://discourse.julialang.org/t/mergewith-dicts/88136/6 "2022-10-03T04:35:56Z")

</div>

Yes, that seems like it should be typed with a `Callable` check, to avoid this type of issue. This “working” without error is an unfortunate consequence of the fact that the combine “operator” `Dict(1 => 10)` is never actually used, since according to `mergewith!` (and its called functions) there’s only an initial value here, `Dict(2=>20)`, so nothing to reduce using the operator. So passing anything at all as the first argument will work, as long as there’s only one other argument to the function.

```julia
julia> mergewith(Main, Dict(2=>20))
Dict{Int64, Int64} with 1 entry:
  2 => 20

julia> mergewith(π, Dict(2=>20))
Dict{Int64, Int64} with 1 entry:
  2 => 20

julia> mergewith("this is free real estate", Dict(2=>20))
Dict{Int64, Int64} with 1 entry:
  2 => 20

```

I’m not sure if the non-specialization penalty of `Function` applies to `Callable` too. If it does, an explicit check of `combine isa Callable` seems worth doing to avoid this quite unintuitive behaviour.

---

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [October 3, 2022, 4:40am UTC](https://discourse.julialang.org/t/mergewith-dicts/88136/7 "2022-10-03T04:40:17Z")

</div>

Jeff says

> `Callable` should not be used anymore.

> <https://github.com/JuliaLang/julia/issues/43491#issuecomment-1003489577>
>
> There is no docstring for it, it doesn't seem to be covered by the manual. Docst…rings even seem to explicitly cover it, e.g.
> \`\`\`julia
> """
> replace(new::Function, A; \[count::Integer\])
> 
> Return a copy of \`A\` where each value \`x\` in \`A\` is replaced by \`new(x)\`.
> ...
> """
> replace(new::Callable, A; count::Integer=typemax(Int)) =
> \_replace!(new, \_similar\_or\_copy(A), A, check\_count(count))
> \`\`\`
> 
> Yet it seems like a very useful concept, and I've been using it in my code without even questioning how "official" it is. I then was surprised when a colleague didn't know about it, and now I wonder where I first picked it up ... ;-).
> 
> Anyway: is it deliberately hidden, or would a patch documenting it be welcome?

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [October 3, 2022, 4:44am UTC](https://discourse.julialang.org/t/mergewith-dicts/88136/8 "2022-10-03T04:44:34Z")

</div>

exactly, so nothing can be done here, even if you error on `combine::AbstractDict`, there are so many other types that is “probably wrong”
