How to empty a collection?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
42 messages Options
123
Reply | Threaded
Open this post in threaded view
|

How to empty a collection?

Sophie424
I want to clear its contents (size goes back to zero), and can't seem to
find something like #clear or #empty. Cannot use a new collection as there
are shared references to it.

Thanks - Sophie



_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: How to empty a collection?

Marcin Tustin
Some kind of facade that holds a collection, and replaces it with an empty one when you call #empty? You could forward all other calls.

On Feb 18, 2008 7:41 PM, itsme213 <[hidden email]> wrote:
I want to clear its contents (size goes back to zero), and can't seem to
find something like #clear or #empty. Cannot use a new collection as there
are shared references to it.

Thanks - Sophie



_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: How to empty a collection?

cedreek
In reply to this post by Sophie424
I would do:

aCollection removeAll: aCollection

Also, I have Aida in my image and I have:

OrderedCollection>>removeAll
        "remove all elements quickly"
        self become: OrderedCollection new

but not sure this way is good because of #become:. I don't know either
if this will keep your references.

hth

Cédrick

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: How to empty a collection?

Bert Freudenberg
In reply to this post by Sophie424

On Feb 18, 2008, at 20:41 , itsme213 wrote:

> I want to clear its contents (size goes back to zero), and can't  
> seem to
> find something like #clear or #empty. Cannot use a new collection  
> as there
> are shared references to it.


myCollection removeAllSuchThat: [:each | true]

- Bert -


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

RE: How to empty a collection?

Ron Teitelbaum
In reply to this post by Sophie424
Hi Sophie,

aCollection copy do: [:anElement |
        aCollection remove: anElement
].

Why copy?  If you start removing items from the collection, increasing the
index will cause you to skip elements.  

Ron

> -----Original Message-----
> From: itsme213
>
> I want to clear its contents (size goes back to zero), and can't seem to
> find something like #clear or #empty. Cannot use a new collection as there
> are shared references to it.
>
> Thanks - Sophie


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: How to empty a collection?

Marcin Tustin
Isn't Cedrick's aida solution going to be significantly faster?

On Feb 19, 2008 1:02 AM, Ron Teitelbaum <[hidden email]> wrote:
Hi Sophie,

aCollection copy do: [:anElement |
       aCollection remove: anElement
].

Why copy?  If you start removing items from the collection, increasing the
index will cause you to skip elements.

Ron

> -----Original Message-----
> From: itsme213
>
> I want to clear its contents (size goes back to zero), and can't seem to
> find something like #clear or #empty. Cannot use a new collection as there
> are shared references to it.
>
> Thanks - Sophie


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: How to empty a collection?

cedreek
> Isn't Cedrick's aida solution going to be significantly faster?
>

this is not mine :)

butI'd interested to see if it's a good use of #become:... Does it
keep references ? is it safe ?

Thanks
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: How to empty a collection?

Marcin Tustin
My own testing suggests that references to the object remain in place. I would guess that that is the whole point of become.

On Feb 19, 2008 1:38 AM, cdrick <[hidden email]> wrote:
> Isn't Cedrick's aida solution going to be significantly faster?
>

this is not mine :)

butI'd interested to see if it's a good use of #become:... Does it
keep references ? is it safe ?

Thanks
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: How to empty a collection?

Brian M
My understanding as well is that this is the purpose of #become:, but
also that it is not very efficient in some versions of Smalltalk. If
you are using an OrderedCollection, this is probably a reasonably
efficient method as it doesn't need to search through the whole list
every time it removes an element:

removeAll
    [self notEmpty] whileTrue: [self removeLast]

Brian.


On Feb 18, 2008 6:42 PM, Marcin Tustin <[hidden email]> wrote:

> My own testing suggests that references to the object remain in place. I
> would guess that that is the whole point of become.
>
>
>
> On Feb 19, 2008 1:38 AM, cdrick <[hidden email]> wrote:
>
> >
> > > Isn't Cedrick's aida solution going to be significantly faster?
> > >
> >
> > this is not mine :)
> >
> > butI'd interested to see if it's a good use of #become:... Does it
> > keep references ? is it safe ?
> >
> > Thanks
> >
> >
> >
> > _______________________________________________
> > Beginners mailing list
> > [hidden email]
> > http://lists.squeakfoundation.org/mailman/listinfo/beginners
> >
>
>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/beginners
>
>
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: How to empty a collection?

Brian M
In reply to this post by Marcin Tustin
My understanding as well is that this is the purpose of #become:, but
also that it is not very efficient in some versions of Smalltalk. If
you are using an OrderedCollection, this is probably a reasonably
efficient method as it doesn't need to search through the whole list
every time it removes an element:

removeAll
   [self notEmpty] whileTrue: [self removeLast]

Brian.


On Feb 18, 2008 6:42 PM, Marcin Tustin <[hidden email]> wrote:

> My own testing suggests that references to the object remain in place. I
> would guess that that is the whole point of become.
>
>
>
> On Feb 19, 2008 1:38 AM, cdrick <[hidden email]> wrote:
>
> >
> > > Isn't Cedrick's aida solution going to be significantly faster?
> > >
> >
> > this is not mine :)
> >
> > butI'd interested to see if it's a good use of #become:... Does it
> > keep references ? is it safe ?
> >
> > Thanks
> >
> >
> >
> > _______________________________________________
> > Beginners mailing list
> > [hidden email]
> > http://lists.squeakfoundation.org/mailman/listinfo/beginners
> >
>
>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/beginners
>
>
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

RE: How to empty a collection?

Ron Teitelbaum
In reply to this post by Marcin Tustin
Hi Marcin,

I'm not a fan of using #become.  I will use it for very specific behavior
when I need to retain pointers to an object.  For example for implementing a
proxy.  In that case become is a very useful tool.  I think that #become is
overkill for this situation, but I won't argue that it doesn't work.  In
most cases you have a well encapsulated collection.  That collection is not
referenced outside the object so you can just reinitialize your collection
without #become.  If it is complicated enough to worry about pointers I
wouldn't use #become.  Someone will get lost and miss your #become hidden
inside #removeAll: .  I'm not saying this will cause problems but I think I
would rather work with the collection directly instead of using the #become.

Also if you are working on a collection that is large enough to worry about
performance then you are probably missing a database that would
significantly improve your performance.  

Ron Teitelbaum



________________________________________
From: [hidden email]
[mailto:[hidden email]] On Behalf Of Marcin
Tustin
Sent: Monday, February 18, 2008 8:43 PM
To: A friendly place to get answers to even the most basic questions
aboutSqueak.
Subject: Re: [Newbies] How to empty a collection?

My own testing suggests that references to the object remain in place. I
would guess that that is the whole point of become.
On Feb 19, 2008 1:38 AM, cdrick <[hidden email]> wrote:
> Isn't Cedrick's aida solution going to be significantly faster?
>
this is not mine :)

butI'd interested to see if it's a good use of #become:... Does it
keep references ? is it safe ?

Thanks
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: How to empty a collection?

Klaus D. Witzel
In reply to this post by Marcin Tustin
On Tue, 19 Feb 2008 02:35:34 +0100, Marcin Tustin wrote:

> Isn't Cedrick's aida solution going to be significantly faster?

No, solutions based on #become: are the slowest possible. The VM has to  
sweep the whole memory, for all variables in the system, to find all  
references during #become:, like this

  | oop |
  oop := self someObject.
  ["check+replace reference in variables of oop, then"
   oop := oop nextObject.
   oop = 0
   ] whileFalse.

Now think that you (and every other user of your software ;-) have an  
.image with 2-4gigs every time you use #become: ...

If you want something faster, look at Bert's

  myCollection removeAllSuchThat: [:each | true]

and try to make it faster but keep still it correct (old elements must be  
nil'ed).

/Klaus

> On Feb 19, 2008 1:02 AM, Ron Teitelbaum <[hidden email]> wrote:
>
>> Hi Sophie,
>>
>> aCollection copy do: [:anElement |
>>        aCollection remove: anElement
>> ].
>>
>> Why copy?  If you start removing items from the collection, increasing  
>> the
>> index will cause you to skip elements.
>>
>> Ron
>>
>> > -----Original Message-----
>> > From: itsme213
>> >
>> > I want to clear its contents (size goes back to zero), and can't seem  
>> to
>> > find something like #clear or #empty. Cannot use a new collection as
>> there
>> > are shared references to it.
>> >
>> > Thanks - Sophie
>>
>>
>> _______________________________________________
>> Beginners mailing list
>> [hidden email]
>> http://lists.squeakfoundation.org/mailman/listinfo/beginners
>>


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

RE: How to empty a collection?

Göran Krampe
In reply to this post by Ron Teitelbaum

Hi!

CCing squeak-dev because I would like to see this fixed. :)

"Ron Teitelbaum" <[hidden email]> wrote:
> Hi Sophie,
>
> aCollection copy do: [:anElement |
> aCollection remove: anElement
> ].
>
> Why copy?  If you start removing items from the collection, increasing the
> index will cause you to skip elements.  

Because modifying the collection while iterating over the same is not
safe generally. The above idiom is "known" - but of course it sucks. :)

I advocated to add a #removeAll message in the protocol of Collection
and then implement it in subclasses using efficient variants a looooong
while back but it never got accepted. The climate today for such a
change is much more... "pragmatic" I think and hope. So we should simply
add it!

The *normal* way people usually do it thoiugh is to *not depend on the
identity* of the Collection - different objects should typically not
share the same Collection. And if you don't share - then the easy way
out is to just do:

        myCollection := OrderedCollection new "or whatever class you use"

...in order to empty it.

But in low level code it would be nice to have the #removeAll method
because it can be very efficiently implemented in different subclasses
and would avoid reallocations etc.

regards, Göran
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: How to empty a collection?

Marcin Tustin
In reply to this post by Ron Teitelbaum


On Feb 19, 2008 2:29 AM, Ron Teitelbaum <[hidden email]> wrote:
Hi Marcin,

I'm not a fan of using #become.  I will use it for very specific behavior
when I need to retain pointers to an object.  For example for implementing a
proxy.  In that case become is a very useful tool.  I think that #become is
overkill for this situation, but I won't argue that it doesn't work.  In
most cases you have a well encapsulated collection.  That collection is not
referenced outside the object so you can just reinitialize your collection

Re-initialize how? I can't see a way to run object initialisation over again on an existing object.


without #become.  If it is complicated enough to worry about pointers I
wouldn't use #become.  Someone will get lost and miss your #become hidden
inside #removeAll: .  I'm not saying this will cause problems but I think I
would rather work with the collection directly instead of using the #become.

Also if you are working on a collection that is large enough to worry about
performance then you are probably missing a database that would
significantly improve your performance.

Ron Teitelbaum



________________________________________
From: [hidden email]
[mailto:[hidden email]] On Behalf Of Marcin
Tustin
Sent: Monday, February 18, 2008 8:43 PM
To: A friendly place to get answers to even the most basic questions
aboutSqueak.
Subject: Re: [Newbies] How to empty a collection?

My own testing suggests that references to the object remain in place. I
would guess that that is the whole point of become.
On Feb 19, 2008 1:38 AM, cdrick <[hidden email]> wrote:
> Isn't Cedrick's aida solution going to be significantly faster?
>
this is not mine :)

butI'd interested to see if it's a good use of #become:... Does it
keep references ? is it safe ?

Thanks
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: How to empty a collection?

Bert Freudenberg
On Feb 19, 2008, at 10:53 , Marcin Tustin wrote:

> Re-initialize how? I can't see a way to run object initialisation  
> over again on an existing object.


Everything in Smalltalk happens by sending a message. How was your  
object initialized? By sending a message. How can you initialize it  
again? Send the message again.

Case in point - OrderedCollection. How is it initialized? Look at  
#new:. It sends #setCollection:. So send #setCollection: with a new  
Array and you're done.

Well, of course you're not *supposed* to be doing this. But you  
could, and it would only be half-evil ;)

- Bert -


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: How to empty a collection?

Reinout Heeck
In reply to this post by Göran Krampe
[hidden email] wrote:
> The *normal* way people usually do it thoiugh is to *not depend on the
> identity* of the Collection - different objects should typically not
> share the same Collection. And if you don't share - then the easy way
> out is to just do:
>
> myCollection := OrderedCollection new "or whatever class you use"
>
> ...in order to empty it.


A word of caution: identity should be preserved in the 'normal' case,
replacing with another collection should be regarded as the exceptional
case. Your assertion that "different objects should typically not share
the same Collection." is only valid in limited cases.

I'm talking from my experience with building mvc-based apps on
VisualWorks. Code needs to be decoupled, ie 'model' objects and
collections should not know about the UI's that are coupled to them,
this is achieved with the various dependency mechanisms available in VW.

Changing identity of the collections will break this paradigm big time
(regardless of whether the dependents are managed in a global dictionary
or by the collection itself).





As to the implementation of #removeAll on non-growable collections:
follow whatever pattern the squeak library uses for other messages that
alter the size (#add:, #remove:,...). In VW the idiom is to call
#shouldNotImplement.



Cheers,

R
-
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: How to empty a collection?

Randal L. Schwartz
In reply to this post by Brian M
>>>>> "Brian" == Brian Murphy-Dye <[hidden email]> writes:

Brian> My understanding as well is that this is the purpose of #become:, but
Brian> also that it is not very efficient in some versions of Smalltalk. If
Brian> you are using an OrderedCollection, this is probably a reasonably
Brian> efficient method as it doesn't need to search through the whole list
Brian> every time it removes an element:

Brian> removeAll
Brian>     [self notEmpty] whileTrue: [self removeLast]

What makes you think #removeLast doesn't need to search through the whole list
in some kinds of OrderedCollection?  You *do* have an implementation
assumption there.

I'd just do:

    removeAll
        self notEmpty ifTrue: [self become: self species new].

and let subclasses make it more efficient using implementation knowledge.

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<[hidden email]> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: How to empty a collection?

cedreek
In reply to this post by Ron Teitelbaum
>
> aCollection copy do: [:anElement |
>         aCollection remove: anElement
> ].
>
> Why copy?  If you start removing items from the collection, increasing the
> index will cause you to skip elements.

I forgot that in my first attemp (and I knew that !)...

col := #(1 2 3) asOrderedCollection.
col  removeAll: col.
^col   returns an OrderedCollection(2)

col  removeAll: col copy is ok.

So, following Bert suggestion, would it be possible to change removeAll: from...

removeAll: aCollection
        aCollection do: [:each | self remove: each].
        ^ aCollection
to

removeAll: aCollection
        aCollection copy do: [:each | self remove: each].
        ^ aCollection
or

removeAll: aCollection
        aCollection == self
                ifTrue: [aCollection copy do: [:each | self remove: each]]
                ifFalse: [aCollection do: [:each | self remove: each]].
        ^ aCollection

or again
removeAll: aCollection
        aCollection == self
                ifTrue: [self removeAll: aCollection copy]
                ifFalse: [aCollection do: [:each | self remove: each]].

Or maybe, if aCollection == self, a warning could be raised ?

What do you think ?

Cédrick

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

RE: How to empty a collection?

Ron Teitelbaum
Hi Cédrick,

I believe there is too little agreement to do very much.  The suggestion you
presented as Bert's suggestion was actually mine.  So given the discussion
that followed I think I would actually follow Bert's advice.

aColl removeAllSuchThat: [:anElement| true].

But I suppose that is still following my own advice because

removeAllSuchThat: aBlock
        "Evaluate aBlock for each element and remove all that elements from
        the receiver for that aBlock evaluates to true.  Use a copy to
enumerate
        collections whose order changes when an element is removed (i.e.
Sets)."

        self copy do: [:each | (aBlock value: each) ifTrue: [self remove:
each]]

:)

Ron Teitelbaum

> -----Original Message-----
> From: cdrick [mailto:[hidden email]]>
> >
> > aCollection copy do: [:anElement |
> >         aCollection remove: anElement
> > ].
> >
> > Why copy?  If you start removing items from the collection, increasing
> the
> > index will cause you to skip elements.
>
> I forgot that in my first attemp (and I knew that !)...
>
> col := #(1 2 3) asOrderedCollection.
> col  removeAll: col.
> ^col   returns an OrderedCollection(2)
>
> col  removeAll: col copy is ok.
>
> So, following Bert suggestion, would it be possible to change removeAll:
> from...
>
> removeAll: aCollection
> aCollection do: [:each | self remove: each].
> ^ aCollection
> to
>
> removeAll: aCollection
> aCollection copy do: [:each | self remove: each].
> ^ aCollection
> or
>
> removeAll: aCollection
> aCollection == self
> ifTrue: [aCollection copy do: [:each | self remove: each]]
> ifFalse: [aCollection do: [:each | self remove: each]].
> ^ aCollection
>
> or again
> removeAll: aCollection
> aCollection == self
>                 ifTrue: [self removeAll: aCollection copy]
>                 ifFalse: [aCollection do: [:each | self remove: each]].
>
> Or maybe, if aCollection == self, a warning could be raised ?
>
> What do you think ?
>
> Cédrick

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: How to empty a collection?

Bert Freudenberg
In reply to this post by cedreek
On Feb 19, 2008, at 16:06 , cdrick wrote:
> So, following Bert suggestion, would it be possible to change  
> removeAll: from...


I'm pretty certain I did not suggest anything like this. Nothing is  
broken here, so let's not fix it.

A new feature would be adding #removeAll, which sounds reasonable¹.

- Bert -

¹I do smell a bit of premature optimization here, or does anyone have  
a really convincing use case?

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
123