doc: add CompareOptions.filterer#18
Conversation
gibson042
left a comment
There was a problem hiding this comment.
I'm a little torn on this, but leaning towards opposition. The only advantage of passing in a predicate rather than applying it to iterator output is that it allows filtering to affect boolean output. But it comes at the cost of making that mode intertwine implementation code with user code, which almost always incurs a performance penalty. I think it's easy enough to get boolean output like const isDifferent = !!deviations.filter(filterer).next().value, and if that much ceremony is too unergonomic then we can push to fix it with a new iterator helper, e.g. const isDifferent = !deviations.filter(filterer).isEmpty().
|
|
||
| ```ts | ||
| type CompareOptions = { | ||
| filterer?: (a: unknown, b: unknown) => boolean, |
There was a problem hiding this comment.
What inputs are expected for a and b? If they're values in the object graph, then how does a filterer differentiate
- extra vs. missing vs. mismatch
- property descriptor
- prototype
or just in general, where in the graph its invocation relates to?
There was a problem hiding this comment.
Ah, yes, I suppose the type of A and B are not unknown: they're a primitive (or "special" key). And a couple things are missing.
So I guess the type would be more like:
| filterer?: (a: unknown, b: unknown) => boolean, | |
| filterer?: ( | |
| a: Primitive, | |
| b: Primitive, | |
| path: (string | Symbol)[], | |
| reason: 'extra' | 'missing' | 'mismatch', | |
| ) => boolean, |
For descriptor, I think we already covered this: A and/or B would have that special key in path (which was missing before, so that probably created the confusion).
RE the "special" path segment, what about a well-known symbol, like Symbol(Deviation:Descriptor) & Symbol(Deviation:Prototype) (or Symbol(DescriptorDeviation) & Symbol(PrototypeDeviation))? I think I'd prefer the : delimited version.
Thoughts on mismatch → unequal, equality, or maybe even the equality algo used like same-zero? mismatch seems a little "shit happened" to me 😅
This isn't about getting a boolean; it's purely about performance (and maybe a little bit about DX—but not related to boolean).
Before I opened this, I checked with Oli, who said this would likely have relatively significant perf benefits:
|
As noted by Justin in the May plenary, this could have quite some advantages (performance, such as avoiding the needless expense of constructing an Iterator just to immediately exclude all its items).