# @unpack with Parameters.jl when key is not found

**URL:** https://discourse.julialang.org/t/unpack-with-parameters-jl-when-key-is-not-found/60716
**Category:** General Usage
**Tags:** question, package
**Created:** [May 7, 2021, 1:42pm UTC](https://discourse.julialang.org/t/unpack-with-parameters-jl-when-key-is-not-found/60716 "2021-05-07T13:42:19Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![gregory](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gregory/32/18969_2.png) [@gregory](https://discourse.julialang.org/u/gregory)
#### Post date: [May 7, 2021, 1:42pm UTC](https://discourse.julialang.org/t/unpack-with-parameters-jl-when-key-is-not-found/60716/1 "2021-05-07T13:42:19Z")

</div>

Hi, is there an easy way to have `Parameters.jl` skip missing keys or fields?

```
using Parameters
mydict = Dict(a=>3,b=>2.3,c=>"mystr")
@unpack (a,b,c,d) = mydict
ERROR: KeyError: key "d" not found

```

I would like it to just skip over the missing key. The reason I want this behavior is I am carrying around two lists which hold fixed parameters and ones to be found via optimization. It would be nice if I could just unpack them, without having to check which ones were in which list like:

```
@unpack (fixed1,fixed2,...) = fixedParams
@unpack (fitted1,fitted2,...) fittedParams

```

and instead being able to just say

```
@unpack (p1,p2,...) = fixedParams
@unpack (p1,p2,...) = fittedParams

```

---

<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: [May 7, 2021, 1:48pm UTC](https://discourse.julialang.org/t/unpack-with-parameters-jl-when-key-is-not-found/60716/2 "2021-05-07T13:48:12Z")

</div>

I don’t think so. Part of the reason `@unpack` is fast is because it doesn’t have these kinds of checks. A macro doesn’t know what’s inside a `Dict`.

---

<div class="post-metadata">

### Author: ![gregory](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gregory/32/18969_2.png) [@gregory](https://discourse.julialang.org/u/gregory)
#### Post date: [May 7, 2021, 2:05pm UTC](https://discourse.julialang.org/t/unpack-with-parameters-jl-when-key-is-not-found/60716/3 "2021-05-07T14:05:50Z")

</div>

Is there a way to write my own method then that does this check? It doesn’t need to be fast.

---

<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: [May 7, 2021, 2:10pm UTC](https://discourse.julialang.org/t/unpack-with-parameters-jl-when-key-is-not-found/60716/4 "2021-05-07T14:10:00Z")

</div>

UnPack.jl is actually super simple once you understand metaprogramming.

[https://github.com/mauro3/UnPack.jl/blob/master/src/UnPack.jl](https://github.com/mauro3/UnPack.jl/blob/master/src/UnPack.jl)

In particular, lines 32-36 are what you would want to change. Instead of `getindex` you would want `get(d, x, nothing)` or similar.

---

<div class="post-metadata">

### Author: ![gregory](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gregory/32/18969_2.png) [@gregory](https://discourse.julialang.org/u/gregory)
#### Post date: [May 7, 2021, 4:08pm UTC](https://discourse.julialang.org/t/unpack-with-parameters-jl-when-key-is-not-found/60716/5 "2021-05-07T16:08:34Z")

</div>

I tried adding both of the following methods:

```julia
@inline unpack(x::AbstractDict{<:AbstractString}, k) = get(x,string(k),nothing)
@inline unpack(x::AbstractDict{<:AbstractString}, ::Val{k}) where {k} = get(x,string(k),nothing)

```

but still got the same error:

```julia
test=Dict("a"=>1,"b"=>2,"c"=>"mystr")
@unpack (a,b,c,d) = test
ERROR: KeyError: key "d" not found

```

---

<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: [May 7, 2021, 4:10pm UTC](https://discourse.julialang.org/t/unpack-with-parameters-jl-when-key-is-not-found/60716/6 "2021-05-07T16:10:34Z")

</div>

Could you please tell us more about what steps you did to add the methods? Did you add the package for development using `] dev`?

---

<div class="post-metadata">

### Author: ![gregory](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gregory/32/18969_2.png) [@gregory](https://discourse.julialang.org/u/gregory)
#### Post date: [May 7, 2021, 4:12pm UTC](https://discourse.julialang.org/t/unpack-with-parameters-jl-when-key-is-not-found/60716/7 "2021-05-07T16:12:01Z")

</div>

Ah sorry. I thought I was able to add methods similar to how I can add methods in `Base.jl`. So I was just adding them inline in my Julia script.

---

<div class="post-metadata">

### Author: ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)
#### Post date: [May 7, 2021, 4:49pm UTC](https://discourse.julialang.org/t/unpack-with-parameters-jl-when-key-is-not-found/60716/8 "2021-05-07T16:49:57Z")

</div>

You can, but you should `import` methods first.  
But this is type piracy and shouldn’t be used if you are writing a library (but more or less fine in your local script)

---

<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: [May 7, 2021, 5:29pm UTC](https://discourse.julialang.org/t/unpack-with-parameters-jl-when-key-is-not-found/60716/9 "2021-05-07T17:29:45Z")

</div>

Here is an MWE

```julia
julia> using UnPack

julia> import UnPack: unpack

help?> unpack
search: unpack UnPack @unpack

  This function is invoked to unpack one field/entry of some DataType dt and has signature:

  unpack(dt::Any, ::Val{sym}) -> value of sym

  The sym is the symbol of the assigned variable.

  Three definitions are included in the package to unpack a composite type or a dictionary with Symbol
  or string keys:

  @inline unpack(x, ::Val{f}) where {f} = getproperty(x, f)
  @inline unpack(x::AbstractDict{Symbol}, ::Val{k}) where {k} = x[k]
  @inline unpack(x::AbstractDict{S}, ::Val{k}) where {S<:AbstractString,k} = x[string(k)]

  More methods can be added to allow for specialized unpacking of other datatypes.

  See also pack!.

julia> unpack(x::AbstractDict{S}, ::Val{k}) where {S<:AbstractString,k} = get(x, string(k), nothing)
unpack (generic function with 3 methods)

julia> d = Dict(["a" => 1])
Dict{String, Int64} with 1 entry:
  "a" => 1

julia> @unpack a, c = d
Dict{String, Int64} with 1 entry:
  "a" => 1

julia> c

```

That said, don’t do this… Maybe you can define your own macro, use `@unpack`’s parsing, but call your own function instead of `unpack`.

---

<div class="post-metadata">

### Author: ![roi.holtzman](https://avatars.discourse-cdn.com/v4/letter/r/f05b48/32.png) [@roi.holtzman](https://discourse.julialang.org/u/roi.holtzman)
#### Post date: [September 9, 2022, 7:49pm UTC](https://discourse.julialang.org/t/unpack-with-parameters-jl-when-key-is-not-found/60716/10 "2022-09-09T19:49:07Z")

</div>

So how should one do this properly?

---

<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: [September 9, 2022, 9:03pm UTC](https://discourse.julialang.org/t/unpack-with-parameters-jl-when-key-is-not-found/60716/11 "2022-09-09T21:03:09Z")

</div>

Fork `@unpack` and change the name of the macro?

---

<div class="post-metadata">

### Author: ![roi.holtzman](https://avatars.discourse-cdn.com/v4/letter/r/f05b48/32.png) [@roi.holtzman](https://discourse.julialang.org/u/roi.holtzman)
#### Post date: [September 9, 2022, 9:58pm UTC](https://discourse.julialang.org/t/unpack-with-parameters-jl-when-key-is-not-found/60716/12 "2022-09-09T21:58:25Z")

</div>

I would like to use it as a convenience function in my own code. I mean, I still want to use the default `Parameters.jl`.

---

<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: [September 9, 2022, 10:28pm UTC](https://discourse.julialang.org/t/unpack-with-parameters-jl-when-key-is-not-found/60716/13 "2022-09-09T22:28:43Z")

</div>

When I say “improper” it means that if you want

```julia
@unpack a = d

```

to _not_ fail when `a` is not in `d`, you need to commit [type piracy](https://docs.julialang.org/en/v1/manual/style-guide/#Avoid-type-piracy), which means overwriting a method you don’t own for a type you don’t own.

You can do that in your own code (see above), but the consequence is

1. When people read your code, the behavior of `@unpack` will be different than they expect
2. If other packages use your code in any way, existing uses of `@unpack` will behave differently than the original authors expected.

So you can’t be “correct” and change the behavior of `@unpack`.
