Hi, Russell, you wrote:

But I must admit I'm "flabbergasted" at how the function 'f as defined
immediately above, works on repeated
applications.  You proposed some ingenious "debugging" approaches, but I
discovered another.  Look at this
console stuff:

>> f: func [/local a] [a: "" insert a 1 a]
>> source f
f: func [/local a][a: "" insert a 1 a]
>> f source f
f: func [/local a][a: "1" insert a 1 a]
>> f source f
f: func [/local a][a: "11" insert a 1 a]
>>
It appears that the interpreter is modifying the source!

>When the expression
> insert a 1
> is evaluated, 1 is inserted into the string referenced by 'a.
>
> Therefore, the second time 'f is evaluated, a is no longer assigned as a
> reference to an empty string. The second time around, 'a is assigned to a
> string that already contains one element, namely the 1 that was inserted
> the first time around. If you want to try that in the REBOL console, you
> have to do the following:
>
> >> a: ""
> == ""
> >> head insert a 1
> == "1"
> >> a: "1"
> == "1"
> >> head insert a 1
> == "11"
> >> a: "11"
> == "11"
> >> head insert a 1
> == "111"
>

The above is certainly correct, as shown by the 'source f results.  But I'm
still amazed.

It surprises me that the interpreter knows that "" does not refer to an
empty string, but to an existing string already referenced by 'a, except in
the first usage whre 'a has no value!  I would consider this as a bug, if so
many smart people were'nt
upset about it!

Except for the problem of initialization of 'a for the first execution of
'f, 'f behaves as though it had been defined:

f: func[local/ a][a: a insert a 1 a]

Or as

f: func[local/ a][insert a 1 a]

Try the following varieties:

f: func[local/ a][a: [none] insert a 1 a ]
f: func[local/ a][a: reduce [none] insert a 1 a]
f: func[local/ a][a: reduce "" insert a 1 a]

in the first [none] acts the same as "", but in the second and third [none]
and "" don't give the same result!!
If it walks like a bug and talks like a bug, isn't it a bug??  It disturbs
me that executing f changes the result of
source f

I agree; that disturbs me!

[L]
See this example code:

a: ""
body: append append/only copy [b:] a [print b]
insert a "1"
body

Results:
>> a: ""
== ""
>> body: append append/only copy [b:] a [print b]
== [b: "" print b]
>> insert a "1"
== ""
>> body
== [b: "1" print b]

Now, you can tell: the interpreter modified BODY! Is it right? The answer
is: no, BODY wasn't modified, but it contains a, which got modified. The
same is true for your example: the interpreter doesn't modify the source of
F, but it modifies the second element of the F's source.

The reason for your surprise lies in the fact, that the expression:

a: ""

doesn't mean:

Create a string "" and give it the name A.

It means this:

Give the name A to an existing string, which was created when the F was
created and is contained in F's body as it's second element. Then, there's
no surprise, that the source of F looks different if we modify it's second
element through modifying A.

Now, let's see this:

a: reduce [none]

This means: create a new block using REDUCE from an existing one, which is
the third element of the function body. When you now modify A, you surely
don't modify the third element of the function body, but something else...

HTH

Ladislav

Reply via email to