I've been following this debate with some interest, but I think it's gone beyond a noob discussion.
Is there a noob answer to this question? There ought to be. I'm sort of leaning toward:
Q. How do you empty a collection. A. You don't, you replace it with a new instance.
Q. What if you have references to the collection in multiple places? A. Wrap the collection in another class, and reference that.
??
On Tue, 19 Feb 2008 22:14:49 +0100, Blake wrote:
I've been following this debate with some interest, but I think it's gone beyond a noob discussion.
Is there a noob answer to this question? There ought to be. I'm sort of leaning toward:
Q. How do you empty a collection. A. You don't, you replace it with a new instance.
Q. What if you have references to the collection in multiple places? A. Wrap the collection in another class, and reference that.
??
Q. can I use #become: instead of wrapper? A. yes but the pro's don't like solutions with #become:, it smells
/Klaus
On Feb 19, 2008, at 10:36 PM, Klaus D. Witzel wrote:
On Tue, 19 Feb 2008 22:14:49 +0100, Blake wrote:
I've been following this debate with some interest, but I think it's gone beyond a noob discussion.
Is there a noob answer to this question? There ought to be. I'm sort of leaning toward:
Q. How do you empty a collection. A. You don't, you replace it with a new instance.
Q. What if you have references to the collection in multiple places? A. Wrap the collection in another class, and reference that.
??
Q. can I use #become: instead of wrapper? A. yes but the pro's don't like solutions with #become:, it smells
and it's slow in Squeak.
/Klaus
Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
Mth
On Tue, 19 Feb 2008 14:20:51 -0800, Mathieu Suen mathk.sue@gmail.com wrote:
On Feb 19, 2008, at 10:36 PM, Klaus D. Witzel wrote:
On Tue, 19 Feb 2008 22:14:49 +0100, Blake wrote:
I've been following this debate with some interest, but I think it's gone beyond a noob discussion.
Is there a noob answer to this question? There ought to be. I'm sort of leaning toward:
Q. How do you empty a collection. A. You don't, you replace it with a new instance.
Q. What if you have references to the collection in multiple places? A. Wrap the collection in another class, and reference that.
??
Q. can I use #become: instead of wrapper? A. yes but the pro's don't like solutions with #become:, it smells
and it's slow in Squeak.
Well, from what I was reading, "slow" and "smells" is putting it too mildly. It sounds like it can corrupt your image, i.e., leave you with non-working objects in unexpected places. I wouldn't even mention it.
On Tue, 19 Feb 2008 15:08:56 -0800, nicolas cellier ncellier@ifrance.com wrote:
Blake a écrit :
Well, from what I was reading, "slow" and "smells" is putting it too mildly. It sounds like it can corrupt your image, i.e., leave you with non-working objects in unexpected places. I wouldn't even mention it.
Huh? Have a proof of what you wrote?
Proof? None at all. I just have this, by Gulik:
"[become:] doesn't work fine. It breaks code that relies on hashes; specifically, a Dictionary elsewhere in yo ur image can start acting screwy if you do a #become: variant that doesn't preserve an object's hash. See #becomeForward>>copyHash:. You would then also be relying on a Squeakish behaviour and your code would become less portable across Sm alltalk dialects.
They are also a fantastic way to introduce bugs of various sorts, and can even cause an image to crash (as in, stack trace and exit to the OS). Say, for example, that one of the arguments you pass is accidently nil, true or false? Your image would c ontinue working... for a while."
Does this sound like something a newbie should use? No, it does not.
===Blake===
Blake a écrit :
On Tue, 19 Feb 2008 15:08:56 -0800, nicolas cellier ncellier@ifrance.com wrote:
Blake a écrit :
Well, from what I was reading, "slow" and "smells" is putting it too mildly. It sounds like it can corrupt your image, i.e., leave you with non-working objects in unexpected places. I wouldn't even mention it.
Huh? Have a proof of what you wrote?
Proof? None at all. I just have this, by Gulik:
"[become:] doesn't work fine. It breaks code that relies on hashes; specifically, a Dictionary elsewhere in yo ur image can start acting screwy if you do a #become: variant that doesn't preserve an object's hash. See #becomeForward>>copyHash:. You would then also be relying on a Squeakish behaviour and your code would become less portable across Sm alltalk dialects.
I see, become: does exchange #identityHash, and that makes our IdentityDictionary work, god thanks, but there is no such provision for ordinary #hash and Dictionary...
However, there are plenty of ordinary things that would have the same result:
| key1 key2 dic | key1 := 'abc' copy. key2 := 'abd' copy. dic := Dictionary new. dic at: key1 put: 1. dic at: key2 put: 2. key1 at: 1 put: $z. {dic includesKey: key1. dic keys includes: key1.}
So i propose newbies do not use #at:put: considering the danger about Dictionary not finding their keys... That's too much.
becomeForward: is squeakish, but the thread was about Squeak implementation of a core library... A rule is to use becomeForward: only with a just created object as argument. But right, that's just too much for this thread.
They are also a fantastic way to introduce bugs of various sorts, and can even cause an image to crash (as in, stack trace and exit to the OS). Say, for example, that one of the arguments you pass is accidently nil, true or false? Your image would c ontinue working... for a while."
Does this sound like something a newbie should use? No, it does not.
===Blake===
OK, good lesson, thank you. Handle with care. Try finding better patterns. Protect usage (don't use with an unknow argument). It smells. I agree. But don't pretend it's broken please.
Anyway, why do you think all code is accessible in Smalltalk? In the spirit, nothing is to be hidden from newbies eyes. Yes I know, maybe some code should
On Tue, 19 Feb 2008 15:59:57 -0800, nicolas cellier ncellier@ifrance.com wrote:
However, there are plenty of ordinary things that would have the same result:
| key1 key2 dic | key1 := 'abc' copy. key2 := 'abd' copy. dic := Dictionary new. dic at: key1 put: 1. dic at: key2 put: 2. key1 at: 1 put: $z. {dic includesKey: key1. dic keys includes: key1.}
So i propose newbies do not use #at:put: considering the danger about Dictionary not finding their keys...
This seems pretty bad to me, too, but it seems more designed to break a known weakness than to actually accomplish something. You know, like empty a collection.<s>
But I'd probably argue that the above should work, and that it's a design flaw that it doesn't.
Anyway, why do you think all code is accessible in Smalltalk? In the spirit, nothing is to be hidden from newbies eyes. Yes I know, maybe some code should
There's a positive fetish about this. I'm all for everything being accessible. But everything being equally accessible all the time is not pragmatic.
Blake a écrit :
On Tue, 19 Feb 2008 15:59:57 -0800, nicolas cellier ncellier@ifrance.com wrote:
However, there are plenty of ordinary things that would have the same result:
| key1 key2 dic | key1 := 'abc' copy. key2 := 'abd' copy. dic := Dictionary new. dic at: key1 put: 1. dic at: key2 put: 2. key1 at: 1 put: $z. {dic includesKey: key1. dic keys includes: key1.}
So i propose newbies do not use #at:put: considering the danger about Dictionary not finding their keys...
This seems pretty bad to me, too, but it seems more designed to break a known weakness than to actually accomplish something. You know, like empty a collection.<s>
Yes, the example is dumb, but that's the kind of thing that happens in real code (just split contructing/changing keys/accessing in three different methods). No use to forbid become: for this reason, there are better reasons (it's sloooow), become: usage was sponsored once upon a time when it was fast, providing both efficient and generic solutions.
But I'd probably argue that the above should work, and that it's a design flaw that it doesn't.
Yes, but it is very hard to make it work efficiently. So that's a limitation we must be aware of.
Anyway, why do you think all code is accessible in Smalltalk? In the spirit, nothing is to be hidden from newbies eyes. Yes I know, maybe some code should
There's a positive fetish about this. I'm all for everything being accessible. But everything being equally accessible all the time is not pragmatic.
On Feb 20, 2008 2:17 PM, nicolas cellier ncellier@ifrance.com wrote:
Blake a écrit :
On Tue, 19 Feb 2008 15:59:57 -0800, nicolas cellier ncellier@ifrance.com wrote:
<snip>
Could we please move this discussion to squeak-dev please? We're going to scare the beginners.
Gulik.
On Wed, 20 Feb 2008 00:59:57 +0100, nicolas cellier wrote:
...
I see, become: does exchange #identityHash, and that makes our IdentityDictionary work, god thanks, but there is no such provision for ordinary #hash and Dictionary...
But there are sufficient provisions in place, since Smalltalk-80, and most Dictionary users know about them :)
However, there are plenty of ordinary things that would have the same result:
| key1 key2 dic | key1 := 'abc' copy. key2 := 'abd' copy. dic := Dictionary new. dic at: key1 put: 1. dic at: key2 put: 2. key1 at: 1 put: $z.
dic rehash "synopsis: re-establish hash invariants, if any ".
{dic includesKey: key1. dic keys includes: key1.}
So i propose newbies do not use #at:put: considering the danger about Dictionary not finding their keys...
There's no danger with Dictionary not finding its keys, unless you yourself do not follow the protocol.
Smalltalk has no such problems; developers use #rehash after they changed the #= of keys in Set and subclasses; and please, don't tell the newcomers the contrary :)
That's too much.
No not too much; in other languages (especially the "popular" ones) you are not even allowed to change you strings-now *that* is too much ;-)
But in Smalltalk you are supported, right from the beginning; happy Smalltalking everybody :)
/Klaus
Klaus D. Witzel a écrit :
On Wed, 20 Feb 2008 00:59:57 +0100, nicolas cellier wrote:
...
I see, become: does exchange #identityHash, and that makes our IdentityDictionary work, god thanks, but there is no such provision for ordinary #hash and Dictionary...
But there are sufficient provisions in place, since Smalltalk-80, and most Dictionary users know about them :)
However, there are plenty of ordinary things that would have the same result:
| key1 key2 dic | key1 := 'abc' copy. key2 := 'abd' copy. dic := Dictionary new. dic at: key1 put: 1. dic at: key2 put: 2. key1 at: 1 put: $z.
dic rehash "synopsis: re-establish hash invariants, if any ".
{dic includesKey: key1. dic keys includes: key1.}
So i propose newbies do not use #at:put: considering the danger about Dictionary not finding their keys...
There's no danger with Dictionary not finding its keys, unless you yourself do not follow the protocol.
Smalltalk has no such problems; developers use #rehash after they changed the #= of keys in Set and subclasses; and please, don't tell the newcomers the contrary :)
Agree. Thanks for this good lesson based on my so dumb example. Wouldn't this deserve a longer (Dictionary comment) ?
That's too much.
No not too much; in other languages (especially the "popular" ones) you are not even allowed to change you strings-now *that* is too much ;-)
But in Smalltalk you are supported, right from the beginning; happy Smalltalking everybody :)
/Klaus
Too much was the idea of forbidding #become: or #at:put: for a wrong reason (Dictionary rehash).
Nicolas
On Wed, 20 Feb 2008 22:12:57 +0100, nicolas cellier wrote:
Klaus D. Witzel a écrit :
On Wed, 20 Feb 2008 00:59:57 +0100, nicolas cellier wrote: ...
I see, become: does exchange #identityHash, and that makes our IdentityDictionary work, god thanks, but there is no such provision for ordinary #hash and Dictionary...
But there are sufficient provisions in place, since Smalltalk-80, and most Dictionary users know about them :)
However, there are plenty of ordinary things that would have the same result:
| key1 key2 dic | key1 := 'abc' copy. key2 := 'abd' copy. dic := Dictionary new. dic at: key1 put: 1. dic at: key2 put: 2. key1 at: 1 put: $z.
dic rehash "synopsis: re-establish hash invariants, if any ".
{dic includesKey: key1. dic keys includes: key1.}
So i propose newbies do not use #at:put: considering the danger about Dictionary not finding their keys...
There's no danger with Dictionary not finding its keys, unless you yourself do not follow the protocol. Smalltalk has no such problems; developers use #rehash after they changed the #= of keys in Set and subclasses; and please, don't tell the newcomers the contrary :)
Agree. Thanks for this good lesson based on my so dumb example. Wouldn't this deserve a longer (Dictionary comment) ?
You're right, the invariant is *essential* for Set and its subclasses, alas no word about it in its class comment. Please open a bug report (with severity "text"); current policy is that this then gets included in the next release.
That's too much.
No not too much; in other languages (especially the "popular" ones) you are not even allowed to change you strings-now *that* is too much ;-) But in Smalltalk you are supported, right from the beginning; happy Smalltalking everybody :) /Klaus
Too much was the idea of forbidding #become: or #at:put: for a wrong reason (Dictionary rehash).
Nicolas
Klaus D. Witzel a écrit :
Wouldn't this deserve a longer (Dictionary comment) ?
You're right, the invariant is *essential* for Set and its subclasses, alas no word about it in its class comment. Please open a bug report (with severity "text"); current policy is that this then gets included in the next release.
Feel free to correct or complete http://bugs.squeak.org/view.php?id=6942
Maybe a reminder 'See also Set comment in Dictionary comment' would be welcome.
Cheers
Nicolas
On Thu, 21 Feb 2008 21:44:05 +0100, nicolas cellier wrote:
Klaus D. Witzel a écrit :
Wouldn't this deserve a longer (Dictionary comment) ?
You're right, the invariant is *essential* for Set and its subclasses, alas no word about it in its class comment. Please open a bug report (with severity "text"); current policy is that this then gets included in the next release.
Feel free to correct or complete http://bugs.squeak.org/view.php?id=6942
Done, added the ANSI wording :)
Maybe a reminder 'See also Set comment in Dictionary comment' would be welcome.
Sure.
Cheers
Nicolas
nicolas cellier a écrit :
Blake a écrit :
Well, from what I was reading, "slow" and "smells" is putting it too mildly. It sounds like it can corrupt your image, i.e., leave you with non-working objects in unexpected places. I wouldn't even mention it.
Huh? Have a proof of what you wrote?
Ah i see, you mean dangerous if used without care, like Smalltalk become: Float. (this one is not very dangerous, just crash your image).
But become: is still essential for operations like growing the MethodDictionary when you add new methods to a class, or migrate allInstances when you a or remove an instance variable to a class, to name few. So, it is not bogus. Just handle with care.
Nicolas
On Tue, 19 Feb 2008 15:19:40 -0800, nicolas cellier ncellier@ifrance.com wrote:
But become: is still essential for operations like growing the MethodDictionary when you add new methods to a class, or migrate allInstances when you a or remove an instance variable to a class, to name few. So, it is not bogus. Just handle with care.
OK. Does a newbie need to use it? To empty a collection? (Or whatever?)
I'm trying to get at what should be a very simple thing without going to the metal, as it were.
One thing I wasn't clear on is whether Bert's suggestion:
aColl removeAllSuchThat: [:anElement| true].
Is okay, and why it's okay while many of the other similar approaches were not.
Blake a écrit :
On Tue, 19 Feb 2008 15:19:40 -0800, nicolas cellier ncellier@ifrance.com wrote:
But become: is still essential for operations like growing the MethodDictionary when you add new methods to a class, or migrate allInstances when you a or remove an instance variable to a class, to name few. So, it is not bogus. Just handle with care.
It seems that we are crossing all our posts!
OK. Does a newbie need to use it? To empty a collection? (Or whatever?)
Only an advanced newbie :) and in very rare case. For squeak core library removeAll, - pros: very generic - cons: #become: is not efficient, especially in large images. In fact, most #become: usages inherited from Smalltalk-80 have been removed from Squeak for this reason. It's wise not to reintroduce them.
I'm trying to get at what should be a very simple thing without going to the metal, as it were.
Unfortunately, modifying a core library has such implications.
One thing I wasn't clear on is whether Bert's suggestion:
aColl removeAllSuchThat: [:anElement| true].
Is okay, and why it's okay while many of the other similar approaches were not.
Bert's suggestion is simple and works well. The only question is about efficiency. Up to (Down to?) subclasses to optimize it.
Some proposed an alternative based on (self removeAll: self), and started writing optimized versions of #removeAll:.
I think our biggest problem is that we have plenty possible ways to do it... Finding a balance between genericity and efficiency...
Nicolas
On Wed, 20 Feb 2008 02:01:49 +0100, nicolas cellier wrote:
...
Bert's suggestion is simple and works well. The only question is about efficiency. Up to (Down to?) subclasses to optimize it.
Some proposed an alternative based on (self removeAll: self), and started writing optimized versions of #removeAll:.
No, (anOrderedCollection removeAll: anOrderedCollection) was not optimized. It had a *very* long known bug, which was fixed. Please do less mixing of subjects in threads.
I think our biggest problem is that we have plenty possible ways to do it... Finding a balance between genericity and efficiency...
No, more correctness at the price of less efficiency :)
Nicolas
Klaus D. Witzel a écrit :
On Wed, 20 Feb 2008 02:01:49 +0100, nicolas cellier wrote:
Some proposed an alternative based on (self removeAll: self), and started writing optimized versions of #removeAll:.
No, (anOrderedCollection removeAll: anOrderedCollection) was not optimized. It had a *very* long known bug, which was fixed. Please do less mixing of subjects in threads.
OK, I'm extrapolating. In this case, while you are at it:
| aSet | aSet :='Klaus' asSet. aSet removeAll: aSet. aSet | aHeap | aHeap := Heap withAll: 'Witzel'. aHeap removeAll: aHeap. aHeap
I would have used my name, but it seems i am removeable ;-) | aSet | aSet :='Cellier' asSet. aSet removeAll: aSet. aSet
Try with the collection of your choice.
In the mean time, don't use (self removeAll: self)... Yes i'm mixing threads,should be How to NOT empty a collection ;-)
Nicolas
I think our biggest problem is that we have plenty possible ways to do it... Finding a balance between genericity and efficiency...
No, more correctness at the price of less efficiency :)
Nicolas
Agree on this one. Then allow removeAllSuchThat: as default implementation.
Nicolas
On Wed, 20 Feb 2008 23:05:47 +0100, nicolas cellier wrote:
Klaus D. Witzel a écrit :
On Wed, 20 Feb 2008 02:01:49 +0100, nicolas cellier wrote:
Some proposed an alternative based on (self removeAll: self), and started writing optimized versions of #removeAll:.
No, (anOrderedCollection removeAll: anOrderedCollection) was not optimized. It had a *very* long known bug, which was fixed. Please do less mixing of subjects in threads.
OK, I'm extrapolating.
O.K. the fix from OrderedCollection *could* be applied to Set (the fix requires #copyEmpty), but see Heap below.
In this case, while you are at it:
| aSet | aSet :='Klaus' asSet. aSet removeAll: aSet. aSet
| aHeap | aHeap := Heap withAll: 'Witzel'. aHeap removeAll: aHeap. aHeap
Don't use Heap much, it is not very conformant; example: (Heap withAll: 'array') reject: [:x | x = $r] => an Array. Perhaps people didn't know about *all* senders of #species ...
I would have used my name, but it seems i am removeable ;-) | aSet | aSet :='Cellier' asSet. aSet removeAll: aSet. aSet
Try with the collection of your choice.
In the mean time, don't use (self removeAll: self)...
One step after the other :) no doubt #removeAll: gets fixed, perhaps in the next release?
Yes i'm mixing threads,should be How to NOT empty a collection ;-)
Nicolas
I think our biggest problem is that we have plenty possible ways to do it... Finding a balance between genericity and efficiency...
No, more correctness at the price of less efficiency :)
Nicolas
Agree on this one. Then allow removeAllSuchThat: as default implementation.
Nicolas
On Feb 20, 2008, at 2:01 , nicolas cellier wrote:
One thing I wasn't clear on is whether Bert's suggestion: aColl removeAllSuchThat: [:anElement| true]. Is okay, and why it's okay while many of the other similar approaches were not.
Bert's suggestion is simple and works well. The only question is about efficiency. Up to (Down to?) subclasses to optimize it.
#removeAllSuchThat: is actually optimized in subclasses (look at its implementation in OrderedCollection).
- Bert -
Ok, I reimplemented this method as Bert suggested and in the next version of Aida/Web it will be:
OrderedCollection>>removeAll "remove all elements quickly" self removeAllSuchThat: [:each | true]. "Squeak specific" " self become: OrderedCollection new " "VW specific"
Note that this method is still an extension of Aida and it must therefore be portable among dialects, which is the reason of commented code for VW above.
Best regards Janko
Bert Freudenberg wrote:
On Feb 20, 2008, at 2:01 , nicolas cellier wrote:
One thing I wasn't clear on is whether Bert's suggestion: aColl removeAllSuchThat: [:anElement| true]. Is okay, and why it's okay while many of the other similar approaches were not.
Bert's suggestion is simple and works well. The only question is about efficiency. Up to (Down to?) subclasses to optimize it.
#removeAllSuchThat: is actually optimized in subclasses (look at its implementation in OrderedCollection).
This is the last change, I promise :) Previous solution was for collections in general, while for OrderedCollection you can simply do:
self setCollection: Array new.
A bit optimized method will therefore be:
removeAll "remove all elements quickly" self setCollection: (Array new: 10). "Squeak specific" self become: OrderedCollection new " "VW specific"
Janko
Janko Mivšek wrote:
Ok, I reimplemented this method as Bert suggested and in the next version of Aida/Web it will be:
OrderedCollection>>removeAll "remove all elements quickly" self removeAllSuchThat: [:each | true]. "Squeak specific" " self become: OrderedCollection new " "VW specific"
Note that this method is still an extension of Aida and it must therefore be portable among dialects, which is the reason of commented code for VW above.
Best regards Janko
Bert Freudenberg wrote:
On Feb 20, 2008, at 2:01 , nicolas cellier wrote:
One thing I wasn't clear on is whether Bert's suggestion: aColl removeAllSuchThat: [:anElement| true]. Is okay, and why it's okay while many of the other similar approaches were not.
Bert's suggestion is simple and works well. The only question is about efficiency. Up to (Down to?) subclasses to optimize it.
#removeAllSuchThat: is actually optimized in subclasses (look at its implementation in OrderedCollection).
beginners@lists.squeakfoundation.org