So one thing I noticed with the standard lib is that we expose a few odd Dict function that I think are only exposed to support the existance of Set. the functions are insertAll, keepShared, and removeAll.
The main reason these functions are weird is their APIs. For example, with insertAll, we are kinda performing the union of two dictionaries. That being said, we always keep the values of the first dictionary. This seems odd. So if I have a dictionary { a: 1, b: 2, c: 3 } and call insertAll on it with { c: 4, d: 5 }, the output would be: { a: 1, b: 2, c: 3, d: 5 } (note: c is 3, not 4).
Next, for keepShared, it keep elements only by looking at the keys and not the values (which feel very unintuitive). If you call it on { a: 1, b: 2, c: 3 } and { a: 4, b: 5, c: 6 }, the output will be { a: 1, b: 2, c: 3 }.
Finally, removeAll. My only issue with removeAll is that the second input should be a list or set of keys. It doesn't make sense for it to be a Dict with values. As an example, calling removeAll with { a: 1, b: 2, c: 3 } and { c: 4, d: 5 } leads to { b: 2, c: 3 } which again feels very weird do to the different values and really only caring about keys.
These functions I believe were only added to create Set.union, Set.intersection, and Set.difference. In the case of sets, these functions make sense, but I don't think they should, at least in there current form should be exposed from dictionaries.
Just looking for general thoughts around the api and what functions make sense to expose
I agree with your assessment of removeAll, it should probably take a container of keys instead (or not be a function exposed by Dict at all)
For keepShared and insertAll I think a useful function to expose instead of those would be something like
Dict.merge : Dict k v, Dict k v, ([Both k v v] -> v)
that takes two dicts and merges their disjoint keys, and for shared key/value pairs, you call a callback to determine what should be put in place
I find myself using something like the last API a lot in OCaml, though of course it's not that common in langs like c++/rust
Question: Can we somehow expose a function from Dict.roc to Set.roc without exposing it in the Standard Libary? I guess we would have to Make InternalDict.roc that doesn't get exposed in the standard library at all. Then make Dict.roc and Set.roc both import that and choose what to expose?
Yeah, we can do that, or hack around exposing functions in the compiler implementation
We have to do the latter anyway for reasons
yeah I like that idea
Last updated: Jun 16 2026 at 16:19 UTC