haskell / containers

Assorted concrete container types
https://hackage.haskell.org/package/containers
315 stars 178 forks source link

Add "Unsafe" modules #1026

Open treeowl opened 1 month ago

treeowl commented 1 month ago

The API currently exposes a few functions that break the abstraction barrier and sometimes allow the construction of invalid structures. We should collect those in separate modules, with the hope of eventually removing them from the "safe" interface.

meooow25 commented 4 weeks ago

I know I suggested this in https://github.com/haskell/containers/pull/1025#issuecomment-2286914198, but it needs more thought 😄

What would be the distinction between Map.Internal and Map.Unsafe in this case?

treeowl commented 4 weeks ago

I think of Unsafe as having much stronger stability expectations than Internal.

meooow25 commented 4 weeks ago

That sounds fine in theory, but in practice I haven't seen Internal modules being unstable at all (at least since I have been paying attention to it).

I'm just trying to see if we can avoid having too many modules.

Alternative option 1: We make Internal stable (and it follows PVP) and move unsafe functions there.

Alternative option 2 (more drastic): We add Unsafe but hide Internal. Unsafe is stable. The exports in the public module and the exports in the Unsafe module are disjoint and together make up the Internal module.

meooow25 commented 4 weeks ago

To get a sense of things,

List of functions in Data.Map.Lazy that can violate Map invariants:

More functions in Data.Map.Internal that can violate Map invariants:

treeowl commented 4 weeks ago

That sounds fine in theory, but in practice I haven't seen Internal modules being unstable at all (at least since I have been paying attention to it).

You write this just a couple months after changing the internal representations of IntSet and IntMap!

meooow25 commented 4 weeks ago

That's true but it is a rare event 😄 IntMap hasn't changed in ~19 years. IntSet has changed once ~13 years ago (packed tips added).