(no title)
cronjobber | 8 years ago
My only complaint about FSet would be map default values; not necessarily the fact they exist, but (1) when using defaults, that two maps can compare equal even though they have different defaults, and (2) when not using defaults, the way they nevertheless intrude upon the map-union protocol, necessitating handling of otherwise unused default values (usually NIL).
But I love FSet when using CL. Thank you for writing and publishing it!
ScottBurson|8 years ago
Agreed on both counts about map default values. I've been wanting to change how they work, but the change I have in mind would be incompatible. Here's what I'm thinking. Instead of every map (and seq) having a default, which defaults to NIL, we would distinguish maps with defaults from those without. Doing LOOKUP on a defaultless map at a key it has no mapping for would signal a condition (similarly for an out-of-bounds lookup on a defaultless seq). Then the defaultless versions could be used more conveniently with UNION (and COMPOSE, another place where I've tripped over this problem).
I was thinking that creating a map without supplying a default should give you a defaultless map, and that's how I wish I had done it from the beginning, but making it work that way now would break a lot of code. I could release it as a new major version (and call it "fset-2" in Quicklisp so people don't pull it down accidentally). Or, I could leave the existing constructor behavior unchanged and just add a new defaultless map (and seq) constructor. I think this is considerably less elegant, but it wouldn't break existing code. What do you think?
cronjobber|8 years ago
I have no way of knowing how such changes would affect the wider installed base of FSet. All I can tell you is what I'd prefer myself.
I wouldn't mind, and actually prefer, if the default SEQ would signal a condition on out-of-bounds access (I'd also suspect that not a lot of existing code would break, but there's no way for me to know that.)
On the other hand, I don't think I'd get much besides having to rewrite code out of map lookups signaling a condition. I glossed over my uses of LOOKUP. For most lookups, the case of some element not being present in the map is normal behavior, expected and handled.
For a minority, an element not being present is an error, but for a majority of those, a specific error message is appropriate, so there'd still be explicit checking and no advantage from signaling within LOOKUP.
The smallest group of LOOKUPS expects the lookup to succeed without checking. In all of these cases, the lookup will succeed unless some code is buggy, and in all cases, a bogus NIL would be consumed immediately by a function that would signal a condition on getting a NIL.
So my personal favorite default kind of map would return (VALUES NIL NIL) for lookup failures but would not have a default for purposes of the MAP-UNION etc protocols.
An alternative (or additional) change that would work for me would be an additional optional function parameter to MAP-UNION and friends which, if present, would handle default values.