# Findfirst() with Dict for which nothing is a valid key

**URL:** <https://discourse.julialang.org/t/findfirst-with-dict-for-which-nothing-is-a-valid-key/9141>\
**Category:** Internals & Design\
**Created:** [February 18, 2018, 12:32am UTC](https://discourse.julialang.org/t/findfirst-with-dict-for-which-nothing-is-a-valid-key/9141 "2018-02-18T00:32:10Z")\
**Posts on this page:** 1\
**Showing post:** 2

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [February 18, 2018, 12:38am UTC](https://discourse.julialang.org/t/findfirst-with-dict-for-which-nothing-is-a-valid-key/9141/2 "2018-02-18T00:38:27Z")

</div>

> [@The new output of findfirst is dangerous](https://discourse.julialang.org/t/the-new-output-of-findfirst-is-dangerous/9131/12):
>
> There can be no confusion as to whether a match was found or not

That’s not true, if `nothing` can be an index (key) into the collection.  
All the change did was hurt performance and move the place where things break down from one place (where 0 might be a valid index [now possible with `OffsetArrays`, or other `AbstractArrays`)

I think a better interface, that would not lose any performance, and would be able to handle the case of `nothing` being an index (where I worked we actually used that, to store `JSON` `null` as a key in `AssociativeArrays`s), would be to add two functions, `found(collection, retval)` and `found_key(collection, retval)` (and maybe a macro to make life a bit easier).  
If a particular type can use something like `0`, or `typemin(Int)` as a in-band sentinel value for a not-found index/key, for example with `String`, then you’d have the definition: `found(::Type{String}, val) = val != 0` and `found_key(::Type{String}, val) = val`.  
For something where no in-band sentinel value is possible (i.e. the key is `<: Any`, or any union that includes `Nothing`), then the return value can simply be a tuple, i.e. `(true, value)` or `(false, nothing)`. If `nothing` is found, it would return `(true, nothing)`, and everything works correctly, no funky special cases. The definitions then would be `found(::Type{MyType}, ret) = ret[1]`, and `found_key(::Type{MyType}, ret) = ret[2]`.

---

_[View the full topic](https://discourse.julialang.org/t/findfirst-with-dict-for-which-nothing-is-a-valid-key/9141)._
