Is a Set still a Set if it silently drops elements?

This is a design/philosophical question.
I have and use a Buffer implementation which has a maximum size, and will drop elements from the front as new elements are added at the back - a useful mini tool for working with windows over other collections. Similarly, I have an immutable CappedSet which serves as a LRU cache with an upper bound on the number of elements: when new elements are added to a full set, the returned set will not contain the same number of least recently used elements.

However, I now have doubts if I should have implemented Buffer and immutable.Set at all, as the contract is altered, which may potentially lead to confusion. What’s your take on both cases? Does it differ between mutable and immutable collections? In a sense, the immutable way of creating new collections from old ones is distinct from the nature of the collection itself, or how elements may be accessed. Dropping standard interfaces will considerably reduce the usability: Set.intersect et.al. will not work with a CappedSet, all existing copyToBuffer methods wouldn’t be possible to use.

A conceivable compromise would be to extend only Iterable, but mix in SetOps[E, CappedSet, CappedSet[E]]/SeqOps[E, WindowBuffer, WindowBuffer[E]]. Lack of these interfaces would hurt the most, as they expose exactly the API I need, just with some semantic changes, and the implementations of the majority of methods there works just as well under new circumstances. What’s the least surprising solution in your minds?

Are you mixing up your buffer and capped set instances with anything else at runtime (thus requiring some common trait / interface - let’s leave union types out of this for now)?

Are you writing a library for reuse by third parties, or are these just used in one place as a one-off?

If the answer to both of those questions is ‘no’, I would drop the trait hierarchy obligations and just get on with using the concrete class types.

Otherwise, my suggestion was going to be to use some kind of set or seq view type from the standard library as your extended trait - I’m presuming these will approximate a ‘just queries, no building of new instances’ policy so you can side step the question of whether a capped set is indeed a fully-fledged set.

Your own suggestion of using SetOps sounds better not me, though.