[REBOL] Re: What kind of bug is this?
From: brian:hawley at: 31-Jul-2001 15:57
Hi Mark,
At 05:35 AM 7/31/01 -0400, you wrote:
>What kind of bug is this?
>
>Ladislav, myself & others have been having a discussion concerning
>evaluation and self modifying code, and some errors? / very strange
>behaviour that REBOL displays.
>
>Consider the following code in which the block 'a modifies itself at
>each call by appending + 1 to it's latter series of values.
>
>Do'ing this block results in an incrementing sum at each call except
>when you get to iterations 6, 14 & 30 when some very wierd things
>start happening.
>
>By printing the SUM part of 'a after each call I thought I might
>be able to deduce the behaviour / evaluation model and predict
>the result of the next call BUT NO! I'm stumped.
>
>Anybody got any explanations?
>
>Mark Dickson
>
>Heres' the code.............................................
>
> >> a: [ append a [+ 1] 1]
>== [append a [+ 1] 1]
> >> loop 50 [ print [do a newline] print [remove/part b: copy
>a 3 newline]]
[results skipped]
REBOL blocks are preallocated in chunks. When you increase the
size of the block (ie. by inserting data) you use up this space
until it runs out. At that point, REBOL copies the contents of
the block into a new, bigger preallocated chunk of RAM. This
process happens automatically, at least as far as REBOL code is
concerned.
Your code demonstrates that the DO native does not take this
into account. DO apparently continues to operate on the old
copy of the block it has been passed when this reallocation
occurs. Whoops! Possibly a speed optimization, but just as
possibly this kind of behavior wasn't anticipated.
There's no reason to assume that this technique would work if
REBOL wasn't specifically designed to handle this behavior.
You should be thankful that it doesn't crash :)
As it is, I would suggest one of four techniques:
- Specify the maximum size of the block ahead of time.
- Perform modifications that don't change the length of the
block you are modifying.
- Perform your modifications in a different block of code than
the one you are modifying, at a time that you are not DOing
the modified block. DO/NEXT can help here.
- Precalculate your modifications. COMPOSE can help here.
I hope this helps.
Brian Hawley