note that add was deprecated, which was IIRC the only way to get dups
proc add[A, B](t: TableRef[A, B]; key: A; val: sink B) {.deprecated: "Deprecated since v1.4; it was more confusing than useful, use `[]=`".}
Even beyond @juancarlospaco's excellent point, the values for duplicate keys differ, yet pop returns just one. It would hurt ergonomics for the common case of user-maintained unique keys to have pop take a var seq[V], for example.
It has been discussed to have del take an optional all=false parameter to do the loop. I think that discussion is buried somewhere on some github sub-thread.
I disagree with the deprecation personally. There are several reasonably good use cases for it (and @exoticisotopic - I, for one, would be curious about yours) and the feature has existed since the very first releases of Nim back in Aug 2008. While you can always do a seq[V] value type, the space/speed performance characteristics are simply distinct. Allowing it does add a burden on the user to not put many dup keys in place (or else pump up how much probing has to happen).
FWIW, the pushback was mostly confusion about "how hash tables can do that?" because it is very uncommon to provide the ability in other prog.lang data structure facilities. Since people mostly learn and sometimes even remember by example/mimicry this caused cognitive dissonance. Nim, of course, provides many uncommon abilities, though. So, while one could view it as "choosing ones battles", in this case nothing was forcing that choice.
If you do really need this, I provide (and never, ever plan to remove) this ability in my adix/lptabz which also has a gazillion knobs you can tune for performance including zero/etc. sentinels instead of saved hash code as an option, compact insertion-ordered or not, Robin-Hood hashing or not, various kinds of resize policies, and an ability to detect when your hash function might be under attack and respond accordingly.
So, while one could view it as "choosing ones battles", in this case nothing was forcing that choice.
Many people used add by accident. Now that could have been fixed by using a different name like addAllowForDuplicate but then the implementation of del (and actually every other operation) is forced to handle duplicates and that seemed rather constraining in the long run.
Rampant misuse (if it is common) may be a choice forcing argument. This misuse comes from lack of attention to docs for which there is another solution - better/more attention-getting docs Re: surprising features. That could be attempted before removing old functionality.
FWIW, my vague recollection of the logical sense of the github debate was "Too surprising - even 'boldface/Table allows dups' would have been insufficient to overcome my (implicitly overstrong) preconceptions." I like to have more faith in people than that.
It may be constraining. critbits can have no add, for example or direct mapped (like array[char]) indices. These feel like special cases, though. Most associative structures like BSTs, skip lists, B-trees allow "inline dups" with similarly distinct space/speed/indirection trade offs an "external dups" like the seq[V] solution.
So, while one must make psychological guesses about surprise & docs and technological predictions about needs -- I feel/felt both of these did not rise to the "remove long standing functionality" level..Reasonable people could disagree on such judgement calls, I suppose, and maybe learning to not totally rely on the stdlib earlier in one's Nim exposure is not a bad lesson, especially for people coming from Python/scripting domains where such reliance is heavily performance-motivated.
In any event, since @exoticisotopic seems new to Nim and seems to be reading & understanding docs (gasp!), and TC brought up removal, and the debate is buried on github, and 1.6 is probably coming up, I thought a "back story" should be told. :-)
I also remain curious if @exoticisotopic has another use case in mind or is just carefully reading docs. Please don't be shy! :-) To my own surprise, I found a (performance, as it must be) use case for inline Table dups within a few months of the deprecation debate. But I can easily just switch to an adix/lptabz dependency which might be faster anyway.
Well, as explained since most instances of Table do not have dups, pop would at least need a separate overload taking a var seq, and the idea came up for del, but people decided they preferred to instead just deprecate dup keys.
So, why did this feature not exist for 13 years to relieve client code of loops? Well, it's open source and understaffed. Features rely upon passions of feature adders and a judgement call about how often they are needed. Deletion itself is often unnecessary and did not work right for half of that time (and not working was not noticed!).
I would be willing to add these to adix/lptabz, though, especially if you wanted to do a PR.