mirror of
https://github.com/ruuda/rcl.git
synced 2025-12-23 04:47:19 +00:00
The map function in particular is a footgun that hit me twice in two
weeks, in a case similar to this one:
{"apple", "orange", "banana"}.map(x => x.len()).sum()
This looks like it sums the lengths of the strings. Except it doesn't,
it sums the *unique* lengths of the strings, so we get 11 instead of 17.
That's surprising, and I don't want that kind of surprise in RCL.
At first I thought to remove Set.map and Set.flat_map entirely. You
would just have to convert to a list first and map there, and if you
wanted the set, convert back with List.to_set_dedup, which makes it
explicit. That's why I added these conversion functions. Then I
implemented deletion ... and as I was writing the PR description and
changelog entry for how to handle the break, it dawned on me, if we
have the _dedup anyway in to_set_dedup, we might as well use it here.
We don't have to delete these methods, we can just call them _dedup.
{"apple", "orange", "banana"}.map_dedup(x => x.len()).sum()
Now the snippet is no longer so sneaky! It's clear that there is
deduplication going on! So I'm fine keeping them in this form. At least
in the Nix transitive closure test, the map_dedup behavior is what I
want, which validates demand for at least map_dedup. But even then,
a changelog entry for a breaking change that says "renamed to X" is a
much better experience than "have been deleted here are some much longer
alternatives".
Also, this change is relatively safe to make: it will break existing
callers, but they will get an error message and there is a clear path
to fixing this. It doesn't silently change the output of something: it's
being called on sets, so there can't even be fields named 'map' or
'flat_map' because sets don't have fields. So I feel comfortable making
a small breaking change here.
|
||
|---|---|---|
| .. | ||
| abstraction.rs | ||
| ast.rs | ||
| cli.rs | ||
| cli_utils.rs | ||
| cmd_build.rs | ||
| cmd_eval.rs | ||
| cst.rs | ||
| decimal.rs | ||
| env.rs | ||
| error.rs | ||
| eval.rs | ||
| fmt_cst.rs | ||
| fmt_json.rs | ||
| fmt_json_lines.rs | ||
| fmt_raw.rs | ||
| fmt_rcl.rs | ||
| fmt_toml.rs | ||
| fmt_type.rs | ||
| fmt_yaml_stream.rs | ||
| highlight.rs | ||
| lexer.rs | ||
| lib.rs | ||
| loader.rs | ||
| main.rs | ||
| markup.rs | ||
| parser.rs | ||
| patch.rs | ||
| pprint.rs | ||
| runtime.rs | ||
| source.rs | ||
| stdlib.rs | ||
| string.rs | ||
| tracer.rs | ||
| type_diff.rs | ||
| type_source.rs | ||
| typecheck.rs | ||
| types.rs | ||