stdlib
stdlib copied to clipboard
Add `dict.change`?
Would there be interest in a dict.change (name to be determined) function? It's signature would look something like this:
pub fn change(
in dict: Dict(k, v),
update key: k,
with fun: fn(Option(v)) -> Option(v),
) -> Dict(k, v)
The semantics would be these:
- The returned
dictis the same as the inputdicton all keys except the givenkey. - The value for
keyis defined byfun:- If the
keyis not present in the dict, then the argument passed tofunisNone.- In this case, if
funreturnsNone, then thatkeyis not added to the map. - Else,
funreturnsSome(k), then thatkeyis added to the map and associated with the valuek.
- In this case, if
- If
keyis present in the dict, then the argument passed tofunisSome(k).- In this case, if
funreturnsNone, then thekeyand its associated value are removed from thedict. - Else,
funreturnsSome(k), then that key is newly associated with the valuek.
- In this case, if
- If the
Here are some other examples of this function:
- OCaml's stdlib calls this update
- OCaml's Base (stdlib replacement) calls this change
- Haskell's containers calls this alter
- Elixir's Map has get_and_update
See also this issue regarding dict.update/dict.upsert: https://github.com/gleam-lang/stdlib/issues/570
OCaml's stdlib calls this update OCaml's Base (stdlib replacement) calls this change Haskell's containers calls this alter Elixir's Map has get_and_update
OT: Reminds me of https://github.com/gleam-lang/gleam/discussions/1645 Maybe that idea could include an optional explanation why that alias exists, e.g. "similar to elixir get_and_update" or "reimplements ocaml update"
Let's use the name "update" after this has been actioned: https://github.com/gleam-lang/stdlib/issues/570
#570 has the update function becoming something like this:
dict.update return Result and Error if no key found
Which does make sense if the current update is renamed to upsert imo, given the sql naming of update/upsert. Whereas this function would need some other name.
I have re-read your proposal and AFAIU it now, change works on dicts with keys that can exist or not exist and depending if they exist or do not exist they can handle those cases by injecting values or even removing values if a key existed all depending on the apply function of the change call? I hope I got it.
I think update does not communicate that, update does not communicate that something is removed. alter or change communicate that something could be removed. Now that we have upsert I am in favour of alter over change but that's just me.
Closing this to track in the other issue. Thanks folks!
@mooreryan is this the impl you meant? https://github.com/gleam-lang/stdlib/pull/659
@mooreryan is this the impl you meant? #659
Looks like it, though I don't think that the function in that pull request should be called update. The callback in that PR is also returning a Result--that would not be my preference, however, I don't have a strong opinion about that aspect.
I think the general policy is that we do not return Option. I agree that it should be called change.