Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Re: En Masse block operations

From: joel:neely:fedex at: 16-Oct-2001 14:09

Hi, Tim, Tim Johnson wrote:
> I see Ryan's opinion not to use 'foreach..... > Could you comment on his opinion on this. > > (I've seen references to a foreach "bug" and > I almost never use it myself.) >
AFAIK there's no bug involved, but it is possible to misunderstand what FOREACH (and REPEAT, for that matter) are doing. Here's your original sample block:
>> blk
== [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"] Let's go through it with FOREACH...
>> foreach item blk [print item: next item]
2 3 4 6 7 8 10 11 12 14 15 16 17 ne ... and then look at the block again ...
>> blk
== [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"] The block itself is unchanged. The (local) word ITEM was set to each value in the block in turn. This means that the expression item: next item in the above code is changing the position to which ITEM refers, but not changing the (explicit, literal) series reference that is in each position of BLK. The same thing happens if you use REPEAT as follows:
>> repeat item blk [print item: next item]
2 3 4 6 7 8 10 11 12 14 15 16 17 ne
>> blk
== [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"] The point is that if you want to mutate the values in BLK, you're going to have to do one of two things: 1) work directly with the references in BLK (or an alternate reference to BLK), or 2) compute a new block based on the old values in BLK and set BLK to refer to that new block. The first alternative could be written as
>> forall blk [ blk/1: next blk/1 ] blk: head blk
== [[2 3 4] [6 7 8] [10 11 12] [14 15 16 17] "ne"]
>> blk
== [[2 3 4] [6 7 8] [10 11 12] [14 15 16 17] "ne"] and could be undone by
>> forall blk [blk/1: head blk/1] blk: head blk
== [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"] The second alternative could be coded in-line or done via MAP, as discussed in my prior email.
>> loop 5 [print mold blk: map blk func [s] [next s]]
[[2 3 4] [6 7 8] [10 11 12] [14 15 16 17] "ne"] [[3 4] [7 8] [11 12] [15 16 17] "e"] [[4] [8] [12] [16 17] ""] [[] [] [] [17] ""] [[] [] [] [] ""]
>> blk: map blk func [s] [head s]
== [[1 2 3 4] [5 6 7 8] [9 10 11 12] [13 14 15 16 17] "one"] In any event, I'm not aware of a FOREACH "bug" and use it all the time. HTH! -jn- -- This sentence contradicts itself -- no actually it doesn't. -- Doug Hofstadter joel<dot>neely<at>fedex<dot>com