Proposal: Rename HashMap.lookupDefault to HashMap.findWithDefault

*What* *====* Rename unordered-container's Data.HashMap.lookupDefault https://hackage.haskell.org/package/unordered-containers-0.2.8.0/docs/Data-H... to findWithDefault. findWithDefault :: (Eq k, Hashable k) => v -> k -> HashMap k v -> v Note: There are no functionality changes, this is purely a rename. *Why* *===* This aligns the Data.HashMap API with containers' Data.Map.findWithDefault https://hackage.haskell.org/package/containers-0.5.11.0/docs/Data-Map-Strict... . Data.Map.findWithDefault :: Ord k => a -> k -> Map k a -> a The map APIs provided by the two packages are *almost* 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. 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. We chose the containers' name findWithDefault over unordered-containers' lookupDefault for two reasons: 1. Existing lookupX functions returns a Maybe value, while findX functions return a non-wrapped value. 2. The containers package ships with GHC and is a "core" package. *Pros:* *-----* - Consistent API between different "map" implementations (Data.Map, Data.IntMap, Data.HashMap). This makes switching implementations an import change. - Naming matches other similar functions (lookupX return Maybe-wrapped values) *Cons:* *-----* - API change requires users to update their code + unordered-containers has A LOT of users: 358815 total (13325 in the last 30 days) *How* *===* https://github.com/tibbe/unordered-containers/pull/176/commits/152f8818ee13d... *Code Changes:* *-------------* - Rename the function in Data.HashMap.Base (and expose it from Strict and Lazy modules) - Make lookupDefault an INLINE alias of findWithDefault - Add DEPRECATION notice to lookupDefault - Bump unordered-containers version to 0.2.9.0 *Migration - Option 1:* *---------------------* *- *Announce on Haskell communication channels (haskell-cafe@, haskell-community@, #haskell on Twitter, Reddit thread, etc.) - Users of unordered-containers >= 0.2.9.0 receive warning about deprecated function - Code can be updated by find and replace: s/lookupDefault/findWithDefault/ - lookupDefault with deprecation notice remains for 1 year (subject to change) - after 1 year the lookupDefault function is removed, unordered-containers version bumped to 0.3.0.0 (major version bump due to breaking change) *Migration - Option 2:* *---------------------* - Announce on Haskell communication channels (haskell-cafe@, haskell-community@, #haskell on Twitter, Reddit thread, etc.) - Users of unordered-containers >= 0.2.9.0 receive warning about deprecated function - Code can be updated by find and replace: s/lookupDefault/findWithDefault/ - lookupDefault function is never removed *Discussion: * *===========* I would like to get some comments on this proposal. In particular: - Is the small API churn worth the increase in consistency? - 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. I hope a decision about the proposal can be reached by 2018-02-09. Thanks!

On 24 January 2018 at 13:14, Matt Renaud
What ====
Rename unordered-container's Data.HashMap.lookupDefault to findWithDefault.
findWithDefault :: (Eq k, Hashable k) => v -> k -> HashMap k v -> v
Note: There are no functionality changes, this is purely a rename.
Why ===
This aligns the Data.HashMap API with containers' Data.Map.findWithDefault.
Data.Map.findWithDefault :: Ord k => a -> k -> Map k a -> a
The map APIs provided by the two packages are almost 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.
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.
We chose the containers' name findWithDefault over unordered-containers' lookupDefault for two reasons:
Existing lookupX functions returns a Maybe value, while findX functions return a non-wrapped value. The containers package ships with GHC and is a "core" package.
Pros: -----
- Consistent API between different "map" implementations (Data.Map, Data.IntMap, Data.HashMap). This makes switching implementations an import change. - Naming matches other similar functions (lookupX return Maybe-wrapped values)
Cons: -----
- API change requires users to update their code + unordered-containers has A LOT of users: 358815 total (13325 in the last 30 days)
How ===
https://github.com/tibbe/unordered-containers/pull/176/commits/152f8818ee13d...
Code Changes: -------------
- Rename the function in Data.HashMap.Base (and expose it from Strict and Lazy modules) - Make lookupDefault an INLINE alias of findWithDefault - Add DEPRECATION notice to lookupDefault - Bump unordered-containers version to 0.2.9.0
Migration - Option 1: ---------------------
- Announce on Haskell communication channels (haskell-cafe@, haskell-community@, #haskell on Twitter, Reddit thread, etc.) - Users of unordered-containers >= 0.2.9.0 receive warning about deprecated function - Code can be updated by find and replace: s/lookupDefault/findWithDefault/ - lookupDefault with deprecation notice remains for 1 year (subject to change) - after 1 year the lookupDefault function is removed, unordered-containers version bumped to 0.3.0.0 (major version bump due to breaking change)
Migration - Option 2: ---------------------
- Announce on Haskell communication channels (haskell-cafe@, haskell-community@, #haskell on Twitter, Reddit thread, etc.) - Users of unordered-containers >= 0.2.9.0 receive warning about deprecated function - Code can be updated by find and replace: s/lookupDefault/findWithDefault/ - lookupDefault function is never removed
Discussion: ===========
I would like to get some comments on this proposal. In particular: - Is the small API churn worth the increase in consistency? - 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.
I hope a decision about the proposal can be reached by 2018-02-09. Thanks!
I prefer Option 1, but I think we need a release _without_ DEPRECATION first, and then it can be added to lookupDefault (which currently requires a major version bump per the PVP, though this might be changing: https://github.com/haskell/pvp/issues/12 ) Whether this is worth it though is another story; until/unless we get Backpack support on containers and unordered-containers (which also requires adding a lot more functionality to the latter last I checked) I think it's OK that they use different names. -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com http://IvanMiljenovic.wordpress.com

Thanks for the input!
I think we need a release _without_ DEPRECATION first...though this might be changing
Either works for me. Personally I'd like it to be removed eventually but I anticipate the timeline for that will be long, in which case having a minor release that doesn't deprecate it to start doesn't seem like it would cause any harm. Then we can wait until the PVP decision is worked out.
until/unless we get Backpack support on containers and unordered-containers
Yeah, this would make it a requirement that they share the same name, in the meantime its unfortunate that they don't have the same name. Obviously an extreme, but imagine if "fmap" was called something different by every functor instance :P Since the migration for users is very straightforward I'd argue the cost is pretty low to increase consistency. On Tue, Jan 23, 2018 at 6:59 PM, Ivan Lazar Miljenovic < ivan.miljenovic@gmail.com> wrote:
What ====
Rename unordered-container's Data.HashMap.lookupDefault to findWithDefault.
findWithDefault :: (Eq k, Hashable k) => v -> k -> HashMap k v -> v
Note: There are no functionality changes, this is purely a rename.
Why ===
This aligns the Data.HashMap API with containers' Data.Map.findWithDefault.
Data.Map.findWithDefault :: Ord k => a -> k -> Map k a -> a
The map APIs provided by the two packages are almost 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.
API consistency reduces the cognitive overhead when learning a new
Having to learn different function names for the same functionality depending on which "map" implementation you're using is a poor developer experience.
We chose the containers' name findWithDefault over unordered-containers' lookupDefault for two reasons:
Existing lookupX functions returns a Maybe value, while findX functions return a non-wrapped value. The containers package ships with GHC and is a "core" package.
Pros: -----
- Consistent API between different "map" implementations (Data.Map, Data.IntMap, Data.HashMap). This makes switching implementations an import change. - Naming matches other similar functions (lookupX return Maybe-wrapped values)
Cons: -----
- API change requires users to update their code + unordered-containers has A LOT of users: 358815 total (13325 in the last 30 days)
How ===
https://github.com/tibbe/unordered-containers/pull/176/commits/ 152f8818ee13dacb370e49b904edc4c1a4c8f87b
Code Changes: -------------
- Rename the function in Data.HashMap.Base (and expose it from Strict and Lazy modules) - Make lookupDefault an INLINE alias of findWithDefault - Add DEPRECATION notice to lookupDefault - Bump unordered-containers version to 0.2.9.0
Migration - Option 1: ---------------------
- Announce on Haskell communication channels (haskell-cafe@, haskell-community@, #haskell on Twitter, Reddit thread, etc.) - Users of unordered-containers >= 0.2.9.0 receive warning about deprecated function - Code can be updated by find and replace: s/lookupDefault/ findWithDefault/ - lookupDefault with deprecation notice remains for 1 year (subject to change) - after 1 year the lookupDefault function is removed, unordered-containers version bumped to 0.3.0.0 (major version bump due to breaking change)
Migration - Option 2: ---------------------
- Announce on Haskell communication channels (haskell-cafe@, haskell-community@, #haskell on Twitter, Reddit thread, etc.) - Users of unordered-containers >= 0.2.9.0 receive warning about deprecated function - Code can be updated by find and replace: s/lookupDefault/ findWithDefault/ - lookupDefault function is never removed
Discussion: ===========
I would like to get some comments on this proposal. In particular: - Is the small API churn worth the increase in consistency? - 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
On 24 January 2018 at 13:14, Matt Renaud
wrote: package. option 2 to start and revisit later if desired.
I hope a decision about the proposal can be reached by 2018-02-09. Thanks!
I prefer Option 1, but I think we need a release _without_ DEPRECATION first, and then it can be added to lookupDefault (which currently requires a major version bump per the PVP, though this might be changing: https://github.com/haskell/pvp/issues/12 )
Whether this is worth it though is another story; until/unless we get Backpack support on containers and unordered-containers (which also requires adding a lot more functionality to the latter last I checked) I think it's OK that they use different names.
-- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com http://IvanMiljenovic.wordpress.com

On Tue, 23 Jan 2018, Matt Renaud wrote:
Cons: -----
- API change requires users to update their code + unordered-containers has A LOT of users: 358815 total (13325 in the last 30 days)
A better measure are certainly the reverse package dependencies: https://www.stackage.org/package/unordered-containers There are almost 1000 packages that import unordered-containers, still quite a lot!
Migration - Option 1: ---------------------
- Announce on Haskell communication channels (haskell-cafe@, haskell-community@, #haskell on Twitter, Reddit thread, etc.) - Users of unordered-containers >= 0.2.9.0 receive warning about deprecated function - Code can be updated by find and replace: s/lookupDefault/findWithDefault/ - lookupDefault with deprecation notice remains for 1 year (subject to change) - after 1 year the lookupDefault function is removed, unordered-containers version bumped to 0.3.0.0 (major version bump due to breaking change)
I'd say 1 year is too short. There is no need to remove the function quickly. I'd vote for adding a deprecation warning soon, but then keep the function until the next larger API overhaul or say, for five years or a decade.

I'd say 1 year is too short. There is no need to remove the function quickly. I'd vote for adding a deprecation warning soon, but then keep the function until the next larger API overhaul or say, for five years or a decade.
+1. Yes. On 24.01.2018 08:11, Henning Thielemann wrote:
On Tue, 23 Jan 2018, Matt Renaud wrote:
Cons: -----
- API change requires users to update their code + unordered-containers has A LOT of users: 358815 total (13325 in the last 30 days)
A better measure are certainly the reverse package dependencies: https://www.stackage.org/package/unordered-containers
There are almost 1000 packages that import unordered-containers, still quite a lot!
Migration - Option 1: ---------------------
- Announce on Haskell communication channels (haskell-cafe@, haskell-community@, #haskell on Twitter, Reddit thread, etc.) - Users of unordered-containers >= 0.2.9.0 receive warning about deprecated function - Code can be updated by find and replace: s/lookupDefault/findWithDefault/ - lookupDefault with deprecation notice remains for 1 year (subject to change) - after 1 year the lookupDefault function is removed, unordered-containers version bumped to 0.3.0.0 (major version bump due to breaking change)
I'd say 1 year is too short. There is no need to remove the function quickly. I'd vote for adding a deprecation warning soon, but then keep the function until the next larger API overhaul or say, for five years or a decade.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- Andreas Abel <>< Du bist der geliebte Mensch. Department of Computer Science and Engineering Chalmers and Gothenburg University, Sweden andreas.abel@gu.se http://www.cse.chalmers.se/~abela/

keep the function until the next larger API overhaul or say, for five years or a decade.
That sounds good to me, I wasn't sure how long is reasonable to wait after
deprecating an API before removing it.
On Wed, Jan 24, 2018 at 6:25 AM, Andreas Abel
I'd say 1 year is too short. There is no need to remove the function quickly. I'd vote for adding a deprecation warning soon, but then keep the function until the next larger API overhaul or say, for five years or a decade.
+1.
Yes.
On 24.01.2018 08:11, Henning Thielemann wrote:
On Tue, 23 Jan 2018, Matt Renaud wrote:
Cons:
-----
- API change requires users to update their code + unordered-containers has A LOT of users: 358815 total (13325 in the last 30 days)
A better measure are certainly the reverse package dependencies: https://www.stackage.org/package/unordered-containers
There are almost 1000 packages that import unordered-containers, still quite a lot!
Migration - Option 1:
---------------------
- Announce on Haskell communication channels (haskell-cafe@, haskell-community@, #haskell on Twitter, Reddit thread, etc.) - Users of unordered-containers >= 0.2.9.0 receive warning about deprecated function - Code can be updated by find and replace: s/lookupDefault/findWithDefaul t/ - lookupDefault with deprecation notice remains for 1 year (subject to change) - after 1 year the lookupDefault function is removed, unordered-containers version bumped to 0.3.0.0 (major version bump due to breaking change)
I'd say 1 year is too short. There is no need to remove the function quickly. I'd vote for adding a deprecation warning soon, but then keep the function until the next larger API overhaul or say, for five years or a decade.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- Andreas Abel <>< Du bist der geliebte Mensch.
Department of Computer Science and Engineering Chalmers and Gothenburg University, Sweden
andreas.abel@gu.se http://www.cse.chalmers.se/~abela/

Doesn't quickly adding a deprecation warning break building any of those 1000+ packages with -Werror? I'd support adding the new function, but am very reluctant to force any quick changes. Tom
El 24 ene 2018, a las 09:25, Andreas Abel
escribió: I'd say 1 year is too short. There is no need to remove the function quickly. I'd vote for adding a deprecation warning soon, but then keep the function until the next larger API overhaul or say, for five years or a decade.
+1.
Yes.
On 24.01.2018 08:11, Henning Thielemann wrote:
On Tue, 23 Jan 2018, Matt Renaud wrote: Cons: -----
- API change requires users to update their code + unordered-containers has A LOT of users: 358815 total (13325 in the last 30 days) A better measure are certainly the reverse package dependencies: https://www.stackage.org/package/unordered-containers There are almost 1000 packages that import unordered-containers, still quite a lot! Migration - Option 1: ---------------------
- Announce on Haskell communication channels (haskell-cafe@, haskell-community@, #haskell on Twitter, Reddit thread, etc.) - Users of unordered-containers >= 0.2.9.0 receive warning about deprecated function - Code can be updated by find and replace: s/lookupDefault/findWithDefault/ - lookupDefault with deprecation notice remains for 1 year (subject to change) - after 1 year the lookupDefault function is removed, unordered-containers version bumped to 0.3.0.0 (major version bump due to breaking change) I'd say 1 year is too short. There is no need to remove the function quickly. I'd vote for adding a deprecation warning soon, but then keep the function until the next larger API overhaul or say, for five years or a decade.
Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- Andreas Abel <>< Du bist der geliebte Mensch.
Department of Computer Science and Engineering Chalmers and Gothenburg University, Sweden
andreas.abel@gu.se http://www.cse.chalmers.se/~abela/ _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

Doesn't quickly adding a deprecation warning break building any of those 1000+ packages with -Werror?
It appears that https://github.com/haskell/pvp/issues/12 is close to being resolved[1], and as hvr mentioned Hackage already prevents packages with -Werror from being uploaded, so this shouldn't be an issue for packages already uploaded. But yes, if someone is using unordered-containers and building locally with -Werror then the build would fail. That being said, if the plan is to deprecate it then I don't think there's a better way than marking it DEPRECATED. We could go with a "soft" deprecation--remove function comments and replace with "This function is deprecated, use findWithDefault" and make some announcements--but I doubt many people would act on that so it would just be kicking the can down the road.
I'd support adding the new function, but am very reluctant to force any quick changes.
Glad to hear! It would be nice if there was a way of getting information
about how often this particular function was used so we could get a better
estimate of how many packages would truly be affected. And I completely
agreed that we should do everything we can to not break people's builds,
but hopefully not at the expense of improving APIs.
[1] https://github.com/haskell/pvp/pull/18
On Wed, Jan 24, 2018 at 3:25 PM,
Doesn't quickly adding a deprecation warning break building any of those 1000+ packages with -Werror?
I'd support adding the new function, but am very reluctant to force any quick changes.
Tom
El 24 ene 2018, a las 09:25, Andreas Abel
escribió: I'd say 1 year is too short. There is no need to remove the function quickly. I'd vote for adding a deprecation warning soon, but then keep the function until the next larger API overhaul or say, for five years or a decade.
+1.
Yes.
On Tue, 23 Jan 2018, Matt Renaud wrote: Cons: -----
- API change requires users to update their code + unordered-containers has A LOT of users: 358815 total (13325 in
On 24.01.2018 08:11, Henning Thielemann wrote: the last 30 days) A better measure are certainly the reverse package dependencies: https://www.stackage.org/package/unordered-containers There are almost 1000 packages that import unordered-containers, still quite a lot!
Migration - Option 1: ---------------------
- Announce on Haskell communication channels (haskell-cafe@, haskell-community@, #haskell on Twitter, Reddit thread, etc.) - Users of unordered-containers >= 0.2.9.0 receive warning about deprecated function - Code can be updated by find and replace: s/lookupDefault/ findWithDefault/ - lookupDefault with deprecation notice remains for 1 year (subject to change) - after 1 year the lookupDefault function is removed, unordered-containers version bumped to 0.3.0.0 (major version bump due to breaking change) I'd say 1 year is too short. There is no need to remove the function quickly. I'd vote for adding a deprecation warning soon, but then keep the function until the next larger API overhaul or say, for five years or a decade.
Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- Andreas Abel <>< Du bist der geliebte Mensch.
Department of Computer Science and Engineering Chalmers and Gothenburg University, Sweden
andreas.abel@gu.se http://www.cse.chalmers.se/~abela/ _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

I'm wondering if we should ultimately get rid of that function altogether,
from both packages. From an API design standpoint, it's kind of silly,
because
findWithDefault d k m =
fromMaybe d (lookup k m)
At present, there's a slight performance penalty to doing it that way. I
wonder if we can squash that now that GHC has unboxed sums.
lookup# :: ... => k -> m a -> (# (# #) | a #)
lookup k m = case lookup# k m of
(# _ | #) -> Nothing
(# | a #) -> Just a
Now case-of-case will get rid of the extra Maybe.
On Jan 23, 2018 9:15 PM, "Matt Renaud"

I'm wondering if we should ultimately get rid of that function altogether, from both packages
I'm on the fence about this one since its such a common operation, I
personally would be a little surprised if it wasn't part of the API. You're
right that it's not /that/ much code to write, but I imagine everyone will
end up writing their own findWithDefault in their codebase, I may be wrong
though.
On Wed, Jan 24, 2018 at 4:27 PM, David Feuer
I'm wondering if we should ultimately get rid of that function altogether, from both packages. From an API design standpoint, it's kind of silly, because
findWithDefault d k m = fromMaybe d (lookup k m)
At present, there's a slight performance penalty to doing it that way. I wonder if we can squash that now that GHC has unboxed sums.
lookup# :: ... => k -> m a -> (# (# #) | a #) lookup k m = case lookup# k m of (# _ | #) -> Nothing (# | a #) -> Just a
Now case-of-case will get rid of the extra Maybe.
On Jan 23, 2018 9:15 PM, "Matt Renaud"
wrote: *What*
*====*
Rename unordered-container's Data.HashMap.lookupDefault https://hackage.haskell.org/package/unordered-containers-0.2.8.0/docs/Data-H... to findWithDefault.
findWithDefault :: (Eq k, Hashable k) => v -> k -> HashMap k v -> v
Note: There are no functionality changes, this is purely a rename.
*Why* *===*
This aligns the Data.HashMap API with containers' Data.Map.findWithDefault https://hackage.haskell.org/package/containers-0.5.11.0/docs/Data-Map-Strict... .
Data.Map.findWithDefault :: Ord k => a -> k -> Map k a -> a
The map APIs provided by the two packages are *almost* 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.
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.
We chose the containers' name findWithDefault over unordered-containers' lookupDefault for two reasons:
1. Existing lookupX functions returns a Maybe value, while findX functions return a non-wrapped value. 2. The containers package ships with GHC and is a "core" package.
*Pros:* *-----*
- Consistent API between different "map" implementations (Data.Map, Data.IntMap, Data.HashMap). This makes switching implementations an import change. - Naming matches other similar functions (lookupX return Maybe-wrapped values)
*Cons:* *-----*
- API change requires users to update their code + unordered-containers has A LOT of users: 358815 total (13325 in the last 30 days)
*How* *===*
https://github.com/tibbe/unordered-containers/pull/176/commi ts/152f8818ee13dacb370e49b904edc4c1a4c8f87b
*Code Changes:* *-------------*
- Rename the function in Data.HashMap.Base (and expose it from Strict and Lazy modules) - Make lookupDefault an INLINE alias of findWithDefault - Add DEPRECATION notice to lookupDefault - Bump unordered-containers version to 0.2.9.0
*Migration - Option 1:*
*---------------------*
*- *Announce on Haskell communication channels (haskell-cafe@, haskell-community@, #haskell on Twitter, Reddit thread, etc.) - Users of unordered-containers >= 0.2.9.0 receive warning about deprecated function - Code can be updated by find and replace: s/lookupDefault/findWithDefaul t/ - lookupDefault with deprecation notice remains for 1 year (subject to change) - after 1 year the lookupDefault function is removed, unordered-containers version bumped to 0.3.0.0 (major version bump due to breaking change)
*Migration - Option 2:*
*---------------------*
- Announce on Haskell communication channels (haskell-cafe@, haskell-community@, #haskell on Twitter, Reddit thread, etc.) - Users of unordered-containers >= 0.2.9.0 receive warning about deprecated function - Code can be updated by find and replace: s/lookupDefault/findWithDefaul t/ - lookupDefault function is never removed
*Discussion: * *===========*
I would like to get some comments on this proposal. In particular: - Is the small API churn worth the increase in consistency? - 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.
I hope a decision about the proposal can be reached by 2018-02-09. Thanks!
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

Reviving this thread since we didn't reach a definitive conclusion (and its
been about a year!).
It appears that the PVP issue about the deprecation has not yet been
resolved, so there still isn't any clarification on if this would require a
major version bump or not. From re-reading the thread it appears the
largest (only?) concerns are around how to properly deprecate it without
breaking anyone's code that is compiled with -Werror.
As a partial solution, I propose that we add the new
HashMap.findWithDefault function (which brings the APIs between Map and
HashMap closer together), and keep the existing function
(HashMap.lookupDefault) but update the function comment to say that it is
deprecated and point to findWithDefault. Are there any objections? We
should eventually officially mark this function as deprecated but I don't
think we should block the addition of the alias in the meantime because
there's not currently consensus on how it should happen, I'd like to move
that to a separate discussion.
Thanks!
On Mon, Jan 29, 2018 at 6:09 PM Matt Renaud
I'm wondering if we should ultimately get rid of that function altogether, from both packages
I'm on the fence about this one since its such a common operation, I personally would be a little surprised if it wasn't part of the API. You're right that it's not /that/ much code to write, but I imagine everyone will end up writing their own findWithDefault in their codebase, I may be wrong though.
On Wed, Jan 24, 2018 at 4:27 PM, David Feuer
wrote: I'm wondering if we should ultimately get rid of that function altogether, from both packages. From an API design standpoint, it's kind of silly, because
findWithDefault d k m = fromMaybe d (lookup k m)
At present, there's a slight performance penalty to doing it that way. I wonder if we can squash that now that GHC has unboxed sums.
lookup# :: ... => k -> m a -> (# (# #) | a #) lookup k m = case lookup# k m of (# _ | #) -> Nothing (# | a #) -> Just a
Now case-of-case will get rid of the extra Maybe.
On Jan 23, 2018 9:15 PM, "Matt Renaud"
wrote: *What*
*====*
Rename unordered-container's Data.HashMap.lookupDefault https://hackage.haskell.org/package/unordered-containers-0.2.8.0/docs/Data-H... to findWithDefault.
findWithDefault :: (Eq k, Hashable k) => v -> k -> HashMap k v -> v
Note: There are no functionality changes, this is purely a rename.
*Why* *===*
This aligns the Data.HashMap API with containers' Data.Map.findWithDefault https://hackage.haskell.org/package/containers-0.5.11.0/docs/Data-Map-Strict... .
Data.Map.findWithDefault :: Ord k => a -> k -> Map k a -> a
The map APIs provided by the two packages are *almost* 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.
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.
We chose the containers' name findWithDefault over unordered-containers' lookupDefault for two reasons:
1. Existing lookupX functions returns a Maybe value, while findX functions return a non-wrapped value. 2. The containers package ships with GHC and is a "core" package.
*Pros:* *-----*
- Consistent API between different "map" implementations (Data.Map, Data.IntMap, Data.HashMap). This makes switching implementations an import change. - Naming matches other similar functions (lookupX return Maybe-wrapped values)
*Cons:* *-----*
- API change requires users to update their code + unordered-containers has A LOT of users: 358815 total (13325 in the last 30 days)
*How* *===*
https://github.com/tibbe/unordered-containers/pull/176/commits/152f8818ee13d...
*Code Changes:* *-------------*
- Rename the function in Data.HashMap.Base (and expose it from Strict and Lazy modules) - Make lookupDefault an INLINE alias of findWithDefault - Add DEPRECATION notice to lookupDefault - Bump unordered-containers version to 0.2.9.0
*Migration - Option 1:*
*---------------------*
*- *Announce on Haskell communication channels (haskell-cafe@, haskell-community@, #haskell on Twitter, Reddit thread, etc.) - Users of unordered-containers >= 0.2.9.0 receive warning about deprecated function - Code can be updated by find and replace: s/lookupDefault/findWithDefault/ - lookupDefault with deprecation notice remains for 1 year (subject to change) - after 1 year the lookupDefault function is removed, unordered-containers version bumped to 0.3.0.0 (major version bump due to breaking change)
*Migration - Option 2:*
*---------------------*
- Announce on Haskell communication channels (haskell-cafe@, haskell-community@, #haskell on Twitter, Reddit thread, etc.) - Users of unordered-containers >= 0.2.9.0 receive warning about deprecated function - Code can be updated by find and replace: s/lookupDefault/findWithDefault/ - lookupDefault function is never removed
*Discussion: * *===========*
I would like to get some comments on this proposal. In particular: - Is the small API churn worth the increase in consistency? - 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.
I hope a decision about the proposal can be reached by 2018-02-09. Thanks!
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
participants (6)
-
amindfv@gmail.com
-
Andreas Abel
-
David Feuer
-
Henning Thielemann
-
Ivan Lazar Miljenovic
-
Matt Renaud