Another Question

Henrik Gedenryd Henrik.Gedenryd at lucs.lu.se
Sat Dec 25 13:09:29 UTC 1999


Dear Mr. Blacktooth,

It's OK to ask questions, there's no need to hide behind an alias ;-)
Compared to Dan and the others from the LRG days were all newbies at this!

I still think there's a good deal of room for making your code more
Smalltalk-like. This is no end in itself; it will also become much shorter
and clearer. In particular, you can exploit the power of the Collection
classes; using loops instead of the Collection protocol is a common symptom
of someone coming from traditional languages.


First of all, if I understand it right, you are doing something similar to a
breadth-first tree traversal, more or less? Here's a standard solution to
b-t traversal, thanks to Kent Beck :) See how short it is thanks to the
Collection protocols:

Node>>levelOrderDo: aBlock
    | queue current |
    queue := OrderedCollection with: self.
    [queue isEmpty] whileFalse: [
        current := queue removeLast.
        aBlock value: current.
        queue addAllFirst: current children]

(The rest is off the top of my head since to run the code I would need more
than this snippet. Ie. it's probably buggy.) The main loop would become:

tempRefs keysAndValuesDo: [ :refKey :refDeps | "gives you the value too"
     refQue := refQue, refDeps.     "merges (most) whole collections for
you"
     [ refQue isEmpty ] whileFalse: [
         temp := (refQue first).
         storage addLast: temp.
         refQue := refQue, (tempRefs at: temp ifAbsent: [#()]). "add nothing
if not there"
         refQue removeFirst ]]]

Now, it looks as if you're just making a verbatim copy of refQue in storage.
You can enumerate thru refQue instead, since you only add to its end:

i := 1.
tempRefs keysAndValuesDo: [ :refKey :refDeps | "gives you the value too"
     refQue := refQue, refDeps.     "merges collections for you"
     [ i <= refQue size ] whileTrue: [
         item := refQue at: i.
         refQue := refQue, (tempRefs at: item ifAbsent: [#()]). "add nothing
if not there"
         i := i + 1]]]

This is probably faster since #, does redundant copying even if the second
collection is empty:

         (tempRefs includes: item)
            ifTrue: [refQue := refQue, (tempRefs at: item)].

Now I hope all this works, heh.

The bottom line of this message is,

< = > .

Seriously.

Henrik


Blacktooth wrote:

> refQue := OrderedCollection new.
> storage := OrderedCollection new.
> 
> tempRefs keysDo: [ :refKey |
> tempDeps := OrderedCollection newFrom: (tempRefs at: refKey).
> tempDeps do: [ :i | refQue add: i. ].
> [ refQue isEmpty ] whileFalse:
> [ temp := (refQue first).
> storage addLast: temp.
> (tempRefs includesKey: temp)
> ifTrue: [ (tempRefs at: temp) do: [ :i | refQue addLast: i ].].
> refQue removeFirst. ].


< = > .





More information about the Squeak-dev mailing list