"Richard A. O'Keefe" ok@cs.otago.ac.nz wrote: [... inline the assertions, too ...]
That's an interesting way to look at the situation, but do note that most Smalltalkers will be suprised to find those assertions or corrections in removeAll:. Most fooAll: methods just do: on the argument and foo: each element, and have no particular protection against #foo: modifying the argument.
It's unreasonable to do full proofs of correctness, and it's unhelpful to point the finger and say it's so and so's responsibility to do such an unreasonable thing.
Nobody has suggested proofs of correctness, only (1) reasonable testing and (2) not throwing away guard code.
| x | x := self allFooishMembers. self removeNonTrueBelievers. "at this point, is x the same as it was up above? you'd like it to be!!"
This is discussed in the Smalltalk Style Guide, which is currently at home or I'd cite the page number. I argued at length (only to be jumped on hard by A----- G-------) that objects shouldn't hand out references to their innards, and if they do, they don't have a usable class invariant any more. In different language, the Smalltalk Style Guide suggests handing out _new_ collections as a good thing to do.
This is actually the point of view I'm coming from. If you follow this style guideline fervently, then you never have to worry about "a removeAll: b" with a==b. If you like the guideline but would are lazy in its implementation, then you'd like to get warnings whenever you violate it in an erroneous or even borderline situation. When, precisely, would a programmer want to do "a removeAll: b" where a==b ? It seems like you have to completely disdain the above guideline if you conciously write such code.
-Lex