<div dir="ltr"><b>What</b><div><b>====<br></b><div><br></div><div>Rename unordered-container's <a href="https://hackage.haskell.org/package/unordered-containers-0.2.8.0/docs/Data-HashMap-Strict.html#v:lookupDefault">Data.HashMap.lookupDefault</a> to findWithDefault.</div><div><br></div><div>findWithDefault :: (Eq k, Hashable k) => v -> k -> HashMap k v -> v</div><div><br></div><div>Note: There are no functionality changes, this is purely a rename.</div><div><br></div><div><br></div><div><b>Why</b></div><div><b>===</b></div><div><br></div><div>This aligns the Data.HashMap API with containers' <a href="https://hackage.haskell.org/package/containers-0.5.11.0/docs/Data-Map-Strict.html#v:findWithDefault">Data.Map.findWithDefault</a>.</div><div><br></div><div>Data.Map.findWithDefault :: Ord k => a -> k -> Map k a -> a</div><div><br></div><div>The map APIs provided by the two packages are <i>almost</i> drop in replacement compatible if you aren't using any of the implementation specific functions (like ordering based functions from Data.Map), this change brings us one step closer.</div><div><br></div><div>API consistency reduces the cognitive overhead when learning a new package. Having to learn different function names for the same functionality depending on which "map" implementation you're using is a poor developer experience.</div><div><br></div><div>We chose the containers' name findWithDefault over unordered-containers' lookupDefault for two reasons:</div><div><ol><li>Existing lookupX functions returns a Maybe value, while findX functions return a non-wrapped value.</li><li>The containers package ships with GHC and is a "core" package.</li></ol></div><div><br></div><div><i>Pros:</i></div><div><i>-----</i></div><div><i><br></i></div><div>- Consistent API between different "map" implementations (Data.Map, Data.IntMap, Data.HashMap). This makes switching implementations an import change.</div><div>- Naming matches other similar functions (lookupX return Maybe-wrapped values)</div><div><br></div><div><i>Cons:</i></div><div><i>-----</i></div><div><i><br></i></div><div>- API change requires users to update their code</div><div>  + unordered-containers has A LOT of users: 358815 total (13325 in the last 30 days)</div><div><br></div><div><br></div><div><b>How</b></div><div><b>===</b></div><div><br></div><div><a href="https://github.com/tibbe/unordered-containers/pull/176/commits/152f8818ee13dacb370e49b904edc4c1a4c8f87b">https://github.com/tibbe/unordered-containers/pull/176/commits/152f8818ee13dacb370e49b904edc4c1a4c8f87b</a><br></div><div><br></div><div><i>Code Changes:</i></div><div><i>-------------</i></div><div><i><br></i></div><div>- Rename the function in Data.HashMap.Base (and expose it from Strict and Lazy modules)</div><div>- Make lookupDefault an INLINE alias of findWithDefault</div><div>- Add DEPRECATION notice to lookupDefault</div><div>- Bump unordered-containers version to 0.2.9.0</div><div><br></div><div><br></div><div><i>Migration - Option 1:</i></div><div><i>---------------------<br></i></div><div><i><br></i></div><div><i>- </i>Announce on Haskell communication channels (haskell-cafe@, haskell-community@, #haskell on Twitter, Reddit thread, etc.)</div><div>- Users of unordered-containers >= 0.2.9.0 receive warning about deprecated function</div><div>- Code can be updated by find and replace: s/lookupDefault/findWithDefault/</div><div>- lookupDefault with deprecation notice remains for 1 year (subject to change)</div><div>- after 1 year the lookupDefault function is removed, unordered-containers version bumped to 0.3.0.0 (major version bump due to breaking change)</div><div><br></div><div><i>Migration - Option 2:</i></div><div><i>---------------------<br></i></div><div><i><br></i></div><div>- Announce on Haskell communication channels (haskell-cafe@, haskell-community@, #haskell on Twitter, Reddit thread, etc.)<i><br></i></div><div><div>- Users of unordered-containers >= 0.2.9.0 receive warning about deprecated function</div><div>- Code can be updated by find and replace: s/lookupDefault/findWithDefault/</div></div><div>- lookupDefault function is never removed</div><div><i><br></i></div><div><br></div><div><div><b>Discussion: </b></div></div><div><b>===========</b></div><div><b><br></b></div><div><div>I would like to get some comments on this proposal. In particular: </div><div>- Is the small API churn worth the increase in consistency?</div></div><div>- Should migration option 1 (completely remove the old function) or 2 (keep old function indefinitely) be taken? We can punt on this and go with option 2 to start and revisit later if desired.</div><div><br></div><div><div>I hope a decision about the proposal can be reached by 2018-02-09. Thanks!</div></div><div><br></div><div><br></div><div><br></div><div><br></div></div></div>