[REBOL] Re: En Masse block operations/foreach bug?
From: tim::johnsons-web::com at: 16-Oct-2001 17:52
On Tue, Oct 16, 2001 at 02:09:26PM -0500, Joel Neely wrote:
> 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:
==>>If memory serves me well (always this disclaimer on my part)...
There was a discussion on this list some months ago regarding
a "bug" in 'foreach.
In that discussion was a link to a file called bugfixes.r
I have downloaded that file, it makes references to several
"bugs" which it claims to fix. I haven't done anything
with that code myself.
==>>I actually haven't found any problems
myself with either 'repeat or 'foreach.
==>>There's a lot of good stuff here Joel, I'm about to
start playing with it. You should be doing training
in rebol. Seriously.
thanks
tj
> >> 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
> --
> To unsubscribe from this list, please send an email to
> [rebol-request--rebol--com] with "unsubscribe" in the
> subject, without the quotes.
--
Tim Johnson <[tim--johnsons-web--com]>
http://www.johnsons-web.com